All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.feathers.core.ValidationQueue.as Maven / Gradle / Ivy

/*
Feathers
Copyright 2012-2015 Bowler Hat LLC. All Rights Reserved.

This program is free software. You can redistribute and/or modify it in
accordance with the terms of the accompanying license agreement.
*/
package feathers.core
{
	import flash.utils.Dictionary;

	import starling.animation.IAnimatable;
	import starling.core.Starling;

	[ExcludeClass]
	public final class ValidationQueue implements IAnimatable
	{
		/**
		 * @private
		 */
		private static const STARLING_TO_VALIDATION_QUEUE:Dictionary = new Dictionary(true);

		/**
		 * Gets the validation queue for the specified Starling instance. If
		 * a validation queue does not exist for the specified Starling
		 * instance, a new one will be created.
		 */
		public static function forStarling(starling:Starling):ValidationQueue
		{
			if(!starling)
			{
				return null;
			}
			var queue:ValidationQueue = STARLING_TO_VALIDATION_QUEUE[starling];
			if(!queue)
			{
				STARLING_TO_VALIDATION_QUEUE[starling] = queue = new ValidationQueue(starling);
			}
			return queue;
		}

		/**
		 * Constructor.
		 */
		public function ValidationQueue(starling:Starling)
		{
			this._starling = starling;
		}

		private var _starling:Starling;

		private var _isValidating:Boolean = false;

		/**
		 * If true, the queue is currently validating.
		 *
		 * 

In the following example, we check if the queue is currently validating:

* * * if( queue.isValidating ) * { * // do something * } */ public function get isValidating():Boolean { return this._isValidating; } private var _delayedQueue:Vector. = new []; private var _queue:Vector. = new []; /** * Disposes the validation queue. */ public function dispose():void { if(this._starling) { this._starling.juggler.remove(this); this._starling = null; } } /** * Adds a validating component to the queue. */ public function addControl(control:IValidating, delayIfValidating:Boolean):void { //if the juggler was purged, we need to add the queue back in. if(!this._starling.juggler.contains(this)) { this._starling.juggler.add(this); } var currentQueue:Vector. = (this._isValidating && delayIfValidating) ? this._delayedQueue : this._queue; if(currentQueue.indexOf(control) >= 0) { //already queued return; } var queueLength:int = currentQueue.length; if(this._isValidating && currentQueue == this._queue) { //special case: we need to keep it sorted var depth:int = control.depth; //we're traversing the queue backwards because it's //significantly more likely that we're going to push than that //we're going to splice, so there's no point to iterating over //the whole queue for(var i:int = queueLength - 1; i >= 0; i--) { var otherControl:IValidating = IValidating(currentQueue[i]); var otherDepth:int = otherControl.depth; //we can skip the overhead of calling queueSortFunction and //of looking up the value we've already stored in the depth //local variable. if(depth >= otherDepth) { break; } } //add one because we're going after the last item we checked //if we made it through all of them, i will be -1, and we want 0 i++; currentQueue.insertAt(i, control); } else { //faster than push() because push() creates a temporary rest //Array that needs to be garbage collected currentQueue[queueLength] = control; } } /** * @private */ public function advanceTime(time:Number):void { if(this._isValidating || !this._starling.contextValid) { return; } var queueLength:int = this._queue.length; if(queueLength == 0) { return; } this._isValidating = true; this._queue = this._queue.sort(queueSortFunction); while(this._queue.length > 0) //rechecking length after the shift { var item:IValidating = this._queue.shift(); if(item.depth < 0) { //skip items that are no longer on the display list continue; } item.validate(); } var temp:Vector. = this._queue; this._queue = this._delayedQueue; this._delayedQueue = temp; this._isValidating = false; } /** * @private */ protected function queueSortFunction(first:IValidating, second:IValidating):int { var difference:int = second.depth - first.depth; if(difference > 0) { return -1; } else if(difference < 0) { return 1; } return 0; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy