Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[Invalidate] support for non-UIComponents and removed promise features.

Removed AS3 promises (Promise Specification C / jQuery standard) classes
- Now in AS3 promises repository
Fixed InvalidationTracker
- now [Invalidate] on non-UIComponents
- now properly invokes optional callback
- now throttles callback to defer invocation 1-2 frames
  • Loading branch information...
commit d46d6cf72ea4efbb7222b1bcfb851a4f37009cef 1 parent 6fe69ff
Thomas Burleson ThomasBurleson authored
2  .actionScriptProperties
... ... @@ -1,6 +1,6 @@
1 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 2 <actionScriptProperties analytics="false" mainApplicationPath="foundation.as" projectUUID="c404e846-5879-4b64-92d8-b5a70efef147" version="10">
3   - <compiler additionalCompilerArguments="-locale en_US &#10;-keep-as3-metadata+=Invalidate &#10;-define=CONFIG::FLEX3,false&#10;-define=CONFIG::FLEX4,true" autoRSLOrdering="true" copyDependentFiles="false" flex3CompatMode="false" flexSDK="Flex 4.5.1" fteInMXComponents="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
  3 + <compiler additionalCompilerArguments="-locale en_US &#10;-keep-as3-metadata+=Invalidate &#10;-define=CONFIG::FLEX3,false&#10;-define=CONFIG::FLEX4,true" autoRSLOrdering="true" copyDependentFiles="false" flex3CompatMode="false" flexSDK="Flex 4.6.0" fteInMXComponents="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
4 4 <compilerSourcePath/>
5 5 <libraryPath defaultLinkType="0">
6 6 <libraryPathEntry kind="4" path="">
5 .flexLibProperties
... ... @@ -1,5 +1,5 @@
1 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2   -<flexLibProperties includeAllClasses="false" useMultiPlatformConfig="false" version="3">
  2 +<flexLibProperties includeAllClasses="true" useMultiPlatformConfig="false" version="3">
3 3 <includeClasses>
4 4 <classEntry path="asset.image.cursor.CursorAsset"/>
5 5 <classEntry path="asset.image.search.SearchAsset"/>
@@ -107,9 +107,6 @@
107 107 <classEntry path="com.codecatalyst.util.invalidation.InvalidationTrackedProperty"/>
108 108 <classEntry path="com.codecatalyst.util.invalidation.InvalidationTracker"/>
109 109 <classEntry path="com.codecatalyst.util.invalidation.mxml.InvalidationTracker"/>
110   - <classEntry path="com.codecatalyst.util.promise.Deferred"/>
111   - <classEntry path="com.codecatalyst.util.promise.Promise"/>
112   - <classEntry path="com.codecatalyst.util.promise.PromiseUtil"/>
113 110 <classEntry path="qs.charts.DashedAreaRenderer"/>
114 111 <classEntry path="qs.charts.DashedLineRenderer"/>
115 112 <classEntry path="qs.utils.GraphicsUtils"/>
BIN  bin/flex-extensions.swc
Binary file not shown
BIN  bin/flex-extensions_sdk3.6.swc
Binary file not shown
BIN  bin/flex-extensions_sdk4.5.1.swc
Binary file not shown
17 src/com/codecatalyst/util/AsyncTokenUtil.as
@@ -22,9 +22,6 @@
22 22
23 23 package com.codecatalyst.util
24 24 {
25   - import com.codecatalyst.util.promise.Deferred;
26   - import com.codecatalyst.util.promise.Promise;
27   -
28 25 import mx.rpc.AsyncToken;
29 26 import mx.rpc.IResponder;
30 27 import mx.rpc.Responder;
@@ -101,19 +98,5 @@ package com.codecatalyst.util
101 98 return proxyToken;
102 99 }
103 100
104   - /**
105   - * Create a Promise for the specified AsyncToken.
106   - *
107   - * @see com.codecatalyst.util.promise.Promise
108   - */
109   - public static function createPromise( token:AsyncToken ):Promise
110   - {
111   - var deferred:Deferred = new Deferred();
112   -
113   - var responder:Responder = new Responder( deferred.resolve, deferred.reject );
114   - token.addResponder( responder );
115   -
116   - return deferred.promise;
117   - }
118 101 }
119 102 }
22 src/com/codecatalyst/util/invalidation/InvalidationTrackedProperty.as
@@ -102,6 +102,12 @@ package com.codecatalyst.util.invalidation
102 102 return _previousValue;
103 103 }
104 104
  105 + /**
  106 + * Support to defer `reset()` when callbacks on non-IInvalidating are used.
  107 + * Set to `false` to allow "throttled" callbacks to used; @see InvalidationTracker::applyThrottler()
  108 + */
  109 + public var autoReset : Boolean = true;
  110 +
105 111 // ========================================
106 112 // Constructor
107 113 // ========================================
@@ -242,7 +248,7 @@ package com.codecatalyst.util.invalidation
242 248 */
243 249 public function invalidate():void
244 250 {
245   - if (_invalidated == false)
  251 + if ( _invalidated == false )
246 252 {
247 253 _invalidated = true;
248 254
@@ -270,11 +276,16 @@ package com.codecatalyst.util.invalidation
270 276 if ( callback != null )
271 277 {
272 278 var currentValue:* = PropertyUtil.getObjectPropertyValue( source, propertyName );
273   -
  279 +
274 280 if ( callback.length == 3 )
275 281 callback( propertyName, previousValue, currentValue );
276 282 else
277 283 callback();
  284 +
  285 + if ( !(source is IInvalidating) && autoReset )
  286 + {
  287 + reset();
  288 + }
278 289 }
279 290
280 291 }
@@ -283,9 +294,8 @@ package com.codecatalyst.util.invalidation
283 294 * Reset this invalidated tracked property.
284 295 */
285 296 public function reset():void
286   - {
287   - _invalidated = false;
288   -
  297 + {
  298 + _invalidated = false;
289 299 _previousValue = PropertyUtil.getObjectPropertyValue( source, propertyName );
290 300 }
291 301
@@ -312,5 +322,7 @@ package com.codecatalyst.util.invalidation
312 322 }
313 323
314 324 private var _customEventName : String;
  325 +
  326 +
315 327 }
316 328 }
58 src/com/codecatalyst/util/invalidation/InvalidationTracker.as
@@ -22,11 +22,13 @@
22 22
23 23 package com.codecatalyst.util.invalidation
24 24 {
  25 + import com.codecatalyst.util.DelayedCall;
25 26 import com.codecatalyst.util.MetadataUtil;
26 27
27 28 import flash.events.IEventDispatcher;
28 29 import flash.utils.Dictionary;
29 30
  31 + import mx.core.IInvalidating;
30 32 import mx.events.FlexEvent;
31 33 import mx.utils.DescribeTypeCache;
32 34 import mx.utils.StringUtil;
@@ -76,16 +78,64 @@ package com.codecatalyst.util.invalidation
76 78 /**
77 79 * Constructor.
78 80 */
79   - public function InvalidationTracker( source:IEventDispatcher, callback:Function = null )
  81 + public function InvalidationTracker( source:IEventDispatcher, callback:Function = null, enableThrottle:Boolean=false )
80 82 {
81 83 super();
82 84
83 85 this.source = source;
84   - this.callback = callback;
  86 + this.callback = applyThrottle( callback, enableThrottle );
85 87
86 88 setup();
87 89 }
88 90
  91 + /**
  92 + * Defer notification via explicit callback for 1-2 frames IF the source
  93 + * is not IInvalidating and user has explicitly requested throttling.
  94 + *
  95 + * NOTE: only callbacks with zero-args can be throttled.
  96 + */
  97 + private function applyThrottle(callback:Function, enable:Boolean) : Function
  98 + {
  99 + var allowed : Boolean = callback && enable && !(source is IInvalidating);
  100 + var delayed : Boolean = false;
  101 +
  102 + /**
  103 + * Since the throttler can be invoked n-times [while deferred]
  104 + * each time with different (propertyName, ...) values.
  105 + * So we restrict throttling only for callbacks with zero-arguments!
  106 + */
  107 + var throttler : Function = function() :void
  108 + {
  109 + // !! The scope of throttler callback is an ITP instance
  110 + this["autoReset"] = false;
  111 +
  112 + // Ignore current callback if `real` is still pending.
  113 + if ( !delayed )
  114 + {
  115 + delayed = true;
  116 +
  117 + // Defer notification for 1-2 frames...
  118 + DelayedCall.schedule( function():void
  119 + {
  120 + delayed = false;
  121 +
  122 + // Call `real` callback 1x
  123 + callback();
  124 +
  125 + // now force reset() on all ITP instances
  126 + for each ( var inst:InvalidationTrackedProperty in trackedProperties )
  127 + {
  128 + inst.reset();
  129 + }
  130 +
  131 + }, [], 45);
  132 + }
  133 +
  134 + };
  135 +
  136 + return allowed ? throttler : callback;
  137 + }
  138 +
89 139 // ========================================
90 140 // Public methods
91 141 // ========================================
@@ -228,7 +278,9 @@ package com.codecatalyst.util.invalidation
228 278
229 279 invalidateMetadataOptions
230 280 .split(",")
231   - .map( function ( item:String, index:int, array:Array ):uint {
  281 + .map( function ( item:String, index:int, array:Array ):uint {
  282 + if (item == "") return InvalidationFlags.NONE;
  283 +
232 284 switch( StringUtil.trim( item ).toLowerCase() )
233 285 {
234 286 case "displaylist": return InvalidationFlags.DISPLAY_LIST;
550 src/com/codecatalyst/util/promise/Deferred.as
... ... @@ -1,550 +0,0 @@
1   -////////////////////////////////////////////////////////////////////////////////
2   -// Copyright (c) 2011 CodeCatalyst, LLC - http://www.codecatalyst.com/
3   -//
4   -// Permission is hereby granted, free of charge, to any person obtaining a copy
5   -// of this software and associated documentation files (the "Software"), to deal
6   -// in the Software without restriction, including without limitation the rights
7   -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   -// copies of the Software, and to permit persons to whom the Software is
9   -// furnished to do so, subject to the following conditions:
10   -//
11   -// The above copyright notice and this permission notice shall be included in
12   -// all copies or substantial portions of the Software.
13   -//
14   -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   -// THE SOFTWARE.
21   -////////////////////////////////////////////////////////////////////////////////
22   -
23   -package com.codecatalyst.util.promise
24   -{
25   - import flash.events.Event;
26   - import flash.events.EventDispatcher;
27   -
28   - /**
29   - * Deferred.
30   - *
31   - * A chainable utility object that can register multiple callbacks into callback queues, invoke callback queues,
32   - * and relay the success, failure and progress state of any synchronous or asynchronous operation.
33   - *
34   - * @see com.codecatalyst.util.promise.Promise
35   - *
36   - * Inspired by jQuery's Deferred implementation.
37   - *
38   - * @author John Yanarella
39   - */
40   - public class Deferred extends EventDispatcher
41   - {
42   - // ========================================
43   - // Protected constants
44   - // ========================================
45   -
46   - /**
47   - * Internal state change Event type.
48   - */
49   - internal static const STATE_CHANGED:String = "stateChanged";
50   -
51   - // ========================================
52   - // Protected constants
53   - // ========================================
54   -
55   - /**
56   - * State for a Deferred that has not yet been resolved, rejected or cancelled.
57   - */
58   - protected static const PENDING_STATE:String = "pending";
59   -
60   - /**
61   - * State for a Deferred that has been resolved.
62   - */
63   - protected static const SUCCEEDED_STATE:String = "succeeded";
64   -
65   - /**
66   - * State for a Deferred that has been rejected.
67   - */
68   - protected static const FAILED_STATE:String = "failed";
69   -
70   - /**
71   - * State for a Deferred that has been cancelled.
72   - */
73   - protected static const CANCELLED_STATE:String = "cancelled";
74   -
75   - // ========================================
76   - // Public properties
77   - // ========================================
78   -
79   - /**
80   - * Promise.
81   - */
82   - public function get promise():Promise
83   - {
84   - return _promise;
85   - }
86   -
87   - [Bindable( "stateChanged" )]
88   - /**
89   - * Indicates this Deferred has not yet been resolved, rejected or cancelled.
90   - */
91   - public function get pending():Boolean
92   - {
93   - return ( state == PENDING_STATE );
94   - }
95   -
96   - [Bindable( "stateChanged" )]
97   - /**
98   - * Indicates this Deferred has been resolved.
99   - */
100   - public function get succeeded():Boolean
101   - {
102   - return ( state == SUCCEEDED_STATE );
103   - }
104   -
105   - [Bindable( "stateChanged" )]
106   - /**
107   - * Indicates this Deferred has been rejected.
108   - */
109   - public function get failed():Boolean
110   - {
111   - return ( state == FAILED_STATE );
112   - }
113   -
114   - [Bindable( "stateChanged" )]
115   - /**
116   - * Indicates this Deferred has been cancelled.
117   - */
118   - public function get cancelled():Boolean
119   - {
120   - return ( state == CANCELLED_STATE );
121   - }
122   -
123   - [Bindable( "stateChanged" )]
124   - /**
125   - * Progress supplied when this Deferred was updated.
126   - */
127   - public function get progress():*
128   - {
129   - return _progress;
130   - }
131   -
132   - [Bindable( "stateChanged" )]
133   - /**
134   - * Result supplied when this Deferred was resolved.
135   - */
136   - public function get result():*
137   - {
138   - return _result;
139   - }
140   -
141   - [Bindable( "stateChanged" )]
142   - /**
143   - * Error supplied when this Deferred was rejected.
144   - */
145   - public function get error():*
146   - {
147   - return _error;
148   - }
149   -
150   - [Bindable( "stateChanged" )]
151   - /**
152   - * Reason supplied when this Deferred was cancelled.
153   - */
154   - public function get reason():*
155   - {
156   - return _reason;
157   - }
158   -
159   - // ========================================
160   - // Protected properties
161   - // ========================================
162   -
163   - /**
164   - * Backing variable for <code>promise</code> property.
165   - */
166   - protected var _promise:Promise = null;
167   -
168   - /**
169   - * Backing variable for <code>progress</code.
170   - */
171   - protected var _progress:* = null;
172   -
173   - /**
174   - * Backing variable for <code>result</code.
175   - */
176   - protected var _result:* = null;
177   -
178   - /**
179   - * Backing variable for <code>error</code.
180   - */
181   - protected var _error:* = null;
182   -
183   - /**
184   - * Backing variable for <code>reason</code.
185   - */
186   - protected var _reason:* = null;
187   -
188   - /**
189   - * Deferred state.
190   - *
191   - * @see #STATE_PENDING
192   - * @see #STATE_SUCCEEDED
193   - * @see #STATE_FAILED
194   - * @see #STATE_CANCELLED
195   - */
196   - protected var state:String = Deferred.PENDING_STATE;
197   -
198   - /**
199   - * Callbacks to be called when this Deferred is updated.
200   - */
201   - protected var progressCallbacks:Array = [];
202   -
203   - /**
204   - * Callbacks to be called when this Deferred is resolved.
205   - */
206   - protected var resultCallbacks:Array = [];
207   -
208   - /**
209   - * Callbacks to be called when this Deferred is rejected.
210   - */
211   - protected var errorCallbacks:Array = [];
212   -
213   - /**
214   - * Callbacks to be called when this Deferred is cancelled.
215   - */
216   - protected var cancelCallbacks:Array = [];
217   -
218   - /**
219   - * Callbacks to be called when this Deferred is resolved or rejected.
220   - */
221   - protected var alwaysCallbacks:Array = [];
222   -
223   - // ========================================
224   - // Constructor
225   - // ========================================
226   -
227   - /**
228   - * Constructor.
229   - */
230   - public function Deferred()
231   - {
232   - super();
233   -
234   - _promise = new Promise( this );
235   - }
236   -
237   - // ========================================
238   - // Public methods
239   - // ========================================
240   -
241   - /**
242   - * Register callbacks to be called when this Deferred is resolved, rejected, cancelled and updated.
243   - */
244   - public function then( resultCallback:Function, errorCallback:Function = null, progressCallback:Function = null, cancelCallback:Function = null ):Deferred
245   - {
246   - onResult( resultCallback );
247   - onError( errorCallback );
248   - onProgress( progressCallback );
249   - onCancel( cancelCallback );
250   -
251   - return this;
252   - }
253   -
254   - /**
255   - * Registers a callback to be called when this Deferred is either resolved, rejected or cancelled.
256   - */
257   - public function always( alwaysCallback:Function ):Deferred
258   - {
259   - if ( alwaysCallback != null )
260   - {
261   - if ( pending )
262   - {
263   - alwaysCallbacks.push( alwaysCallback );
264   - }
265   - else if ( succeeded )
266   - {
267   - notify( [ alwaysCallback ], result );
268   - }
269   - else if ( failed )
270   - {
271   - notify( [ alwaysCallback ], error );
272   - }
273   - else if ( cancelled )
274   - {
275   - notify( [ alwaysCallback ], reason );
276   - }
277   - }
278   -
279   - return this;
280   - }
281   -
282   - /**
283   - * Utility method to filter and/or chain Deferreds.
284   - */
285   - public function pipe( resultCallback:Function, errorCallback:Function = null ):Promise
286   - {
287   - var deferred:Deferred = new Deferred();
288   -
289   - then(
290   - function ( result:* ):void
291   - {
292   - if ( resultCallback != null )
293   - {
294   - var returnValue:* = resultCallback( result );
295   - if ( returnValue is Deferred )
296   - {
297   - returnValue.promise.then( deferred.resolve, deferred.reject, deferred.update, deferred.cancel );
298   - }
299   - else if ( returnValue is Promise )
300   - {
301   - returnValue.then( deferred.resolve, deferred.reject, deferred.update, deferred.cancel );
302   - }
303   - else
304   - {
305   - deferred.resolve( returnValue );
306   - }
307   - }
308   - else
309   - {
310   - deferred.resolve( result );
311   - }
312   - },
313   - function ( error:* ):void
314   - {
315   - if ( errorCallback != null )
316   - {
317   - var returnValue:* = errorCallback( error );
318   - if ( returnValue is Deferred )
319   - {
320   - returnValue.promise.then( deferred.resolve, deferred.reject, deferred.update, deferred.cancel );
321   - }
322   - else if ( returnValue is Promise )
323   - {
324   - returnValue.then( deferred.resolve, deferred.reject, deferred.update, deferred.cancel );
325   - }
326   - else
327   - {
328   - deferred.reject( returnValue );
329   - }
330   - }
331   - else
332   - {
333   - deferred.reject( error );
334   - }
335   - },
336   - function ( update:* ):void
337   - {
338   - deferred.update( update );
339   - },
340   - function ( reason:* ):void
341   - {
342   - deferred.cancel( reason );
343   - }
344   - );
345   -
346   - return deferred.promise;
347   - }
348   -
349   - /**
350   - * Registers a callback to be called when this Deferred is updated.
351   - */
352   - public function onProgress( progressCallback:Function ):Deferred
353   - {
354   - if ( progressCallback != null )
355   - {
356   - if ( pending )
357   - {
358   - progressCallbacks.push( progressCallback );
359   -
360   - if ( progress != null )
361   - notify( [ progressCallback ], progress );
362   - }
363   - }
364   -
365   - return this;
366   - }
367   -
368   - /**
369   - * Registers a callback to be called when this Deferred is resolved.
370   - */
371   - public function onResult( resultCallback:Function ):Deferred
372   - {
373   - if ( resultCallback != null )
374   - {
375   - if ( pending )
376   - {
377   - resultCallbacks.push( resultCallback );
378   - }
379   - else if ( succeeded )
380   - {
381   - notify( [ resultCallback ], result );
382   - }
383   - }
384   -
385   - return this;
386   - }
387   -
388   - /**
389   - * Registers a callback to be called when this Deferred is rejected.
390   - */
391   - public function onError( errorCallback:Function ):Deferred
392   - {
393   - if ( errorCallback != null )
394   - {
395   - if ( pending )
396   - {
397   - errorCallbacks.push( errorCallback );
398   - }
399   - else if ( failed )
400   - {
401   - notify( [ errorCallback ], error );
402   - }
403   - }
404   -
405   - return this;
406   - }
407   -
408   - /**
409   - * Registers a callback to be called when this Deferred is cancelled.
410   - */
411   - public function onCancel( cancelCallback:Function ):Deferred
412   - {
413   - if ( cancelCallback != null )
414   - {
415   - if ( pending )
416   - {
417   - cancelCallbacks.push( cancelCallback );
418   - }
419   - else if ( failed )
420   - {
421   - notify( [ cancelCallback ], reason );
422   - }
423   - }
424   -
425   - return this;
426   - }
427   -
428   - /**
429   - * Update this Deferred and notify relevant callbacks.
430   - */
431   - public function update( progress:* ):Deferred
432   - {
433   - if ( pending )
434   - {
435   - _progress = progress;
436   -
437   - notify( progressCallbacks, progress );
438   - }
439   -
440   - return this;
441   - }
442   -
443   - /**
444   - * Resolve this Deferred and notify relevant callbacks.
445   - */
446   - public function resolve( result:* ):Deferred
447   - {
448   - if ( pending )
449   - {
450   - _result = result;
451   - setState( Deferred.SUCCEEDED_STATE );
452   -
453   - notify( resultCallbacks.concat( alwaysCallbacks ), result );
454   - releaseCallbacks();
455   - }
456   -
457   - return this;
458   - }
459   -
460   - /**
461   - * Reject this Deferred and notify relevant callbacks.
462   - */
463   - public function reject( error:* ):Deferred
464   - {
465   - if ( pending )
466   - {
467   - _error = error;
468   - setState( Deferred.FAILED_STATE );
469   -
470   - notify( errorCallbacks.concat( alwaysCallbacks ), error );
471   - releaseCallbacks();
472   - }
473   -
474   - return this;
475   - }
476   -
477   - /**
478   - * Cancel this Deferred and notify relevant callbacks.
479   - */
480   - public function cancel( reason:* = null ):Deferred
481   - {
482   - if ( pending )
483   - {
484   - setState( Deferred.CANCELLED_STATE );
485   -
486   - notify( cancelCallbacks.concat( alwaysCallbacks ), reason );
487   - releaseCallbacks();
488   - }
489   -
490   - return this;
491   - }
492   -
493   - // ========================================
494   - // Protected methods
495   - // ========================================
496   -
497   - /**
498   - * Set the state for this Deferred.
499   - *
500   - * @see #pending
501   - * @see #succeeded
502   - * @see #failed
503   - * @see #cancelled
504   - */
505   - protected function setState( value:String ):void
506   - {
507   - if ( value != state )
508   - {
509   - state = value;
510   - dispatchEvent( new Event( STATE_CHANGED ) );
511   - }
512   - }
513   -
514   - /**
515   - * Notify the specified callbacks, optionally passing the a reference to this Deferred and the specified value.
516   - */
517   - protected function notify( callbacks:Array, value:* ):void
518   - {
519   - for each ( var callback:Function in callbacks )
520   - {
521   - switch ( callback.length )
522   - {
523   - case 2:
524   - callback( promise, value );
525   - break;
526   -
527   - case 1:
528   - callback( value );
529   - break;
530   -
531   - default:
532   - callback();
533   - break;
534   - }
535   - }
536   - }
537   -
538   - /**
539   - * Release references to all callbacks registered with this Deferred.
540   - */
541   - protected function releaseCallbacks():void
542   - {
543   - resultCallbacks = [];
544   - errorCallbacks = [];
545   - progressCallbacks = [];
546   - cancelCallbacks = [];
547   - alwaysCallbacks = [];
548   - }
549   - }
550   -}
297 src/com/codecatalyst/util/promise/Promise.as
... ... @@ -1,297 +0,0 @@
1   -////////////////////////////////////////////////////////////////////////////////
2   -// Copyright (c) 2011 CodeCatalyst, LLC - http://www.codecatalyst.com/
3   -//
4   -// Permission is hereby granted, free of charge, to any person obtaining a copy
5   -// of this software and associated documentation files (the "Software"), to deal
6   -// in the Software without restriction, including without limitation the rights
7   -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8   -// copies of the Software, and to permit persons to whom the Software is
9   -// furnished to do so, subject to the following conditions:
10   -//
11   -// The above copyright notice and this permission notice shall be included in
12   -// all copies or substantial portions of the Software.
13   -//
14   -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20   -// THE SOFTWARE.
21   -////////////////////////////////////////////////////////////////////////////////
22   -
23   -package com.codecatalyst.util.promise
24   -{
25   - import flash.events.Event;
26   - import flash.events.EventDispatcher;
27   -
28   - /**
29   - * Promise.
30   - *
31   - * An object that acts as a proxy for observing deferred result, fault or progress state from a synchronous or asynchronous operation.
32   - *
33   - * Inspired by jQuery's Promise implementation.
34   - *
35   - * @author John Yanarella
36   - */
37   - public class Promise extends EventDispatcher
38   - {
39   - // ========================================
40   - // Public properties
41   - // ========================================
42   -
43   - [Bindable( "stateChanged" )]
44   - /**
45   - * Indicates this Promise has not yet been fulfilled.
46   - */
47   - public function get unfulfilled():Boolean
48   - {
49   - return deferred.pending;
50   - }
51   -
52   - [Bindable( "stateChanged" )]
53   - /**
54   - * Indicates this Promise has been fulfilled.
55   - */
56   - public function get fulfilled():Boolean
57   - {
58   - return deferred.succeeded;
59   - }
60   -
61   - [Bindable( "stateChanged" )]
62   - /**
63   - * Indicates this Promise has failed.
64   - */
65   - public function get failed():Boolean
66   - {
67   - return deferred.failed;
68   - }
69   -
70   - [Bindable( "stateChanged" )]
71   - /**
72   - * Indicates this Promise has been cancelled.
73   - */
74   - public function get cancelled():Boolean
75   - {
76   - return deferred.cancelled;
77   - }
78   -
79   - [Bindable( "stateChanged" )]
80   - /**
81   - * Progress supplied when this Promise was updated.
82   - */
83   - public function get progress():*
84   - {
85   - return deferred.progress;
86   - }
87   -
88   - [Bindable( "stateChanged" )]
89   - /**
90   - * Result supplied when this Promise was fulfilled.
91   - */
92   - public function get result():*
93   - {
94   - return deferred.result;
95   - }
96   -
97   - [Bindable( "stateChanged" )]
98   - /**
99   - * Error supplied when this Promise failed.
100   - */
101   - public function get error():*
102   - {
103   - return deferred.error;
104   - }
105   -
106   - [Bindable( "stateChanged" )]
107   - /**
108   - * Reason supplied when this Promise failed.
109   - */
110   - public function get reason():*
111   - {
112   - return deferred.reason;
113   - }
114   -
115   - // ========================================
116   - // Protected properties
117   - // ========================================
118   -
119   - /**
120   - * Deferred operation for which this is a Promise.
121   - */
122   - protected var deferred:Deferred = null;
123   -
124   - // ========================================
125   - // Constructor
126   - // ========================================
127   -
128   - /**
129   - * Constructor.
130   - */
131   - public function Promise( deferred:Deferred )
132   - {
133   - super();
134   -
135   - this.deferred = deferred;
136   -
137   - deferred.addEventListener( Deferred.STATE_CHANGED, deferred_stateChangeHandler, false, 0, true );
138   - }
139   -
140   - // ========================================
141   - // Public static methods
142   - // ========================================
143   -
144   - /**
145   - * Utility method to create a new Promise based on one or more Promises (i.e. parallel chaining).
146   - *
147   - * NOTE: Result and progress handlers added to this new Promise will be passed an Array of aggregated result or progress values.
148   - */
149   - public static function when( ...promises ):Promise
150   - {
151   - var deferred:Deferred = new Deferred();
152   -
153   - // Special handling for when an Array of Promises is specified instead of variable numbe of Promise arguments.
154   - if ( ( promises.length == 1 ) && ( promises[ 0 ] is Array ) )
155   - promises = promises[ 0 ];
156   -
157   - // Ensure the promises Array is populated with Promises.
158   - var parameterCount:int = promises.length;
159   - for ( var parameterIndex:int = 0; parameterIndex < parameterCount; parameterIndex++ )
160   - {
161   - var parameter:* = promises[ parameterIndex ];
162   -
163   - switch ( parameter.constructor )
164   - {
165   - case Promise:
166   - break;
167   -
168   - case Deferred:
169   - // Replace the promises Array element with the associated Promise for the specified Deferred value.
170   - promises[ parameterIndex ] = parameter.promise;
171   - break;
172   -
173   - default:
174   - // Create a new Deferred resolved with the specified parameter value, and replace the promises Array element with the associated Promise.
175   - promises[ parameterIndex ] = new Deferred().resolve( parameter ).promise;
176   - break;
177   - }
178   - }
179   -
180   - var pendingPromiseCount:int = promises.length;
181   -
182   - var progressValues:Array = new Array( pendingPromiseCount );
183   - var resultValues:Array = new Array( pendingPromiseCount );
184   -
185   - for each ( var promise:Promise in promises )
186   - {
187   - promise
188   - .then(
189   - function ( promise:Promise, result:* ):void
190   - {
191   - resultValues[ promises.indexOf( promise ) ] = result;
192   -
193   - pendingPromiseCount--;
194   - if ( pendingPromiseCount == 0 )
195   - deferred.resolve( resultValues );
196   - },
197   - function ( error:* ):void
198   - {
199   - deferred.reject( error );
200   - },
201   - function ( promise:Promise, update:* ):void
202   - {
203   - progressValues[ promises.indexOf( promise ) ] = update;
204   -
205   - deferred.update( progressValues );
206   - },
207   - function ( reason:* ):void
208   - {
209   - deferred.cancel( reason );
210   - }
211   - );
212   - }
213   -
214   - return deferred.promise;
215   - }
216   -
217   - // ========================================
218   - // Public methods
219   - // ========================================
220   -
221   - /**
222   - * Register callbacks to be called when this Promise is resolved or rejected.
223   - */
224   - public function then( resultCallback:Function, errorCallback:Function = null, progressCallback:Function = null, cancelCallback:Function = null ):Promise
225   - {
226   - return deferred.then( resultCallback, errorCallback, progressCallback, cancelCallback ).promise;
227   - }
228   -
229   - /**
230   - * Registers a callback to be called when this Promise is either resolved or rejected.
231   - */
232   - public function always( alwaysCallback:Function ):Promise
233   - {
234   - return deferred.always( alwaysCallback ).promise;
235   - }
236   -
237   - /**
238   - * Utility method to filter and/or chain Deferreds.
239   - */
240   - public function pipe( resultCallback:Function, errorCallback:Function = null ):Promise
241   - {
242   - return deferred.pipe( resultCallback, errorCallback );
243   - }
244   -
245   - /**
246   - * Registers a callback to be called when this Promise is updated.
247   - */
248   - public function onProgress( progressCallback:Function ):Promise
249   - {
250   - return deferred.onProgress( progressCallback ).promise;
251   - }
252   -
253   - /**
254   - * Registers a callback to be called when this Promise is resolved.
255   - */
256   - public function onResult( resultCallback:Function ):Promise
257   - {
258   - return deferred.onResult( resultCallback ).promise;
259   - }
260   -
261   - /**
262   - * Registers a callback to be called when this Promise is rejected.
263   - */
264   - public function onError( errorCallback:Function ):Promise
265   - {
266   - return deferred.onError( errorCallback ).promise;
267   - }
268   -
269   - /**
270   - * Registers a callback to be called when this Promise is cancelled.
271   - */
272   - public function onCancel( cancelCallback:Function ):Promise
273   - {
274   - return deferred.onCancel( cancelCallback ).promise;
275   - }
276   -
277   - /**
278   - * Cancel this Promise.
279   - */
280   - public function cancel( reason:* = null ):void
281   - {
282   - deferred.cancel( reason );
283   - }
284   -
285   - // ========================================
286   - // Protected methods
287   - // ========================================
288   -
289   - /**
290   - * Handle and redispatch state change notifications from the Deferred operation.
291   - */
292   - protected function deferred_stateChangeHandler( event:Event ):void
293   - {
294   - dispatchEvent( event.clone() );
295   - }
296   - }
297   -}
106 src/com/codecatalyst/util/promise/PromiseUtil.as
... ... @@ -1,106 +0,0 @@
1   -package com.codecatalyst.util.promise
2   -{
3   - import com.codecatalyst.util.PropertyUtil;
4   -
5   - import flash.events.Event;
6   - import flash.events.IEventDispatcher;
7   -
8   - /**
9   - * Utility methods related to Promises and adapting Flash and ActionScript asynchronous operations for use with Promises.
10   - *
11   - * @see com.codecatalyst.util.AsyncTokenUtil#createPromise()
12   - *
13   - * @author John Yanarella
14   - */
15   - public class PromiseUtil
16   - {
17   - /**
18   - * Creates a Promise that adapts an asynchronous operation that uses Event based notification, given
19   - * the event dispatcher, a single result event type, an Array of potential fault types, and an optional progress type.
20   - *
21   - * NOTE: Event dispatchers that dispatch Events corresponding to multiple concurrent asynchronous operations cannot be adapted with this approach unless
22   - * there is a 'token' property accessible via the Event or Event target which can be used to correlate an operation with its Events.
23   - * In this case, use the optional eventTokenProperty and eventTokenPropertyPath parameters to specify this token and its path (in dot notation) relative to the Events.
24   - *
25   - * Promise callbacks will be called with the corresponding Event; consider using Promise's pipe() method to process the Event into result or fault values.
26   - * @see com.codecatalyst.util.promise.Promise#pipe()
27   - *
28   - * NOTE: It is critical to specify the result event type and all possible fault event types to avoid introducing memory leaks.
29   - */
30   - public static function listen( dispatcher:IEventDispatcher, resultEventType:String, faultEventTypes:Array, progressEventType:String = null, progressEventProperty:String = null, useCapture:Boolean = false, priority:int = 0, eventTokenPropertyPath:String = null, expectedTokenValue:* = null ):Promise
31