PageRenderTime 93ms CodeModel.GetById 40ms app.highlight 7ms RepoModel.GetById 43ms app.codeStats 0ms

/source/temple/utils/FrameDelay.as

http://templelibrary.googlecode.com/
ActionScript | 213 lines | 91 code | 23 blank | 99 comment | 11 complexity | 8c44100bb74efdb9d4672d4f0bf3d863 MD5 | raw file
  1/*
  2 *	Temple Library for ActionScript 3.0
  3 *	Copyright Š MediaMonks B.V.
  4 *	All rights reserved.
  5 *	
  6 *	Redistribution and use in source and binary forms, with or without
  7 *	modification, are permitted provided that the following conditions are met:
  8 *	1. Redistributions of source code must retain the above copyright
  9 *	   notice, this list of conditions and the following disclaimer.
 10 *	2. Redistributions in binary form must reproduce the above copyright
 11 *	   notice, this list of conditions and the following disclaimer in the
 12 *	   documentation and/or other materials provided with the distribution.
 13 *	3. All advertising materials mentioning features or use of this software
 14 *	   must display the following acknowledgement:
 15 *	   This product includes software developed by MediaMonks B.V.
 16 *	4. Neither the name of MediaMonks B.V. nor the
 17 *	   names of its contributors may be used to endorse or promote products
 18 *	   derived from this software without specific prior written permission.
 19 *	
 20 *	THIS SOFTWARE IS PROVIDED BY MEDIAMONKS B.V. ''AS IS'' AND ANY
 21 *	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 22 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 23 *	DISCLAIMED. IN NO EVENT SHALL MEDIAMONKS B.V. BE LIABLE FOR ANY
 24 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 25 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 26 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 27 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 28 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 29 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 30 *	
 31 *	
 32 *	Note: This license does not apply to 3rd party classes inside the Temple
 33 *	repository with their own license!
 34 */
 35
 36package temple.utils 
 37{
 38	import temple.common.interfaces.IPauseable;
 39	import temple.core.CoreObject;
 40	import temple.core.debug.IDebuggable;
 41	import temple.utils.types.FunctionUtils;
 42
 43	import flash.events.Event;
 44
 45
 46	/**
 47	 * Delay a function call with one or more frames. Use this when initializing a SWF or a bunch of DisplayObjects, to enable the player to do its thing.	Usually a single frame delay will do the job, since the next enterFrame will come when all other jobs are finished.
 48	 * To execute function 'init' after 1 frame, use:
 49	 * 
 50	 * @example
 51	 * <listing version="3.0">
 52	 * new FrameDelay(init);
 53	 * </listing>
 54	 * 
 55	 * To execute function 'init' after 10 frames, use:
 56	 * <listing version="3.0">
 57	 * new FrameDelay(init, 10);
 58	 * </listing>
 59	 * 
 60	 * To call function 'setProps' with parameters, executed after 1 frame:
 61	 * <listing version="3.0">
 62	 * new FrameDelay(setProps, 1, [shape, 'alpha', 0]);
 63	 * </listing>
 64	 * 
 65	 * <listing version="3.0">
 66	 * private function setProps (shape:Shape, property:String, value:Number):void
 67	 * {
 68	 * 		shape[property] = value;
 69	 * }
 70	 * </listing>
 71	 * 
 72	 * @author ASAPLibrary, Thijs Broerse
 73	 */
 74	public class FrameDelay extends CoreObject implements IPauseable, IDebuggable
 75	{
 76		/**
 77		 * Make frame-delayed callback: (eg: a closure to .resume() of a paused FrameDelay)
 78		 */
 79		public static function closure(callback:Function, frameCount:int = 1, params:Array = null):Function
 80		{
 81			var fd:FrameDelay = new FrameDelay(callback, frameCount, params);
 82			fd.pause();
 83			return fd.resume;
 84		}
 85		
 86		private var _isDone:Boolean = false;
 87		private var _currentFrame:int;
 88		private var _callback:Function;
 89		private var _params:Array;
 90		private var _paused:Boolean;
 91		private var _debug:Boolean;
 92		private var _callbackString:String;
 93
 94		/**
 95		 * Creates a new FrameDelay. Starts the delay immediately.
 96		 * @param callback the callback function to be called when done waiting
 97		 * @param frameCount the number of frames to wait; when left out, or set to 1 or 0, one frame is waited
 98		 * @param params list of parameters to pass to the callback function
 99		 * @param debug if set to true, debug information will be logged.
100		 */
101		public function FrameDelay(callback:Function, frameCount:int = 1, params:Array = null, debug:Boolean = false) 
102		{
103			this.toStringProps.push('callback');
104			
105			this._currentFrame = frameCount;
106			this._callback = callback;
107			this._params = params;
108			this._isDone = frameCount <= 1;
109			FramePulse.addEnterFrameListener(this.handleEnterFrame);
110			
111			this.debug = debug;
112		}
113
114		/**
115		 * Returns the callback as a String, useful for debug purposes.
116		 */
117		public function get callback():String
118		{
119			return this._callbackString ||= FunctionUtils.functionToString(this._callback);
120		}
121		
122		/**
123		 * @inheritDoc
124		 */
125		public function pause():void
126		{
127			if (this.debug) this.logDebug("pause: ");
128			
129			FramePulse.removeEnterFrameListener(this.handleEnterFrame);
130			this._paused = true;
131		}
132		
133		/**
134		 * @inheritDoc
135		 */
136		public function resume():void
137		{
138			if (this.debug) this.logDebug("resume: ");
139			
140			if (!this.isDestructed && this._paused)
141			{
142				FramePulse.addEnterFrameListener(handleEnterFrame);
143			}
144		}
145		
146		/**
147		 * @inheritDoc
148		 */
149		public function get paused():Boolean
150		{
151			return this._paused;
152		}
153		
154		/**
155		 * @inheritDoc
156		 */
157		public function get debug():Boolean
158		{
159			return this._debug;
160		}
161
162		/**
163		 * @inheritDoc
164		 */
165		public function set debug(value:Boolean):void
166		{
167			this._debug = value;
168		}
169
170		/**
171		 * Handle the Event.ENTER_FRAME event.
172		 * Checks if still waiting - when true: calls callback function.
173		 * @param event not used
174		 */
175		private function handleEnterFrame(event:Event):void 
176		{
177			if (this._isDone) 
178			{
179				FramePulse.removeEnterFrameListener(this.handleEnterFrame);
180				if (this._callback != null)
181				{
182					if (this.debug) this.logDebug("Done, execute callback: ");
183					
184					this._callback.apply(null, this._params);
185				}
186				this.destruct();
187			}
188			else 
189			{
190				this._currentFrame--;
191				this._isDone = (this._currentFrame <= 1);
192				
193				if (this.debug) this.logDebug("handleEnterFrame: wait for " + this._currentFrame + " frames...");
194			}
195		}
196		
197		/**
198		 * Release reference to creating object.
199		 * Use this to remove a FrameDelay object that is still running when the creating object will be removed.
200		 */
201		override public function destruct():void 
202		{
203			if (this.debug) this.logDebug("destruct: ");
204			
205			FramePulse.removeEnterFrameListener(this.handleEnterFrame);
206			
207			this._callback = null;
208			this._params = null;
209			
210			super.destruct();
211		}
212	}
213}