1 package flare.animate.interpolate
3 import flare.util.Property;
5 import flash.utils.getDefinitionByName;
6 import flash.utils.getQualifiedClassName;
9 * Base class for value interpolators. This class also provides factory
10 * methods for creating concrete interpolator instances -- see the
11 * <code>create</code> method for details about interpolator creation.
13 public class Interpolator
15 /** The target object whose property is being interpolated. */
16 protected var _target:Object;
17 /** The property to interpolate. */
18 protected var _prop:Property;
21 * Base constructor for Interpolator instances.
22 * @param target the object whose property is being interpolated
23 * @param property the property to interpolate
24 * @param value the target value of the interpolation
26 public function Interpolator(target:Object, property:String,
27 start:Object, end:Object)
29 reset(target, property, start, end);
33 * Re-initializes an exising interpolator instance.
34 * @param target the object whose property is being interpolated
35 * @param property the property to interpolate
36 * @param value the target value of the interpolation
38 public function reset(target:Object, property:String,
39 start:Object, end:Object):void
42 _prop = Property.$(property);
47 * Performs initialization of an interpolator, typically by
48 * initializing the start and ending values. Subclasses should
49 * override this method for custom initialization.
50 * @param value the target value of the interpolation
52 protected function init(start:Object, end:Object) : void
54 // for subclasses to override
58 * Calculate and set an interpolated property value. Subclasses should
59 * override this method to implement custom interpolation routines.
60 * @param f the interpolation fraction (typically between 0 and 1)
62 public function interpolate(f:Number) : void
64 throw new Error("This is an abstract method");
67 // -- Interpolator Factory --------------------------------------------
69 private static var _maxPoolSize:int = 10000;
70 private static var _pools:Object = [];
71 private static var _lookup:Object = buildLookupTable();
72 private static var _rules:Array = buildRules();
74 private static function buildLookupTable() : Object
76 // add variables to ensure classes are included by compiler
77 var ni:NumberInterpolator;
78 var di:DateInterpolator;
79 var pi:PointInterpolator;
80 var ri:RectangleInterpolator;
81 var mi:MatrixInterpolator;
82 var ai:ArrayInterpolator;
83 var ci:ColorInterpolator;
84 var oi:ObjectInterpolator;
86 // build the value->interpolator lookup table
87 var lut:Object = new Object();
88 lut["Number"] = "flare.animate.interpolate::NumberInterpolator";
89 lut["int"] = "flare.animate.interpolate::NumberInterpolator";
90 lut["Date"] = "flare.animate.interpolate::DateInterpolator";
91 lut["Array"] = "flare.animate.interpolate::ArrayInterpolator";
92 lut["flash.geom::Point"] = "flare.animate.interpolate::PointInterpolator";
93 lut["flash.geom::Rectangle"] = "flare.animate.interpolate::RectangleInterpolator";
94 lut["flash.geom::Matrix"] = "flare.animate.interpolate::MatrixInterpolator";
98 private static function buildRules() : Array
100 var rules:Array = new Array();
106 private static function isColor(target:Object, property:String, s:Object, e:Object)
109 return property.indexOf("Color")>=0 || property.indexOf("color")>=0
110 ? "flare.animate.interpolate::ColorInterpolator"
114 private static function isShape(target:Object, property:String, s:Object, e:Object)
117 return property == "shape"
118 ? "flare.animate.interpolate::ObjectInterpolator"
123 * Extends the interpolator factory with a new interpolator type.
124 * @param valueType the fully qualified class name for the object type
126 * @param interpType the fully qualified class name for the
127 * interpolator class type
129 public static function addInterpolatorType(valueType:String, interpType:String) : void
131 _lookup[valueType] = interpType;
135 * Clears the lookup table of interpolator types, removing all
136 * type to interpolator mappings.
138 public static function clearInterpolatorTypes():void
140 _lookup = new Object();
144 * Adds a rule to the interpolator factory. The input function should
145 * take a target object, property name string, and target value as
146 * arguments and either return a fully qualified class name for the
147 * type of interpolator to use, or null if this rule does not apply.
148 * @param f the rule function for supplying custom interpolator types
149 * based on contextual conditions
151 public static function addInterpolatorRule(f:Function):void
157 * Clears all interpolator rule functions from the interpolator
160 public static function clearInterpolatorRules():void
162 _rules = new Array();
166 * Returns a new interpolator instance for the given target object,
167 * property name, and interpolation target value. This factory method
168 * follows these steps to provide an interpolator instance:
170 * <li>The list of installed interpolator rules is consulted, and if a
171 * rule returns a non-null class name string, an interpolator of
172 * that type will be returned.</li>
173 * <li>If all rules return null values, then the class type of the
174 * interpolation value is used to look up the appropriate
175 * interpolator type for that value. If a matching interpolator
176 * type is found, an interpolator is initialized and returned.
178 * <li>If no matching type is found, a default ObjectInterpolator
179 * instance is initialized and returned.</li>
182 * <p>By default, the interpolator factory contains two rules. The
183 * first rule returns the class name of ColorInterpolator for any
184 * property names containing the string "color" or "Color". The second
185 * rule returns the class name of ObjectInterpolator for the property
188 * <p>The default value type to interpolator type mappings are:
190 * <li><code>Number -> NumberInterpolator</code></li>
191 * <li><code>int -> NumberInterpolator</code></li>
192 * <li><code>Date -> DateInterpolator</code></li>
193 * <li><code>Array -> ArrayInterpolator</code></li>
194 * <li><code>flash.geom.Point -> PointInterpolator</code></li>
195 * <li><code>flash.geom.Rectangle -> RectangleInterpolator</code></li>
199 * <p>The interpolator factory can be extended either by adding new
200 * interpolation rule functions or by adding new mappings from
201 * interpolation value types to custom interpolator classes.</p>
203 public static function create(target:Object, property:String,
204 start:Object, end:Object): Interpolator
206 // first, check the rules list for an interpolator
207 var name:String = null;
208 for (var i:uint=0; name==null && i<_rules.length; ++i) {
209 name = _rules[i](target, property, start, end);
211 // if no matching rule, use the type lookup table
213 name = _lookup[getQualifiedClassName(end)];
215 // if that fails, use ObjectInterpolator as default
217 name = "flare.animate.interpolate::ObjectInterpolator";
220 // now create the interpolator, recycling from the pool if possible
221 var pool:Array = _pools[name] as Array;
222 if (pool == null || pool.length == 0) {
223 // nothing in the pool, create a new instance
224 var Ref:Class = getDefinitionByName(name) as Class;
225 return new Ref(target, property, start, end) as Interpolator;
227 // reuse an interpolator from the object pool
228 var interp:Interpolator = pool.pop() as Interpolator;
229 interp.reset(target, property, start, end);
235 * Reclaims an interpolator for later recycling. The reclaimed
236 * interpolator should not be in active use by any other classes.
237 * @param interp the Interpolator to reclaim
239 public static function reclaim(interp:Interpolator):void
241 var type:String = getQualifiedClassName(interp);
242 var pool:Array = _pools[type] as Array;
244 _pools[type] = [interp];
245 } else if (pool.length < _maxPoolSize) {
250 } // end of class Interpolator