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!



25 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.

Leave a Reply

  • zoloft order
  • try viagra for free
  • buy medicine online
  • cholesterol care
  • alternative antibiotics
  • reducing cholesterol
  • bone loss treatment
  • cat products
  • reduce swelling methods
  • osteoporosis medication side effects
  • pets products
  • at home acne treatments
  • types of blood pressure medicine
  • cholesterol medication
  • vitamin nutrition supplement
  • buy birth control pills
  • order calcium carbonate
  • viagra and buy
  • reducing high blood pressure
  • order metformin online
  • buy prescription medication online
  • generic for viagra
  • accutane buy
  • skin solutions
  • cialis approval
  • treating chlamydia
  • fat loss tips
  • buy birth control pills
  • help for edema
  • cheap pain pills
  • healthy dog puppy food
  • new stop smoking medication
  • high cholesterol meds
  • healthy pet
  • vitamin metabolism
  • buy levitra onlines
  • lisinopril 5mg
  • new diabetes meds
  • arthritis in back
  • how to increase bust
  • drugstore online
  • weight loss help
  • cheap phentermine
  • canadian drug stores
  • cure for aids
  • zyban online from canada
  • cheap premarin
  • generic viagra lowest price
  • suffering produces endurance
  • longer lasting erection
  • viagra how works
  • skin cancer treatments
  • throat gonorrhea
  • information on congestive heart failure
  • new weight loss drugs
  • cialis blood pressure
  • preventing pregnancy after sex
  • stopping hair loss
  • online pharmacy in canada
  • price zyban
  • stop hair loss
  • quitting zyban
  • buy soma cheap online
  • list of prescription pain meds
  • treat high blood pressure
  • prescription med
  • drugs to help sleep
  • preventing pregnancy after sex
  • omega fish oil
  • senna constipation
  • order medication
  • how to relieve lower back pain
  • weight loss drinks
  • weight loss for women
  • safest weight loss pill
  • treatments for lung cancer
  • diabetes drug
  • treatments for high blood pressure
  • free weight loss program
  • nolvadex no prescription
  • anxiety insomnia
  • control premature ejaculation
  • causes erectile dysfunction
  • best hangover remedy
  • what is diazepam
  • body building product
  • clomid dosage
  • bipolar disorder
  • fast antibiotics cure chlamydia
  • buy singulair
  • aids for sleeping
  • hair loss cures
  • lisinopril 5mg
  • arthritis help
  • medication price
  • risperdal anxiety
  • blockers calcium channel
  • online soma
  • ambien 20mg
  • hair loss in children
  • best hair loss treatment
  • hand skin problems
  • good guide health womans
  • zyban pharmacy
  • buy singulair
  • what is generic viagra
  • chewable viagra
  • buy pain pills on line
  • new medicine for diabetes
  • osteoporosis therapy
  • strength training
  • tips to help loss weight
  • relieve pain in neck
  • increasing breast size naturally
  • new fda diet pill
  • vardenafil effectiveness
  • ambien 10
  • dog s health
  • severe leg muscle pain
  • dietary drug
  • alprazolam
  • allergies singulair
  • alternative therapy for rheumatoid arthritis
  • anxiety
  • new diet supplements
  • care dog skin
  • hair loss treatments for women
  • fluconazole interaction
  • carisoprodol price
  • online kamagra
  • infection lung
  • effective weight loss
  • lopressor drug
  • antibiotics gonorrhea
  • stress relievers
  • effexor dose
  • dog s health
  • generic online order viagra
  • buy generic cialis online
  • food allergies
  • scabies treatments
  • buy stopping diabetes
  • drugs for energy
  • repels insects
  • cialis on line
  • cheap baclofen
  • treatmemt of diabetes
  • treatment of obesity
  • where can i buy arthritis drugs
  • medical chlamydia
  • does levitra work
  • generic 5mg proscar cheap
  • cancer medications
  • prescription medication
  • abnormal blood clots
  • blood pressure treatment
  • cialis contraindications
  • online paxil
  • on line drug stores
  • control premature ejaculation
  • prozac depression
  • pain in chest
  • cheap canadian pharmacy
  • muscle and fitness
  • how to find medication prescriptions xanax
  • how do a stop smoking
  • simvastatin reaction
  • cheapest levitra
  • flu medicine
  • nausea cure
  • celebrex information
  • online pharmacy discount
  • online pharmacy discount drugs
  • over weight dog
  • diet and health products
  • lamisil generic
  • strength training
  • buy levitra online with fast delivery
  • weight loss drugs order
  • depression in men
  • dog health help
  • medication for depression
  • high blood calcium level
  • generic amoxicillin
  • cures for lung cancer
  • diet and health products
  • buy levaquin
  • drugs weight loss
  • prevention of hypertension
  • drugs for depression
  • sildenafil kamagra
  • cialis alcohol
  • singulair generic
  • pain management
  • wellbutrin cymbalta
  • buy zocor
  • cholesterol treatment
  • singulair generic
  • zoloft discount
  • european online pharmacy