1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2009 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11 12package mx.charts.chartClasses 13{ 14 15import flash.text.TextFormat; 16 17import mx.core.ClassFactory; 18import mx.core.ContextualClassFactory; 19import mx.core.IFactory; 20import mx.core.IFlexModuleFactory; 21import mx.core.IUITextField; 22 23/** 24 * InstanceCache is a utility that governs the task of creating and managing 25 * a set of <i>n</i> object instances, where <i>n</i> changes frequently. 26 * 27 * @langversion 3.0 28 * @playerversion Flash 9 29 * @playerversion AIR 1.1 30 * @productversion Flex 3 31 */ 32public class InstanceCache 33{ 34 include "../../core/Version.as"; 35 36 //-------------------------------------------------------------------------- 37 // 38 // Constructor 39 // 40 //-------------------------------------------------------------------------- 41 42 /** 43 * Constructor. 44 * 45 * @param type The type of object to construct. 46 * This can be either a Class or an IFactory. 47 * 48 * @param parent An optional DisplayObject to add new instances to. 49 * 50 * @param insertPosition Where in the parent's child list 51 * to insert instances. Set to -1 to add the children to the end of the child list. 52 * 53 * @param moduleFactory The context for using embedded fonts and for 54 * finding the style manager that controls the styles for this component. 55 * 56 * @langversion 3.0 57 * @playerversion Flash 9 58 * @playerversion AIR 1.1 59 * @productversion Flex 3 60 */ 61 public function InstanceCache(type:Object, parent:Object = null, 62 insertPosition:int = -1, moduleFactory:IFlexModuleFactory = null) 63 { 64 super(); 65 66 _parent = parent; 67 68 if (type is IFactory) 69 { 70 _factory = IFactory(type); 71 } 72 else if (type is Class) 73 { 74 _class = Class(type); 75 _factory = new ContextualClassFactory(Class(type), moduleFactory); 76 } 77 78 _insertPosition = insertPosition; 79 } 80 81 //-------------------------------------------------------------------------- 82 // 83 // Variables 84 // 85 //-------------------------------------------------------------------------- 86 87 /** 88 * @private 89 */ 90 private var _parent:Object; 91 92 /** 93 * @private 94 */ 95 private var _class:Class = null; 96 97 /** 98 * @private 99 */ 100 private var _insertPosition:int; 101 102 /** 103 * @private 104 */ 105 private var _count:int = 0; 106 107 //-------------------------------------------------------------------------- 108 // 109 // Properties 110 // 111 //-------------------------------------------------------------------------- 112 113 //---------------------------------- 114 // count 115 //---------------------------------- 116 117 [Inspectable(environment="none")] 118 119 /** 120 * The number of items currently required in the cache. 121 * 122 * @langversion 3.0 123 * @playerversion Flash 9 124 * @playerversion AIR 1.1 125 * @productversion Flex 3 126 */ 127 public function get count():int 128 { 129 return _count; 130 } 131 132 /** 133 * @private 134 */ 135 public function set count(value:int):void 136 { 137 if (value == _count) 138 return; 139 140 var newInstanceCount:int = value; 141 var oldInstanceCount:int = _count; 142 var availableInstanceCount:int = _instances.length; 143 var insertBase:int; 144 if (_parent != null) 145 { 146 insertBase = Math.min(_insertPosition, 147 _parent.numChildren - availableInstanceCount); 148 } 149 150 if (newInstanceCount> oldInstanceCount) 151 { 152 if (!_factory) 153 { 154 value = 0; 155 } 156 else 157 { 158 for (var i:int = oldInstanceCount; 159 i < newInstanceCount && i < availableInstanceCount; 160 i++) 161 { 162 if (hide) 163 _instances[i].visible = true; 164 165 if (_parent && remove) 166 { 167 if (insertBase >= 0) 168 _parent.addChildAt(_instances[i],insertBase + i); 169 else 170 _parent.addChild(_instances[i]); 171 } 172 } 173 174 for (; i < newInstanceCount; i++) 175 { 176 var newInst:Object = _factory.newInstance(); 177 178 if (_parent) 179 { 180 if (insertBase > 0) 181 _parent.addChildAt(newInst, insertBase + i); 182 else 183 _parent.addChild(newInst); 184 } 185 186 if (creationCallback != null) 187 creationCallback(newInst,this); 188 189 _instances.push(newInst); 190 } 191 192 applyProperties(availableInstanceCount, newInstanceCount); 193 194 if (_format) 195 applyFormat(availableInstanceCount, newInstanceCount); 196 } 197 } 198 199 else if (newInstanceCount < oldInstanceCount) 200 { 201 if (remove) 202 { 203 for (i = newInstanceCount; i < oldInstanceCount; i++) 204 { 205 _parent.removeChild(_instances[i]); 206 } 207 } 208 209 if (hide) 210 { 211 for (i = newInstanceCount; i < oldInstanceCount; i++) 212 { 213 _instances[i].visible = false; 214 } 215 } 216 217 if (discard) 218 _instances = _instances.slice(0, newInstanceCount); 219 } 220 221 _count = value; 222 } 223 224 //---------------------------------- 225 // creationCallback 226 //---------------------------------- 227 228 [Inspectable(environment="none")] 229 230 /** 231 * A callback invoked when new instances are created. 232 * This callback has the following signature: 233 * <pre> 234 * function creationCallback(<i>newInstance</i>:Object, <i>cache</i>:InstanceCache):void; 235 * </pre> 236 * 237 * @langversion 3.0 238 * @playerversion Flash 9 239 * @playerversion AIR 1.1 240 * @productversion Flex 3 241 */ 242 public var creationCallback:Function; 243 244 //---------------------------------- 245 // discard 246 //---------------------------------- 247 248 [Inspectable(environment="none")] 249 250 /** 251 * Determines if unneeded instances are discarded. 252 * If set to <code>true</code>, extra elements are discarded 253 * when the cache count is reduced. 254 * Otherwise, extra elements are kept in a separate cache 255 * and reused when the count is increased. 256 * 257 * @langversion 3.0 258 * @playerversion Flash 9 259 * @playerversion AIR 1.1 260 * @productversion Flex 3 261 */ 262 public var discard:Boolean = false; 263 264 //---------------------------------- 265 // factory 266 //---------------------------------- 267 268 /** 269 * @private 270 */ 271 private var _factory:IFactory; 272 273 [Inspectable(environment="none")] 274 275 /** 276 * A factory that generates the type of object to cache. 277 * Assigning to this discards all current instances 278 * and recreate new instances of the correct type. 279 * 280 * @langversion 3.0 281 * @playerversion Flash 9 282 * @playerversion AIR 1.1 283 * @productversion Flex 3 284 */ 285 public function get factory():IFactory 286 { 287 return _factory; 288 } 289 290 /** 291 * @private 292 */ 293 public function set factory(value:IFactory):void 294 { 295 if (value == _factory || 296 ((value is ClassFactory) && 297 (_factory is ClassFactory) && 298 (ClassFactory(_factory).generator == ClassFactory(value).generator) && 299 (!(value is ContextualClassFactory)))) 300 return; 301 302 _factory = value; 303 _class = null; 304 305 var instanceCount:Number = _count; 306 count = 0; 307 count = instanceCount; 308 } 309 310 //---------------------------------- 311 // format 312 //---------------------------------- 313 314 /** 315 * @private 316 */ 317 private var _format:TextFormat; 318 319 [Inspectable(environment="none")] 320 321 /** 322 * A TextFormat to apply to any instances created. 323 * If set, this format is applied as the current and default format 324 * for the contents of any instances created. 325 * This property is only relevant if the factory 326 * generates TextField instances. 327 * 328 * @langversion 3.0 329 * @playerversion Flash 9 330 * @playerversion AIR 1.1 331 * @productversion Flex 3 332 */ 333 public function get format():TextFormat 334 { 335 return _format; 336 } 337 338 /** 339 * @private 340 */ 341 public function set format(value:TextFormat):void 342 { 343 _format = value; 344 345 if (_format) 346 applyFormat(0, _instances.length); 347 } 348 349 //---------------------------------- 350 // hide 351 //---------------------------------- 352 353 [Inspectable(environment="none")] 354 355 /** 356 * Determines if unneeded instances should be hidden. 357 * If <code>true</code>, the <code>visible</code> property 358 * is set to <code>false</code> on each extra element 359 * when the cache count is reduced, and set to <code>true</code> 360 * when the count is increased. 361 * 362 * <p>This property is only relevant when the factory 363 * generates DisplayObjects. 364 * Setting this property to <code>true</code> for other factory types 365 * generates a run-time error.</p> 366 * 367 * @langversion 3.0 368 * @playerversion Flash 9 369 * @playerversion AIR 1.1 370 * @productversion Flex 3 371 */ 372 public var hide:Boolean = true; 373 374 //---------------------------------- 375 // insertPosition 376 //---------------------------------- 377 378 [Inspectable(environment="none")] 379 380 /** 381 * The position of the instance in the parent's child list. 382 * 383 * @langversion 3.0 384 * @playerversion Flash 9 385 * @playerversion AIR 1.1 386 * @productversion Flex 3 387 */ 388 public function set insertPosition(value:int):void 389 { 390 if (value != _insertPosition) 391 { 392 _insertPosition = value; 393 394 if (_parent) 395 { 396 var n:int = _instances.length; 397 for (var i:int = 0; i < n; i++) 398 { 399 _parent.setChildIndex(_instances[i], i + _insertPosition); 400 } 401 } 402 } 403 } 404 405 //---------------------------------- 406 // instances 407 //---------------------------------- 408 409 /** 410 * @private 411 */ 412 private var _instances:Array /* of Object */= []; 413 414 [Inspectable(environment="none")] 415 416 /** 417 * The Array of cached instances. 418 * There may be more instances in this Array than currently requested. 419 * You should rely on the <code>count</code> property 420 * of the instance cache rather than the length of this Array. 421 * 422 * @langversion 3.0 423 * @playerversion Flash 9 424 * @playerversion AIR 1.1 425 * @productversion Flex 3 426 */ 427 public function get instances():Array /* of Object */ 428 { 429 return _instances; 430 } 431 432 //---------------------------------- 433 // properties 434 //---------------------------------- 435 436 /** 437 * @private 438 */ 439 private var _properties:Object = {}; 440 441 [Inspectable(environment="none")] 442 443 /** 444 * A hashmap of properties to assign to new instances. 445 * Each key/value pair in this hashmap is assigned 446 * to each new instance created. 447 * The property hashmap is assigned to any existing instances when set. 448 * 449 * <p>The values in the hashmap are not cloned; 450 * object values are shared by all instances.</p> 451 * 452 * @langversion 3.0 453 * @playerversion Flash 9 454 * @playerversion AIR 1.1 455 * @productversion Flex 3 456 */ 457 public function get properties():Object 458 { 459 return _properties; 460 } 461 462 /** 463 * @private 464 */ 465 public function set properties(value:Object):void 466 { 467 _properties = value; 468 469 applyProperties(0, _instances.length); 470 } 471 472 //---------------------------------- 473 // remove 474 //---------------------------------- 475 476 [Inspectable(environment="none")] 477 478 /** 479 * Determines if unneeded instances should be removed from their parent. 480 * If <code>true</code>, the <code>removeChild()</code> method 481 * is called on the parent for each extra element 482 * when the cache count is reduced. 483 * 484 * <p>This property is only relevant when the factory 485 * generates DisplayObjects. 486 * Setting this property to <code>true</code> for other factory types 487 * generates a run-time error.</p> 488 * 489 * @langversion 3.0 490 * @playerversion Flash 9 491 * @playerversion AIR 1.1 492 * @productversion Flex 3 493 */ 494 public var remove:Boolean = false; 495 496 //-------------------------------------------------------------------------- 497 // 498 // Methods 499 // 500 //-------------------------------------------------------------------------- 501 502 /** 503 * @private 504 */ 505 private function applyProperties(start:int, end:int):void 506 { 507 for (var i:int = start; i < end; i++) 508 { 509 var newInst:Object = _instances[i]; 510 511 for (var p:String in _properties) 512 { 513 newInst[p] = _properties[p]; 514 } 515 } 516 } 517 518 /** 519 * @private 520 */ 521 private function applyFormat(start:int, end:int):void 522 { 523 for (var i:int = start; i < end; i++) 524 { 525 var newField:IUITextField = _instances[i]; 526 newField.setTextFormat(_format); 527 newField.defaultTextFormat = _format; 528 529 } 530 } 531} 532 533}