Custom Binding Released!

Custom Binding Released!

Delivered as promised. It has a smaller memory footprint, a faster clock-speed and, best of all, it’s 100% weak-referenced. Data binding is supposed to be light and unobtrusive. Now you can have the smallest ActionScript 3 binding available, released as a component of the open source Flight Framework.

Flight’s data binding is powerful and simple, consisting of two classes. A Binding object represents a single data source: a source object and a source-path, such as model and "user.userName". Any number of event listeners and object/property pairs can be registered with this single Binding instance, allowing each to update when the data source changes. This class may be useful for special needs, but you usually don’t deal with Binding directly.

The Bind class is the primary interface to Flight binding and is used much like you would use Flex BindingUtils. This class exposes a static API for adding and removing bindings and listeners. It can also be instantiated via MXML for special cases where you need weak-reference binding that curly-brace bindings just don’t support. Here’s an example of usage:

Binding via Static ActionScript API:

// Bind.addBinding(target:Object, targetPath:String, source:Object, sourcePath:String, twoWay:Boolean = false):Boolean
 
Bind.addBinding(this, "userTxt.text", this, "model.user.userName");

Instance binds via MXML:

<!-- constructor: Bind(target:Object = null, targetPath:String = null, source:Object = null, sourcePath:String = null, twoWay:Boolean = false):void -->
 
<flight:Bind targetPath="userTxt.text" sourcePath="model.user.userName"/>

Visit the Google Project to download release 0.8.1 or higher.


Optimization For Faster Binding

Flight data binding works seamlessly with existing Flex components, responding to the same property update notifications and dispatching similar events. Flight binding is faster at updating and synchronization than Flex’s data binding when using these Flex property change events. But it is even faster if you choose to use Flight’s own property change methods, illustrated below:

import flight.events.PropertyEvent;
 
[Bindable(event="propertyChange", flight="true")]
public function get userName():String
{
    return _userName;
}
public function set userName(value:String):void
{
    if(_userName != value) {
        var oldValue:Object = _userName;
        _userName = value;
        // any other behavior, updates, etc that should happen with this change
        PropertyEvent.dispatchChange(this, "userName", oldValue, _userName);
    }
}

It takes more code, but by using Flight’s PropertyEvent an event is only dispatched if it is being actively bound to – Flex will dispatch an event for every property change in the system, which creates more performance overhead. In Flight, events are targeted to a specific property change by using a propertyName + "Change" convention – "userNameChange" – preventing an additional listener and response from binds that target other properties.

Flex uses a generic "propertyChange" event that every binding listens to. Bindings in Flex also listen to every single bindable event on the class.Flex will target the events of a single property appropriately. For this reason the unique meta data [Bindable(event="propertyChange" flight="true")] insures that Flight bindings are optimally tuned for performance while still allowing Flex bindings to be usable. To illustrate: if each bindable meta tag where to reflect a unique event (propertyName + "Change"), Flex binding performance would suffer on classes with a significant number of properties because each bind would be listening to every one of these events. Flight presents a custom solution for speeding up binding resolution, yet still has increased performance using regular Flex bindings [Bindable] public var userName:String;

I misinterpreted Flex’s binding procedures and have found that built-in Flex binding will still target a specific property’s bindable events, not the binding events of the entire class. So to get optimal performance from both Flight and Flex binding, the appropriate meta tag should be formatted [Bindable(event="matrixChange")] public var matrix:Matrix;, where the event name is the name of the property + “Change”. Flight’s PropertyEvent.dispatchChange was designed around dispatching this type of event for best performance.


The classes are only just being documented. Like the rest of Flight the binding is seeing an early release and has some polishing left to do. If you try it out I’d love to hear your feedback, positive or otherwise. The Flight Framework group (mailing list) is available here. Enjoy!



29 Responses to “Custom Binding Released!”

  1. [...] and faster than Flex’s but can be used in Flex and even has an MXML tag to create a bind. Check it out. [...]

  2. Ben Dalton says:

    Now if you can patch mxmlc to generate your bindings for the {} shorthand, we’ll be all set :-)

  3. Alan says:

    Any chance for a mailing list?

  4. iongion says:

    Wonderful, but let me understand, this won’t work when using curly braces ?

    I mean, what wouldn’t work ?

  5. xtyler says:

    Curly brace binding automatically uses the built-in Flex solution, so the benefits of Flight’s binding (such as weak-reference and speed improvements) are lost. In other words, there is no reason to use Flight binding within curly braces. But it wouldn’t hurt anything either.

  6. James Ward says:

    Hi Tyler,

    This is very cool and something that I’ve definitely needed on some projects. Is your Bindable tag a typo? I had to put a comma in to make it compile. Also, I can’t seem to make this work on an ArrayContainer. I’m using the latest Flight from SVN. One last thing… It would be great if I could setup a Logger or something and get some debugging info about the binding stuff. This is one major lacking of Flex’s Binding. It’s a black box so it’s very hard to debug problems.

    Thanks for your hard work on this! Flight is looking great!

    -James

  7. xtyler says:

    I’ll contact you directly about the bugs. As for the logger that’s a great idea – Flight has a logging class that hasn’t really been utilized or stress-tested yet, this might be a good opportunity.

    Thanks James!

  8. wolfroma says:

    PropertyEvent.dispatchChange(this, “userName”, oldValue, _userName);

    This code is such ugly (:
    If you want custom event name you should use metatag [Bindable("EventName")], as say before for perfomance you can check listeners.

    [Bindable("sourceChange")]
    public function get source():Object{
        return _source;
    }
     
    public function set source(value:Object):void{
        if(value!=_source){
            _source = value;
            if(this.hasEventListener("sourceChange")){
                 dispatchEvent(new Event("sourceChange"))
            }
        }
    }

    Are you have more optimization???

    I think adobe binding – it’s powerful tool’s, special if you use BindUtils class.

  9. xtyler says:

    wolfroma – glad you brought this up. Because property changes are so universal, any optimizations can go a long way. Using PropertyEvent’s dispatchChange has higher performance than 1) creating an Event object and 2) dispatching that Event object when nothing is listening. Everywhere.

    With the sheer number of properties that are Bindable compared to actual Bindings, this single change makes data binding possible in complex systems.

    Flex’s PropertyChangeEvent also has the static method, but without the optimization benefit. This code is auto-generated by the Flex SDK and so is never questioned. Flex’s BindingUtils works fine and is convenient. My goal is to provide something smaller, faster and weak-referenced in response to the concession, “data binding is too slow for larger applications”.

    It would be great if these techniques were adopted as a standard and available through a convenient workflow like Adobe’s data binding. For now it’s a little more effort, so use it where it makes sense for you.

  10. Jakub Galas says:

    Thanks a lot! Somehow I’ve made an assumption that the default Flex binding uses weak references (after all – that would be quite logical, right?). Huge memory leaks in my app have proven me wrong. Your solution helped me to cope with that to some degree.

    I’ve noticed some issues in your binding though:

    Let’s say you have a control that displays some complex data. An object can be assigned to it’s property, let’s call it personData. You want to bind something with some internal property of the object and get it refereshed each time a new objects gets assigned to personData:

    Bind.addBinding(this, ‘cityLabel.text’, this, ‘personData.address.city’);

    This will usually throw an error if data is not set yet (is null). A little tweak in your code seems to fix the problem – just check if source is not null in Binding::bindPath (Binding.as line 244):

    if(source != null && !(prop in source) ) {

    I suppose that after a reference to an object is assigned to data, sub-objects don’t get the property change listener attached, so internal changes inside data won’t be detected… Or am I wrong?

    Another problem is event priority. We have an object that has a List object inside it.

    … and you have a property bound with selectedItem of the list:

    Bind.addBinding(this, ‘mySelectedItem’, myList, ‘selectedItem’);

    if you read mySelectedItem inside the handleChange() function, it should be equal to myList.selectedItem, but it still holds the previous value. I tried to use eventPriority of EventPriority.BINDING in addEventListener calls inside Binding.as, but it doesn’t seem to help, so I think the problem is more complex.

    Btw – I’ve noticed, that you don’t useWeakReference in addEventListener – is that ok?

    Thanks again for posting your code.

  11. xtyler says:

    Jakub,

    Great comments, thanks! The fix for checking if source is null was implemented in the repo a while ago, I have yet to update the downloads (sorry).

    I’m not sure about the binding priority problems, but that’s excellent feedback – I’ll implement a higher-priority for bindings. The best test-case to check whether the bug is in Flex’s List or Flight’s Binding is to swap it out with Flex’s BindingUtils and see if it updates properly.

    Where binding is listening to an object’s property-changes, I purposefully don’t use weak-referenced event listeners. Theoretically the object won’t leave memory without notifying the binding through a dispatched propertyChange event. In practice however there is no guarantee that an object dispatches property changes (defeating binding at that point, but sometimes necessary) – do you think it would be safer to have even those listeners weak-reference? There is a slight performance hit over many weak-referenced listeners on the same IEventDispatcher, but probably not enough to be concerned.

    thanks again for the feedback!

  12. Nice, I’ve been planning to do something long these lines, but hadn’t gotten around to it yet. Looking forward to seeing more of Flight.

  13. I seem to be having trouble sorting my namespaces out – I’m getting an error ‘could not resolve to a component implementation. I’ve added ‘xmlns:flight=”flight.*”‘ to my top level tag (TitleWindow) and I have flight-framework.swc in my libs folder – any ideas? I’m just trying to use Bind at this point, not the whole framework.
    Regards, Martin

  14. ah – the xml got stripped out of the error message in my post, replaced with underscores below:
    Could not resolve _flight:Bind_ to a component implementation
    Thanks

  15. xtyler says:

    Martin,

    The xml namespace is xmlns:flight=”http://flight.flightxd.com/2009″

    It’s supposed to auto-complete for you in the Flex Builder environment, sorry if it’s given you much trouble.

    Let me know if that works for you.

  16. Brilliant, thank you – fixed. I think I filled in the xmlns myself first, didn’t give Flex a chance to do it for me – will watch out for that next time.
    I’ll let you know how I get on, Bind looks to be eactly what I need. I have a windowing app that crashes due to Binding causing massive memory leaks when I open and close windows,
    Thanks again, Martin

  17. viatropos says:

    Hey man,

    How much faster/better performing is this custom binding than traditional Flex binding? 2x, 5x, 10x? If I have 1000 items in an ArrayCollection all changing values at once, will it prevent the application from temporarily freezing?

    Thanks for the info,
    Lance

  18. xtyler says:

    There have been enough changes/improvements since this post that I’ll write an update on this topic and provide some tests and statistics. I don’t think you’ll see a huge difference, especially over a trivial 1000 items. The Flex binding is still fast, coded on AS3, but it uses more memory and isn’t weak-referenced (Garbage Collection Friendly). Both solutions are tied into the Event Dispatching system.

  19. viatropos says:

    One more thing: Binding and Tweening. Animations run in Flash/pure Actionscript are MUCH faster/smoother than the SAME animations run in Flex. This is presumably from both Binding and invalidation calls.

    For example, if you tween “alpha”, “x”, and “y” of a 500×500 Panel for 1 second, that can dispatch 50+ events, plus make a billion invalidation calls. If you do “setActualSize” for resizing (which they recommend), that’s another 3 events, so you can have in a single tween: ‘alphaChanged’, ‘xChanged’, ‘yChanged’, ‘widthChanged’, ‘heightChanged’, ‘resize’… every frame! On most computers other than the newest newest, or the ones we soup up, they chop through 2-4 frames of the animation. Terrible. I think it’s from all the binding going on which you don’t need.

    Question is, is Flight ready to handle that problem? It seems like it just about is, if you could put in there a “suspendBinding” method that we could set when running our effects and tweens, that would suspend binding events temporarily. That way I can run animations with zero binding events (when I don’t want them, which is almost always), and zero invalidation calls (some of the time).

    Any thoughts?
    Lance

  20. xtyler says:

    Current Flight binding does not have a “suspend binding” feature. But if nothing is bound to a property then the propertyChange event is never created and dispatched. This is one of the best system-wide improvements over Adobe’s binding, where instantiating a new object, the event, and then dispatching can add up.

    Recently I’ve been interested in revisiting the binding solution with a completely new method of updating bindings outside of the event flow. This means that any object could be bindable, not just IEventDispatchers, and it would also mean further speed improvements. The only downside to a new solution like this is that it wouldn’t be compatible with Flex at all, where the current binding is seamless.

    Overall I think tweening performance issues stem from the Flex invalidation cycle. Binding in Flex isn’t slow enough to be noticeable unless you’re doing many thousands of property changes in the same thread. Of course that is only taking the binding system into account, not any of the Flex code that responds to some of these property changes.

  21. viatropos says:

    Here’s some stats on the performance increases of just adding that “hasEventListener” business.

    http://forums.adobe.com/message/2204490#2204490

    Cheers,
    Lance

  22. xtyler says:

    Quote from cited article:

    “so it looks like just adding that conditional statement to check for the event listener is kind of expensive. But it’s only a 2x performance hit instead of ~7-8x for dispatching an unnecessary event…”

    Most events go unlistened to, considering all the property changes and other events on all DisplayObjects and EventDispatcher’s in the system. This check saves significantly in overall performance of any system, while its minimal cost goes unnoticed.

  23. p48l0 says:

    Found the error / bug ? mabe i have a bad setup or something, this line dosen´t work:

    propertyCache[metadata][value] = propertyCache[value].(child(“metadata”).(@name == metadata).length() > 0);

    but this one does:

    propertyCache[metadata][value] = propertyCache[value].(child(“metadata”).(@name == “Bindable”).length() > 0);

    this is from source code: flight.utils.Type

    Someone knows why is this?

  24. xtyler says:

    This is a compiler error, if you rename the ‘metadata’ local property to ‘meta’ for example it will work great once again.

  25. Fyodor says:

    Does it work with dynamic objects like ObjectProxy? I’m using it as a Map or associative array.

    I’m binding to an ObjectProxy field and it only works if the proxy already contains the field at the moment the binding is created.

    I’m using Flight 1.0 RC.

  26. [...] You can read more details about this custom binding here: http://www.xtyler.com/code/177 [...]

Leave a Reply

  • drugs hair loss
  • antibiotic
  • side effects of antibiotics
  • nexium health
  • new medication for cancer treatment
  • congestive heart failure overview
  • canada cialis generic
  • appetite suppressant
  • pain med without prescription
  • buspar online
  • medication pediatric insomnia
  • very cheap viagra
  • increase womens sex drive
  • lowest price generic viagra
  • buying online viagra
  • cheap alcoholism treatment
  • information on ambien
  • celexa and anxiety
  • lamictal withdrawal
  • celebrex capsules
  • diabetes treatment
  • pain meds no prescription
  • weight loss food
  • body building diets
  • drugs fda
  • anti-fungal
  • pharmacy allegra
  • parkinsons disease medication
  • reducing high blood pressure
  • how does viagra work?
  • medications for depression
  • clomid cycles
  • best male enhancement drugs
  • bodybuilding nutrition buy supplements
  • natural dog health
  • next day medication
  • herbal weight loss products
  • weight loss nutrition
  • famvir dose
  • cheap antibiotics
  • order zoloft
  • zyrtec medication
  • acne skin treatment
  • prescription pain medicines
  • wal mart pharmacy
  • cheap nolvadex
  • online phentermine online prescription
  • tips for insomnia
  • stress medicine for cats
  • canada online drug stores
  • osteoporosis evista
  • viagra order online
  • drugs online no prescription
  • cheap birth control online
  • newest bodybuilding products
  • treating diabetes
  • deep sleep disorder
  • celexa buy
  • how to lose asthma
  • rheumatoid arthritis medications
  • xanax sales
  • high cholesterol diet
  • anxiety order
  • canada pharmacy
  • vitamine guide for dogs
  • different treatments of alcoholism
  • online apotheke
  • hypertension and low heart rate medications
  • treatment for hepatitis c
  • list of blood pressure medicines
  • information on sleeping aids
  • cheap antibiotics
  • bust enlarge
  • how to get viagra prescription
  • muscle nerve pain
  • mens health 40
  • hair re-growth
  • acai berry products
  • tips for gaining muscle mass
  • where to order soma
  • baby acne
  • cialis 10
  • viagra discount online
  • sleeping problems uk
  • buy cialis without a prescription
  • free stop smoking ways
  • womens health menopause
  • how to relieve ear pain
  • hoodia fast
  • aldactone medication
  • uric acid remedies
  • generic zyrtec
  • hangover help
  • buy ambien online cheap
  • lexapro paxil
  • sinus infection med
  • dog lose weight
  • order birth control
  • anti-fungal
  • neck pain
  • psoriasis treatments
  • cialis on line
  • pravastatin
  • new heart attack drugs
  • how to cure diarrhea
  • online pharmacy ratings
  • generic allegra
  • ativan prescription
  • prescription for severe stomach pain
  • medical irritable bowel
  • teeth whitening buy
  • women's hair loss remedie
  • why most people benefit from antidepressants
  • pain cure
  • klonopin anxiety
  • hiv medications
  • prevent itching
  • xanax buy on line
  • nolvadex no prescription
  • xanax perscription
  • anxiety disorder
  • canadian arthritis medication
  • menstrual cramp pain
  • stomach ulcer pain
  • dietary supplement
  • acai berry pills
  • viagra coverage california
  • cures for depression
  • lower your blood pressure
  • treatment of psoriasis
  • cold sores help
  • buy Lozol
  • high blood pressure and treatment
  • pet health care
  • diet supplements distributors
  • cyclophosphamide
  • get klonopin
  • anti-fungal
  • shoulder arthritis
  • cheap caffeine
  • acne tips
  • free prescription medication
  • cat anxiety medicine
  • hepatitis c treatments
  • medication for severe chronic pain
  • order prozac
  • blue pills
  • parkinson's meds
  • anti malaria drugs
  • diet pills online
  • online drug store
  • vascular edema
  • online valium no prescription
  • help stop smoking
  • hydrochlorothiazide generic
  • medication prices
  • cold v flu
  • congestive heart failure med
  • blue pills
  • kidney cancer drugs
  • chlamydia cures
  • vitamin c for dogs
  • oral diabetes medication
  • us drugstore
  • ultimate weight loss
  • list pain meds
  • cialis best on-line drugstore
  • ambien sample
  • new treatment for heart failure
  • pet meds on line
  • buy clomid
  • cheap cialis site
  • bodybuilding nutrition
  • small penis
  • ambien dosages
  • treatments and cures for epilepsy
  • natural weight loss supplements
  • dry skin treatment
  • online order ambien
  • symptoms of stop smoking
  • blood pressure treatment drugs
  • diclofenac dosage
  • helping high blood pressure
  • bronchitis medications
  • antibiotics safe for dogs
  • immune system strengthen
  • best weight loss pills
  • usa pharmacy
  • allied health
  • colon cancer treatment
  • drug treatment for alcoholism
  • tramadol very cheap
  • early prostate cancer treatment
  • side effects claritin
  • retin a cheap
  • online pharmacies in mexico
  • new treatment for allergies
  • prescription drug prices
  • generic plavix
  • buying viagra prescription