forked from: Automatically Cleaning up Closures

by swfgeek forked from Automatically Cleaning up Closures (diff: 1)
♥0 | Line 49 | Modified 2011-08-21 00:34:05 | MIT License
play

ActionScript3 source code

/**
 * Copyright swfgeek ( http://wonderfl.net/user/swfgeek )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bDbO
 */

// forked from jonnyreeves83's Automatically Cleaning up Closures
package {
    import flash.net.URLRequest;
    import flash.net.URLLoader;
    import flash.events.IEventDispatcher;
    import flash.text.TextField;
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.utils.setTimeout;
    
    public class FlashTest extends Sprite {
        private var _output : TextField;
        
        public function FlashTest() {
            initOutputTextField();
            
            // The inline function will be invoked when this object dispatches Event.COMPLETE.
            when(this, Event.COMPLETE, function(e:Event) : void { 
                log("EventHeard");
                
                // Proove that when() has not left any eventlisteners hanging around.
                log("Has eventListener: " + hasEventListener(Event.COMPLETE));
            });
            
            // This inline function will be invoked when this object dispatches Event.CONNECT
            const connectEventClosure :  Function = when(this, Event.CONNECT, function(e : Event) : void {
                // However, it will never ben invoked because the closure bound to Event.COMPLETE
                // is removing the event listner to demonstrate how we can clean up.
                log("Will not be invoked");  
            });

            
            // Simulate something happening in the future...  In actual production code this
            // could be a URLLoader firing Event.COMPLETE, etc.
            log("Init");
            
            setTimeout(function() : void {
                dispatchEvent(new Event(Event.COMPLETE));
                
                // Remove the handler bound to Event.CONNECT
                removeEventListener(Event.CONNECT, connectEventClosure);
            }, 1500);
            
            setTimeout(function() : void {
                dispatchEvent(new Event(Event.CONNECT));
            }, 2000);
        }
        
        private function when(dispatcher : IEventDispatcher, eventType : String, callback : Function, useCapture : Boolean = false, priority : int = 0, useWeakReference : Boolean = false) : Function {
            // This closure will be become the listener function.
            const closure : Function = function(event : Event) : void {
                // Remove the listener we added on the line above.
                dispatcher.removeEventListener(eventType, closure);
                
                // Invoke the supplied delegate.
                callback(event);
            };
            
            // Bind the above closure to the supplied dispatcher
            dispatcher.addEventListener(eventType, closure, useCapture, priority, useWeakReference);
            
            // Return a reference to the inner closure so that it can be removed if necessary,
            // for example as part of a destroy() method.
            return closure;
        }

        
        
        private function initOutputTextField() : void {
            // write as3 code here..
            _output = new TextField();
            _output.multiline = true;
            _output.wordWrap = true;
            _output.height = stage.stageWidth;
            _output.width = stage.stageWidth;
            addChild(_output);
        }

        private function log(message : String) : void {
            _output.appendText(message + "\n");
        }

    }
}