Created
November 4, 2011 20:58
-
-
Save bustardcelly/1340472 to your computer and use it in GitHub Desktop.
Deferred IViewElement attachment to a subclass of Group on which children are defined in MXML markup.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.events.Event; | |
import mx.events.FlexEvent; | |
import spark.components.Group; | |
/** | |
* Use the deferredElements property as the modifier that is handed the list of IVisualElements defined in MXML. | |
*/ | |
[DefaultProperty("deferredElements")] | |
/** | |
* Group container extension in order to do deferred child element attachment. | |
*/ | |
public class DeferredGroup extends Group | |
{ | |
protected var _elementAddQuota:int = 10; | |
/* IVisualElement[] */ | |
protected var _deferredElements:Array; | |
protected var _deferredElementsChanged:Boolean; | |
protected var _deferredElementAttacher:IDeferredElementAttacher; | |
public function DeferredGroup() | |
{ | |
super(); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
override protected function commitProperties():void | |
{ | |
super.commitProperties(); | |
if( _deferredElementsChanged ) | |
{ | |
queueDeferredElements(); | |
_deferredElementsChanged = false; | |
} | |
} | |
/** | |
* Defines and executes the IDeferredElementAttacher implementation used in queue-ing up "packs" of IVisualElement instances declared in MXML and assigned as deferredElements. | |
*/ | |
protected function queueDeferredElements():void | |
{ | |
// Define IDeferredElementAttacher and listen for completion on attach of all elements within deferredElements. | |
_deferredElementAttacher = new FrameDeferredElementAttacher( this ); | |
_deferredElementAttacher.addEventListener( Event.COMPLETE, handleDeferredAttachmentComplete, false, 0, true ); | |
// "Chunk" up lists of IVisualElements based on limit quota. | |
var i:int; | |
var startIndex:int; | |
var endIndex:int; | |
var length:int = _deferredElements.length; | |
var count:int = Math.ceil(length / _elementAddQuota); | |
for( i = 0; i < count; i++ ) | |
{ | |
startIndex = i * _elementAddQuota; | |
endIndex = startIndex + _elementAddQuota; | |
endIndex = ( endIndex > length ) ? length : endIndex; | |
_deferredElementAttacher.addElementPack( _deferredElements.slice( startIndex, endIndex ) ); | |
} | |
_deferredElementAttacher.start(); | |
} | |
/** | |
* Event handler for completion from the IDeferredElementAttacher instance. | |
* @param evt Event | |
*/ | |
protected function handleDeferredAttachmentComplete( evt:Event ):void | |
{ | |
// Kill reference. | |
_deferredElementAttacher.removeEventListener( Event.COMPLETE, handleDeferredAttachmentComplete, false ); | |
_deferredElementAttacher.dispose(); | |
_deferredElementAttacher = null; | |
// -> Do whatever you normally would do in a handler for CREATION_COMPLETE. | |
} | |
/** | |
* The amount of IVisualElements to "chunk" into packets for deferred queue. | |
* @return int | |
*/ | |
public function get elementAddQuota():int | |
{ | |
return _elementAddQuota; | |
} | |
public function set elementAddQuota( value:int ):void | |
{ | |
_elementAddQuota = value; | |
} | |
/** | |
* The DefaultProperty array of IVisualElements declared in MXML markup. | |
* @return Array Required to be IVisualElement[] | |
*/ | |
public function get deferredElements():Array | |
{ | |
return _deferredElements; | |
} | |
public function set deferredElements( value:Array ):void | |
{ | |
if( _deferredElements == value ) return; | |
_deferredElements = value; | |
_deferredElementsChanged = true; | |
invalidateProperties(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.events.Event; | |
import flash.events.EventDispatcher; | |
import flash.events.IEventDispatcher; | |
import mx.core.IVisualElement; | |
import mx.core.IVisualElementContainer; | |
[Event(name="complete", type="flash.events.Event")] | |
/** | |
* IDeferredElementAttacher implementation that adds "packs" of IVisualElements based on frame progression. | |
*/ | |
public class FrameDeferredElementAttacher extends EventDispatcher implements IDeferredElementAttacher | |
{ | |
/** | |
* Target container to add IVisualElements to. | |
*/ | |
protected var target:IVisualElementContainer; | |
/** | |
* List of arrays of IVisualElement | |
*/ | |
protected var packs:Vector.<Array>; | |
/** | |
* Instantiates new instance with target container to add elements to. | |
* @param target IVisualElementContainer | |
*/ | |
public function FrameDeferredElementAttacher( target:IVisualElementContainer ) | |
{ | |
this.target = target; | |
packs = new Vector.<Array>(); | |
} | |
/** | |
* Assigns frame handler. | |
*/ | |
protected function addDeferredHandler():void | |
{ | |
(target as IEventDispatcher).addEventListener( Event.ENTER_FRAME, handleFrame, false, 0, true ); | |
} | |
/** | |
* Removes frame handler. | |
*/ | |
protected function removeDeferredHandler():void | |
{ | |
(target as IEventDispatcher).removeEventListener( Event.ENTER_FRAME, handleFrame, false ); | |
} | |
/** | |
* Frame event handler. | |
* @param evt Event | |
*/ | |
protected function handleFrame( evt:Event ):void | |
{ | |
if( packs.length > 0 ) | |
{ | |
/* IVisualElement */ | |
// Pop packet and add elements to target. | |
var elements:Array = packs.shift(); | |
while( elements.length > 0 ) | |
{ | |
target.addElement( elements.shift() as IVisualElement ); | |
} | |
} | |
else | |
{ | |
// Emptied. Dispatch complete. | |
removeDeferredHandler(); | |
dispatchEvent( new Event( Event.COMPLETE ) ); | |
} | |
} | |
/** | |
* @copy IDeferredElementAttacher#addElementPack() | |
*/ | |
public function addElementPack( value:Array /* IVisualElement */ ):void | |
{ | |
packs[packs.length] = value; | |
} | |
/** | |
* @copy IDeferredElementAttacher#start() | |
*/ | |
public function start():void | |
{ | |
addDeferredHandler(); | |
} | |
/** | |
* @copy IDeferredElementAttacher#stop() | |
*/ | |
public function stop():void | |
{ | |
removeDeferredHandler(); | |
} | |
/** | |
* @copy IDeferredElementAttacher#dispose() | |
*/ | |
public function dispose():void | |
{ | |
stop(); | |
target = null; | |
packs = null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.events.IEventDispatcher; | |
[Event(name="complete", type="flash.events.Event")] | |
/** | |
* Queues and dequeue "packs" of IVisualElement instances to be attached to a target container. | |
*/ | |
public interface IDeferredElementAttacher extends IEventDispatcher | |
{ | |
/** | |
* Adds "pack" of IVisualElement to queue. | |
* @param value Array Array of IVisualElement | |
*/ | |
function addElementPack( value:Array /* IVisualElement */ ):void; | |
/** | |
* Starts dequeue. | |
*/ | |
function start():void; | |
/** | |
* Stops its operation. | |
*/ | |
function stop():void; | |
/** | |
* Kills references and ready for GC. | |
*/ | |
function dispose():void; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package | |
{ | |
import flash.events.Event; | |
import flash.events.EventDispatcher; | |
import flash.events.TimerEvent; | |
import flash.utils.Timer; | |
import mx.core.IVisualElement; | |
import mx.core.IVisualElementContainer; | |
[Event(name="complete", type="flash.events.Event")] | |
/** | |
* IDeferredElementAttacher implementation that adds "packs" of IVisualElements based on a defined time delay. | |
*/ | |
public class TimerDeferredElementAttacher extends EventDispatcher implements IDeferredElementAttacher | |
{ | |
protected var target:IVisualElementContainer; | |
/* [] -> IVisualElement[] */ | |
protected var packs:Vector.<Array>; | |
protected var timer:Timer; | |
/** | |
* Instantiates new instance with target container to add elements to. | |
* @param target IVisualElementContainer | |
* @param delay int | |
*/ | |
public function TimerDeferredElementAttacher( target:IVisualElementContainer, delay:int = 100 ) | |
{ | |
this.target = target; | |
this.packs = new Vector.<Array>(); | |
establishTimer( delay ); | |
} | |
/** | |
* @private | |
* | |
* Creates and establishes handlers on timer. | |
* @param delay int | |
*/ | |
protected function establishTimer( delay:int ):void | |
{ | |
timer = new Timer( delay, 1 ); | |
timer.addEventListener( TimerEvent.TIMER_COMPLETE, handleTimerComplete, false, 0, true ); | |
} | |
/** | |
* @private | |
* | |
* Stops and removes handlers on timer. | |
*/ | |
protected function killTimer():void | |
{ | |
stop(); | |
timer.removeEventListener( TimerEvent.TIMER_COMPLETE, handleTimerComplete, false ); | |
} | |
/** | |
* @private | |
* | |
* Event handler for timer complete. | |
* @param evt Event | |
*/ | |
protected function handleTimerComplete( evt:Event ):void | |
{ | |
if( packs.length > 0 ) | |
{ | |
/* IVisualElement */ | |
var elements:Array = packs.shift(); | |
while( elements.length > 0 ) | |
{ | |
target.addElement( elements.shift() as IVisualElement ); | |
} | |
timer.start(); | |
} | |
else | |
{ | |
timer.stop(); | |
timer.reset(); | |
dispatchEvent( new Event( Event.COMPLETE ) ); | |
} | |
} | |
/** | |
* @copy IDeferredElementAttacher#addElementPack() | |
*/ | |
public function addElementPack( value:Array /* IVisualElement */ ):void | |
{ | |
packs[packs.length] = value; | |
} | |
/** | |
* @copy IDeferredElementAttacher#start() | |
*/ | |
public function start():void | |
{ | |
timer.start(); | |
} | |
/** | |
* @copy IDeferredElementAttacher#stop() | |
*/ | |
public function stop():void | |
{ | |
timer.stop(); | |
timer.reset(); | |
} | |
/** | |
* @copy IDeferredElementAttacher#dispose() | |
*/ | |
public function dispose():void | |
{ | |
killTimer(); | |
target = null; | |
packs = null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment