Thankfully, the people at Adobe at least gave us a way to work around this CPU deathtrap. You can mark your bindings to evaluate on a custom event type like this: [Bindable('myCustomEventType')]. If you use this wisely then the player will know exactly which property to check out when it detects the event, moving the binding evaluation time back from O(n) to constant time. Much better.
In past projects I've used this method with generic fash.events.Event objects to great success. However, on my current project Jonathan Branam, the lead architect, wanted to be more "correct" and use custom PropertyChangeEvents. Okay, makes sense, should be no problem, right? Well, it was a small problem. So, I set up my custom binding like this:
/**
* The current number of bytes loaded by the server during upload.
*/
protected var _bytesLoaded:int = 0;
[Bindable('bytesLoadedChanged')]
/** @copy #_bytesLoaded **/
public function get bytesLoaded():int{
return _bytesLoaded;
}
public function set bytesLoaded(value:int):void{
if(_bytesLoaded != value){ // only set the value if its different
var oldValue:int = _bytesLoaded;
_bytesLoaded = value;
dispatchEvent(new PropertyChangeEvent('bytesLoadedChanged',
false, false, PropertyChangeEventKind.UPDATE,
_bytesLoaded, oldValue, value, this));
}
}
Then I ran my code and the bindings didn't evaluate. It looked right to me, so what was the problem? I looked at the documentation for PropertyChangeEvent (duh, probably should have been a first step) and found this for the "property" property: "A String, QName, or int specifying the property that changed." So, the "property" property of the PropertyChangeEvent should be the NAME of the property that changed, not a reference to that property (follow that?). That amounted to changing three characters, instead of:
dispatchEvent(new PropertyChangeEvent('bytesLoadedChanged',
false, false, PropertyChangeEventKind.UPDATE,
_bytesLoaded, oldValue, value, this));
I now have:
dispatchEvent(new PropertyChangeEvent('bytesLoadedChanged',
false, false, PropertyChangeEventKind.UPDATE,
'bytesLoaded', oldValue, value, this));
And now my bindings work! For some reason having that property set incorrectly was preventing the player from identifying that I had dispatched a binding event. My guess is that it silently was causing an exception in the PropertyChangeEvent constructor, but I'm not sure. What I do know is that now my bindings work, they're efficient, and they're "correct." And I'm happy.

0 comments:
Post a Comment