package aerys.minko.scene
{
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.binding.DataBindings;

	import flash.utils.Dictionary;
	import flash.utils.Proxy;
	import flash.utils.describeType;
	import flash.utils.flash_proxy;
	import flash.utils.getQualifiedClassName;

	public dynamic class SceneIterator extends Proxy
	{
		private static const TYPE_CACHE	: Dictionary		= new Dictionary(true);
		private static const OPERATORS	: Vector.<String>	= new <String>[
			'//', '/', '[', ']', '..', '.', '~=', '?=', '=', '@', '*', '(', ')',
			'>=', '>', '<=', '<', '==', '='
		];
		private static const REGEX_TRIM	: RegExp			= /^\s+|\s+$/;

		private var _path		: String				= null;
		private var _selection	: Vector.<ISceneNode>	= null;
		private var _modifier	: String				= null;

		public function get length() : uint
		{
			return _selection.length;
		}

		public function SceneIterator(path 		: String,
									  selection : Vector.<ISceneNode>,
									  modifier	: String	= "")
		{
			super();

			_modifier = modifier;

			initialize(path, selection);
		}

		public function toString() : String
		{
			return _selection.toString();
		}

//		override flash_proxy function setProperty(name : *, value : *):void
//		{
//			var propertyName : String = name;
//
//			for each (var node : ISceneNode in _selection)
//				getValueObject(node, _modifier)[propertyName] = value;
//		}

		override flash_proxy function getProperty(name : *) : *
		{
			var index : int = parseInt(name);

			if (index == name)
				return index < _selection.length ? _selection[index] : null;
			else
			{
				throw new Error(
					'Unable to get a property on a set of objects. '
					+ 'You must use the [] operator to fetch one of the objects.'
				);
			}
		}

		override flash_proxy function nextNameIndex(index : int) : int
		{
			return index < _selection.length ? index + 1 : 0;
		}

		override flash_proxy function nextName(index : int) : String
		{
			return String(index - 1);
		}

		override flash_proxy function nextValue(index : int) : *
		{
			return _selection[int(index - 1)];
		}

//		override flash_proxy function callProperty(name:*, ...parameters):*
//		{
//			var methodName : String = name;
//
//			for each (var node : ISceneNode in _selection)
//			{
//				var method : Function = getValueObject(node, _modifier)[methodName];
//
//				method.apply(null, parameters);
//			}
//
//			return this;
//		}

		private function initialize(path : String, selection : Vector.<ISceneNode>) : void
		{
			_path = path;

			// update root
			var token : String = getToken();

			_selection = selection.slice();
			if (token == "/")
			{
				selectRoots();
				nextToken(token);
			}

			// parse
			while (token = getToken())
			{
				switch (token)
				{
					case '//' :
						nextToken(token);
						selectDescendants();
						break ;
					case '/' :
						nextToken(token);
						selectChildren();
						break ;
					default :
						nextToken(token);
						parseNodeType(token);
						break ;
				}
			}
		}

		private function getToken(doNext : Boolean = false) : String
		{
			var token	: String	= null;

			if (!_path)
				return null;

			_path = _path.replace(/^\s+/, '');

			var nextOpIndex : int = int.MAX_VALUE;

			for each (var op : String in OPERATORS)
			{
				var opIndex : int = _path.indexOf(op);

				if (opIndex > 0 && opIndex < nextOpIndex)
					nextOpIndex = opIndex;

				if (opIndex == 0)
				{
					token = op;
					break ;
				}
			}

			if (!token)
				token = _path.substring(0, nextOpIndex);

			if (doNext)
				nextToken(token);

			return token;
		}

		private function getValueToken() : Object
		{
			var value : Object	= null;

			_path = _path.replace(/^\s+/, '');

			if (_path.charAt(0) == "'")
			{
				var endOfStringIndex : int = _path.indexOf("'", 1);

				if (endOfStringIndex < 0)
					throw new Error("Unterminated string expression.");

				var stringValue	: String	=  _path.substring(1, endOfStringIndex);

				_path = _path.substring(endOfStringIndex + 1);

				value = stringValue;
			}
			else
			{
				var token : String	= getToken(true);

				if (token == 'true')
					value = true;
				else if (token == 'false')
					value = false;
				else if (token.indexOf('0x') == 0)
					value = parseInt(token, 16);
			}

			return value;
		}

		private function nextToken(token : String) : void
		{
			_path = _path.substring(_path.indexOf(token) + token.length);
		}

		private function selectChildren(typeName : String = null) : void
		{
			var selection : Vector.<ISceneNode> = _selection.slice();

			if (typeName != null)
				typeName = typeName.toLowerCase();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
			{
				if (node is Group)
				{
					var group 		: Group = node as Group;
					var numChildren : uint 	= group.numChildren;

					for (var i : uint = 0; i < numChildren; ++i)
					{
						var child 		: ISceneNode 	= group.getChildAt(i);
						var className	: String		= getQualifiedClassName(child)
						var childType 	: String 		= className.substr(className.lastIndexOf(':') + 1);

						if (typeName == null || childType.toLowerCase() == typeName)
							_selection.push(child);
					}
				}
			}
		}

		private function selectRoots() : void
		{
			var selection	: Vector.<ISceneNode>	= _selection.slice();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
				if (_selection.indexOf(node.root) < 0)
					_selection.push(node);
		}

		private function selectDescendants() : void
		{
			var selection : Vector.<ISceneNode> = _selection.slice();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
			{
				_selection.push(node);
				if (node is Group)
					(node as Group).getDescendantsByType(ISceneNode, _selection);
			}
		}

		private function selectParents() : void
		{
			var selection : Vector.<ISceneNode> = _selection.slice();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
			{
				if (node.parent)
					_selection.push(node.parent);
				else
					_selection.push(node);
			}
		}

		private function parseNodeType(nodeType : String) : void
		{
			if (nodeType == '.')
			{
				// nothing
			}
			if (nodeType == '..')
				selectParents();
			else if (nodeType == '*')
				selectChildren();
			else
				selectChildren(nodeType);

			// apply predicates
			var token : String = getToken();

			while (token == '[')
			{
				nextToken(token);
				parsePredicate();

				token = getToken();
			}
		}

		private function parsePredicate() : void
		{
			var propertyName	: String	= getToken(true);
			var isBinding		: Boolean	= propertyName == '@';

			if (isBinding)
				propertyName = getToken(true);

			var index	: int	= parseInt(propertyName);

			if (propertyName == 'hasController')
				filterOnController();
			if (propertyName == 'hasProperty')
				filterOnProperty();
			else if (propertyName == 'position')
				filterOnPosition();
			else if (propertyName == 'last')
				filterLast();
			else if (propertyName == 'first')
				filterFirst();
			else if (index.toString() == propertyName)
			{
				if (index < _selection.length)
				{
					_selection[0] = _selection[index];
					_selection.length = 1;
				}
				else
					_selection.length = 0;
			}
			else
				filterOnValue(propertyName, isBinding);

			checkNextToken(']');
		}

		private function filterLast() : void
		{
			checkNextToken('(');
			checkNextToken(')');

			_selection[0] = _selection[uint(_selection.length - 1)];
			_selection.length = 1;
		}

		private function filterFirst() : void
		{
			checkNextToken('(');
			checkNextToken(')');

			_selection.length = 1;
		}

		private function filterOnValue(propertyName : String, isBinding : Boolean = false) : void
		{
			var operator	: String	= getToken(true);
			var chunks		: Array		= [propertyName];

			while (operator == '.')
			{
				chunks.push(getToken(true));
				operator = getToken(true);
			}

			var value		: Object	= getValueToken();
			var numNodes	: uint		= _selection.length;

			for (var i : int = numNodes - 1; i >= 0; --i)
			{
				var node		: ISceneNode	= _selection[i];
				var nodeValue 	: Object 		= null;

				if (isBinding && (node['bindings'] is DataBindings))
					nodeValue = (node['bindings'] as DataBindings).getProperty(propertyName);
				else
				{
					try
					{
						nodeValue = getValueObject(node, chunks);
						if (!compare(operator, nodeValue, value))
							removeFromSelection(i);
					}
					catch (e : Error)
					{
						removeFromSelection(i);
					}
				}

			}
		}

		private function compare(operator : String, a : Object, b : Object) : Boolean
		{
			switch (operator)
			{
				case '>' :
					return a > b;
				case '>=' :
					return a >= b;
				case '<' :
					return a >= b;
				case '<=' :
					return a <= b;
				case '=' :
				case '==' :
					return a == b;
				case '~=' :
					var matches	: Array	= String(a).match(b);

					return matches && matches.length != 0;
				default:
					throw new Error('Unknown comparison operator \'' + operator + '\'');
			}
		}

		private function filterOnController() : Object
		{
			checkNextToken('(');
			var controllerName : String = getToken(true);
			checkNextToken(')');

			var numNodes	: uint	= _selection.length;

			for (var i : int = numNodes - 1; i >= 0; --i)
			{
				var node			: ISceneNode	= _selection[i];
				var numControllers	: uint			= node.numControllers;
				var keepSceneNode	: Boolean		= false;

				for (var controllerId : uint = 0; controllerId < numControllers; ++controllerId)
				{
					var controllerType : String = getQualifiedClassName(node.getController(controllerId));
					controllerType = controllerType.substr(controllerType.lastIndexOf(':') + 1);

					if (controllerType == controllerName)
					{
						keepSceneNode = true;
						break;
					}
				}

				if (!keepSceneNode)
					removeFromSelection(i);
			}

			return null;
		}

		private function filterOnPosition() : void
		{
			checkNextToken('(');
			checkNextToken(')');

			var operator 	: String 	= getToken(true);
			var value 		: uint 		= uint(parseInt(getToken(true)));

			switch (operator)
			{
				case '>':
					++value;
				case '>=':
					_selection = _selection.slice(value);
					break;
				case '<':
					--value;
				case '<=':
					_selection = _selection.slice(0, value);
					break;
				case '=':
				case '==':
					_selection[0] = _selection[value];
					_selection.length = 1;
				default:
					throw new Error('Unknown comparison operator \'' + operator + '\'');
			}
		}

		private function filterOnProperty() : void
		{
			checkNextToken('(');

			var chunks		: Array 	= [getToken(true)];
			var operator	: String 	= getToken(true);

			while (operator == '.')
			{
				chunks.push(operator);
				operator = getToken(true);
			}

			if (operator != ')')
				throwParseError(')', operator);

			var numNodes : uint	= _selection.length;
			for (var i : int = numNodes - 1; i >= 0; --i)
			{
				try
				{
					getValueObject(_selection[i], chunks);
				}
				catch (e : Error)
				{
					removeFromSelection(i);
				}
			}
		}

		private function getValueObject(source : Object, chunks : Array) : Object
		{
			if (chunks)
				for each (var chunk : String in chunks)
					source = source[chunk];

			return source;
		}

		private function removeFromSelection(index : uint) : void
		{
			var numNodes : uint = _selection.length - 1;

			_selection[index] = _selection[numNodes];
			_selection.length = numNodes;
		}

		private function checkNextToken(expected : String) : void
		{
			var token : String = getToken(true);

			if (token != expected)
				throwParseError(expected, token);
		}

		private function throwParseError(expected	: String,
										 got		: String) : void
		{
			throw new Error(
				'Parse error: expected \'' + expected + '\', got \'' + got + '\'.'
			);
		}
	}
}

package aerys.minko.scene
{
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.binding.DataBindings;

	import flash.utils.Dictionary;
	import flash.utils.Proxy;
	import flash.utils.describeType;
	import flash.utils.flash_proxy;
	import flash.utils.getQualifiedClassName;

	public dynamic class SceneIterator extends Proxy
	{
		private static const TYPE_CACHE	: Dictionary		= new Dictionary(true);
		private static const OPERATORS	: Vector.<String>	= new <String>[
			'//', '/', '[', ']', '..', '.', '~=', '?=', '=', '@', '*', '(', ')',
			'>=', '>', '<=', '<', '==', '='
		];
		private static const REGEX_TRIM	: RegExp			= /^\s+|\s+$/;

		private var _path		: String				= null;
		private var _selection	: Vector.<ISceneNode>	= null;
		private var _modifier	: String				= null;

		public function get length() : uint
		{
			return _selection.length;
		}

		public function SceneIterator(path 		: String,
									  selection : Vector.<ISceneNode>,
									  modifier	: String	= "")
		{
			super();

			_modifier = modifier;

			initialize(path, selection);
		}

		public function toString() : String
		{
			return _selection.toString();
		}

//		override flash_proxy function setProperty(name : *, value : *):void
//		{
//			var propertyName : String = name;
//
//			for each (var node : ISceneNode in _selection)
//				getValueObject(node, _modifier)[propertyName] = value;
//		}

		override flash_proxy function getProperty(name : *) : *
		{
			var index : int = parseInt(name);

			if (index == name)
				return index < _selection.length ? _selection[index] : null;
			else
			{
				throw new Error(
					'Unable to get a property on a set of objects. '
					+ 'You must use the [] operator to fetch one of the objects.'
				);
			}
		}

		override flash_proxy function nextNameIndex(index : int) : int
		{
			return index < _selection.length ? index + 1 : 0;
		}

		override flash_proxy function nextName(index : int) : String
		{
			return String(index - 1);
		}

		override flash_proxy function nextValue(index : int) : *
		{
			return _selection[int(index - 1)];
		}

//		override flash_proxy function callProperty(name:*, ...parameters):*
//		{
//			var methodName : String = name;
//
//			for each (var node : ISceneNode in _selection)
//			{
//				var method : Function = getValueObject(node, _modifier)[methodName];
//
//				method.apply(null, parameters);
//			}
//
//			return this;
//		}

		private function initialize(path : String, selection : Vector.<ISceneNode>) : void
		{
			_path = path;

			// update root
			var token : String = getToken();

			_selection = selection.slice();
			if (token == "/")
			{
				selectRoots();
				nextToken(token);
			}

			// parse
			while ((token = getToken()) != null)
			{
				switch (token)
				{
					case '//' :
						nextToken(token);
						selectDescendants();
						break ;
					case '/' :
						nextToken(token);
						selectChildren();
						break ;
					default :
						nextToken(token);
						parseNodeType(token);
						break ;
				}
			}
		}

		private function getToken(doNext : Boolean = false) : String
		{
			var token	: String	= null;

			if (!_path)
				return null;

			_path = _path.replace(/^\s+/, '');

			var nextOpIndex : int = int.MAX_VALUE;

			for each (var op : String in OPERATORS)
			{
				var opIndex : int = _path.indexOf(op);

				if (opIndex > 0 && opIndex < nextOpIndex)
					nextOpIndex = opIndex;

				if (opIndex == 0)
				{
					token = op;
					break ;
				}
			}

			if (!token)
				token = _path.substring(0, nextOpIndex);

			if (doNext)
				nextToken(token);

			return token;
		}

		private function getValueToken() : Object
		{
			var value : Object	= null;

			_path = _path.replace(/^\s+/, '');

			if (_path.charAt(0) == "'")
			{
				var endOfStringIndex : int = _path.indexOf("'", 1);

				if (endOfStringIndex < 0)
					throw new Error("Unterminated string expression.");

				var stringValue	: String	=  _path.substring(1, endOfStringIndex);

				_path = _path.substring(endOfStringIndex + 1);

				value = stringValue;
			}
			else
			{
				var token : String	= getToken(true);

				if (token == 'true')
					value = true;
				else if (token == 'false')
					value = false;
				else if (token.indexOf('0x') == 0)
					value = parseInt(token, 16);
			}

			return value;
		}

		private function nextToken(token : String) : void
		{
			_path = _path.substring(_path.indexOf(token) + token.length);
		}

		private function selectChildren(typeName : String = null) : void
		{
			var selection : Vector.<ISceneNode> = _selection.slice();

			if (typeName != null)
				typeName = typeName.toLowerCase();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
			{
				if (node is Group)
				{
					var group 		: Group = node as Group;
					var numChildren : uint 	= group.numChildren;

					for (var i : uint = 0; i < numChildren; ++i)
					{
						var child 		: ISceneNode 	= group.getChildAt(i);
						var className	: String		= getQualifiedClassName(child)
						var childType 	: String 		= className.substr(className.lastIndexOf(':') + 1);

						if (typeName == null || childType.toLowerCase() == typeName)
							_selection.push(child);
					}
				}
			}
		}

		private function selectRoots() : void
		{
			var selection	: Vector.<ISceneNode>	= _selection.slice();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
				if (_selection.indexOf(node.root) < 0)
					_selection.push(node);
		}

		private function selectDescendants() : void
		{
			var selection : Vector.<ISceneNode> = _selection.slice();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
			{
				_selection.push(node);
				if (node is Group)
					(node as Group).getDescendantsByType(ISceneNode, _selection);
			}
		}

		private function selectParents() : void
		{
			var selection : Vector.<ISceneNode> = _selection.slice();

			_selection.length = 0;
			for each (var node : ISceneNode in selection)
			{
				if (node.parent)
					_selection.push(node.parent);
				else
					_selection.push(node);
			}
		}

		private function parseNodeType(nodeType : String) : void
		{
			if (nodeType == '.')
			{
				// nothing
			}
			if (nodeType == '..')
				selectParents();
			else if (nodeType == '*')
				selectChildren();
			else
				selectChildren(nodeType);

			// apply predicates
			var token : String = getToken();

			while (token == '[')
			{
				nextToken(token);
				parsePredicate();

				token = getToken();
			}
		}

		private function parsePredicate() : void
		{
			var propertyName	: String	= getToken(true);
			var isBinding		: Boolean	= propertyName == '@';

			if (isBinding)
				propertyName = getToken(true);

			var index	: int	= parseInt(propertyName);

			if (propertyName == 'hasController')
				filterOnController();
			if (propertyName == 'hasProperty')
				filterOnProperty();
			else if (propertyName == 'position')
				filterOnPosition();
			else if (propertyName == 'last')
				filterLast();
			else if (propertyName == 'first')
				filterFirst();
			else if (index.toString() == propertyName)
			{
				if (index < _selection.length)
				{
					_selection[0] = _selection[index];
					_selection.length = 1;
				}
				else
					_selection.length = 0;
			}
			else
				filterOnValue(propertyName, isBinding);

			checkNextToken(']');
		}

		private function filterLast() : void
		{
			checkNextToken('(');
			checkNextToken(')');

			_selection[0] = _selection[uint(_selection.length - 1)];
			_selection.length = 1;
		}

		private function filterFirst() : void
		{
			checkNextToken('(');
			checkNextToken(')');

			_selection.length = 1;
		}

		private function filterOnValue(propertyName : String, isBinding : Boolean = false) : void
		{
			var operator	: String	= getToken(true);
			var chunks		: Array		= [propertyName];

			while (operator == '.')
			{
				chunks.push(getToken(true));
				operator = getToken(true);
			}

			var value		: Object	= getValueToken();
			var numNodes	: uint		= _selection.length;

			for (var i : int = numNodes - 1; i >= 0; --i)
			{
				var node		: ISceneNode	= _selection[i];
				var nodeValue 	: Object 		= null;

				if (isBinding && (node['bindings'] is DataBindings))
					nodeValue = (node['bindings'] as DataBindings).getProperty(propertyName);
				else
				{
					try
					{
						nodeValue = getValueObject(node, chunks);
						if (!compare(operator, nodeValue, value))
							removeFromSelection(i);
					}
					catch (e : Error)
					{
						removeFromSelection(i);
					}
				}

			}
		}

		private function compare(operator : String, a : Object, b : Object) : Boolean
		{
			switch (operator)
			{
				case '>' :
					return a > b;
				case '>=' :
					return a >= b;
				case '<' :
					return a >= b;
				case '<=' :
					return a <= b;
				case '=' :
				case '==' :
					return a == b;
				case '~=' :
					var matches	: Array	= String(a).match(b);

					return matches && matches.length != 0;
				default:
					throw new Error('Unknown comparison operator \'' + operator + '\'');
			}
		}

		private function filterOnController() : Object
		{
			checkNextToken('(');
			var controllerName : String = getToken(true);
			checkNextToken(')');

			var numNodes	: uint	= _selection.length;

			for (var i : int = numNodes - 1; i >= 0; --i)
			{
				var node			: ISceneNode	= _selection[i];
				var numControllers	: uint			= node.numControllers;
				var keepSceneNode	: Boolean		= false;

				for (var controllerId : uint = 0; controllerId < numControllers; ++controllerId)
				{
					var controllerType : String = getQualifiedClassName(node.getController(controllerId));
					controllerType = controllerType.substr(controllerType.lastIndexOf(':') + 1);

					if (controllerType == controllerName)
					{
						keepSceneNode = true;
						break;
					}
				}

				if (!keepSceneNode)
					removeFromSelection(i);
			}

			return null;
		}

		private function filterOnPosition() : void
		{
			checkNextToken('(');
			checkNextToken(')');

			var operator 	: String 	= getToken(true);
			var value 		: uint 		= uint(parseInt(getToken(true)));

			switch (operator)
			{
				case '>':
					++value;
				case '>=':
					_selection = _selection.slice(value);
					break;
				case '<':
					--value;
				case '<=':
					_selection = _selection.slice(0, value);
					break;
				case '=':
				case '==':
					_selection[0] = _selection[value];
					_selection.length = 1;
				default:
					throw new Error('Unknown comparison operator \'' + operator + '\'');
			}
		}

		private function filterOnProperty() : void
		{
			checkNextToken('(');

			var chunks		: Array 	= [getToken(true)];
			var operator	: String 	= getToken(true);

			while (operator == '.')
			{
				chunks.push(operator);
				operator = getToken(true);
			}

			if (operator != ')')
				throwParseError(')', operator);

			var numNodes : uint	= _selection.length;
			for (var i : int = numNodes - 1; i >= 0; --i)
			{
				try
				{
					getValueObject(_selection[i], chunks);
				}
				catch (e : Error)
				{
					removeFromSelection(i);
				}
			}
		}

		private function getValueObject(source : Object, chunks : Array) : Object
		{
			if (chunks)
				for each (var chunk : String in chunks)
					source = source[chunk];

			return source;
		}

		private function removeFromSelection(index : uint) : void
		{
			var numNodes : uint = _selection.length - 1;

			_selection[index] = _selection[numNodes];
			_selection.length = numNodes;
		}

		private function checkNextToken(expected : String) : void
		{
			var token : String = getToken(true);

			if (token != expected)
				throwParseError(expected, token);
		}

		private function throwParseError(expected	: String,
										 got		: String) : void
		{
			throw new Error(
				'Parse error: expected \'' + expected + '\', got \'' + got + '\'.'
			);
		}
	}
}

fix ambigous = operator in if boolean expression to comply with ASC 2.0 compiler


package com.threerings.io {

import com.threerings.util.ClassUtil;
import com.threerings.util.Cloneable;

public dynamic class TypedArray extends Array
    implements Cloneable
{
    /**
     * Create a TypedArray
     *
     * @param jtype The java classname of this array, for example "[I" to
     * represent an int[], or "[Ljava.lang.Object;" for Object[].
     */
    public function TypedArray (jtype :String)
    {
        _jtype = jtype;
    }

    /**
     * Convenience method to get the java type of an array containing
     * objects of the specified class.
     */
    public static function getJavaType (of :Class) :String
    {
        if (of === Boolean) {
            return "[Z";

        } else if (of === int) { // Number will be int if something like 3.0
            return "[I";

        } else if (of === Number) {
            return "[D";
        }

        var cname :String = Translations.getToServer(
            ClassUtil.getClassName(of));
        return "[L" + cname + ";";
    }

    /**
     * A factory method to create a TypedArray for holding objects
     * of the specified type.
     */
    public static function create (of :Class) :TypedArray
    {
        return new TypedArray(getJavaType(of));
    }

    public function getJavaType () :String
    {
        return _jtype;
    }

    // from Cloneable
    public function clone () :Object
    {
        var clazz :Class = ClassUtil.getClass(this);
        var copy :TypedArray = new clazz(_jtype);
        for (var ii :int = length - 1; ii >= 0; ii--) {
            copy[ii] = this[ii];
        }
        return copy;
    }

    /** The 'type' of this array, which doesn't really mean anything
     * except gives it a clue as to how to stream to our server. */
    protected var _jtype :String;
}
}

package com.threerings.io {

import flash.utils.ByteArray;

import com.threerings.util.ClassUtil;
import com.threerings.util.Cloneable;

public dynamic class TypedArray extends Array
    implements Cloneable
{
    /**
     * Create a TypedArray
     *
     * @param jtype The java classname of this array, for example "[I" to
     * represent an int[], or "[Ljava.lang.Object;" for Object[].
     */
    public function TypedArray (jtype :String)
    {
        _jtype = jtype;
    }

    /**
     * Convenience method to get the java type of an array containing
     * objects of the specified class.
     */
    public static function getJavaType (of :Class) :String
    {
        if (of === Boolean) {
            return "[Z";

        } else if (of === int) { // Number will be int if something like 3.0
            return "[I";

        } else if (of === Number) {
            return "[D";

        } else if (of === ByteArray) {
            return "[[B";
        }

        var cname :String = Translations.getToServer(
            ClassUtil.getClassName(of));
        return "[L" + cname + ";";
    }

    /**
     * A factory method to create a TypedArray for holding objects
     * of the specified type.
     */
    public static function create (of :Class) :TypedArray
    {
        return new TypedArray(getJavaType(of));
    }

    public function getJavaType () :String
    {
        return _jtype;
    }

    // from Cloneable
    public function clone () :Object
    {
        var clazz :Class = ClassUtil.getClass(this);
        var copy :TypedArray = new clazz(_jtype);
        for (var ii :int = length - 1; ii >= 0; ii--) {
            copy[ii] = this[ii];
        }
        return copy;
    }

    /** The 'type' of this array, which doesn't really mean anything
     * except gives it a clue as to how to stream to our server. */
    protected var _jtype :String;
}
}

Allow creation of an array of arrays of bytes...

git-svn-id: a1a4b28b82a3276cc491891159dd9963a0a72fae@4332 542714f4-19e9-0310-aa3c-eee0fc999fb1


package fm.wavesurfer.audio {
	import fm.wavesurfer.audio.events.LoadProgressEvent;
	import flash.events.ProgressEvent;
	import fm.wavesurfer.audio.events.LoadErrorEvent;
	import flash.events.IOErrorEvent;
	import fm.wavesurfer.audio.events.LoadedEvent;

	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.media.SoundLoaderContext;
	import flash.net.URLRequest;

	/**
	 * @author laurent
	 */
	public class AudioLoader extends EventDispatcher {

		private var sound : Sound;
		private var url : String;

		public function AudioLoader() {
			sound = new Sound();
			sound.addEventListener(Event.COMPLETE, onSoundLoaded);
			sound.addEventListener(IOErrorEvent.IO_ERROR, onSoundLoadError);
			sound.addEventListener(ProgressEvent.PROGRESS, onSoundLoadProgress);
		}

		public function load(url : String) : void {
			this.url = url;
			sound.load(new URLRequest(url), new SoundLoaderContext());
		}

		private function onSoundLoaded(event : Event) : void {
			var audio : AudioData = new AudioData(sound);
			dispatchEvent(new LoadedEvent(audio));
		}

		private function onSoundLoadError(event : IOErrorEvent) : void {
			dispatchEvent(new LoadErrorEvent(url));
		}

		private function onSoundLoadProgress(event : ProgressEvent) : void {
			var total : Number = event.bytesTotal ? event.bytesTotal : 1;
			dispatchEvent(new LoadProgressEvent(Math.min(1, event.bytesLoaded / total)));
		}
	}
}

package fm.wavesurfer.audio {
	import fm.wavesurfer.audio.events.LoadProgressEvent;
	import flash.events.ProgressEvent;
	import fm.wavesurfer.audio.events.LoadErrorEvent;
	import flash.events.IOErrorEvent;
	import fm.wavesurfer.audio.events.LoadedEvent;

	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.media.SoundLoaderContext;
	import flash.net.URLRequest;

	/**
	 * @author laurent
	 */
	public class AudioLoader extends EventDispatcher {

		private var sound : Sound;
		private var url : String;

		public function AudioLoader() {
			sound = new Sound();
			sound.addEventListener(Event.COMPLETE, onSoundLoaded);
			sound.addEventListener(IOErrorEvent.IO_ERROR, onSoundLoadError);
			sound.addEventListener(ProgressEvent.PROGRESS, onSoundLoadProgress);
		}

		public function load(url : String) : void {
			this.url = url;
			sound.load(new URLRequest(url), new SoundLoaderContext(1000, true));
		}

		private function onSoundLoaded(event : Event) : void {
			var audio : AudioData = new AudioData(sound);
			dispatchEvent(new LoadedEvent(audio));
		}

		private function onSoundLoadError(event : IOErrorEvent) : void {
			dispatchEvent(new LoadErrorEvent(url));
		}

		private function onSoundLoadProgress(event : ProgressEvent) : void {
			var total : Number = event.bytesTotal ? event.bytesTotal : 1;
			dispatchEvent(new LoadProgressEvent(Math.min(1, event.bytesLoaded / total)));
		}
	}
}

Load crossdomain by default

Load crossdomain by default


/*
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package flash.utils {
import avmplus.FLASH10_FLAGS;

public function describeType(value):XML {
  return avmplus.describeType(value, FLASH10_FLAGS);
}

[native("FlashUtilScript::getAliasName")]
public native function getAliasName(value):String;

public function getQualifiedClassName(value):String {
  return avmplus.getQualifiedClassName(value);
}

[native("FlashUtilScript::getDefinitionByName")]
public native function getDefinitionByName(name:String):Object;

public function getQualifiedSuperclassName(value):String {
  return avmplus.getQualifiedSuperclassName(value);
}

[native("FlashUtilScript::getTimer")]
public native function getTimer():int;

[native("FlashUtilScript::escapeMultiByte")]
public native function escapeMultiByte(value:String):String;

[native("FlashUtilScript::unescapeMultiByte")]
public native function unescapeMultiByte(value:String):String;
}

Add license header to flash/utils/FlashUtilScript.as


package weave.ui
{
	import weave.compiler.StandardLib;
	import weave.api.core.ILinkableObject;

	import mx.containers.Canvas;
	import mx.controls.Image;

	import flash.events.Event;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import flash.events.TimerEvent;

	public class JavaScriptCanvas extends Canvas implements ILinkableObject
	{
		private var buffers:Vector.<Image> = new Vector.<Image>(2, true);
		private var buffer_index:int = 0;
		private var lastUpdate:int = 0;
		private var forceReadTimer:Timer;

		public var sourceId:String = null;

		public function JavaScriptCanvas()
		{
			super();
		}

		override protected function createChildren():void
		{
			lastUpdate = getTimer();
			forceReadTimer = new Timer(250);
			buffers[0] = new Image();
			buffers[1] = new Image();

			buffers[0].addEventListener(Event.COMPLETE, readFromCanvas);
			buffers[1].addEventListener(Event.COMPLETE, readFromCanvas);
			forceReadTimer.addEventListener(TimerEvent.TIMER, readFromCanvas);

			addChild(buffers[0]);
			addChild(buffers[1]);

			super.createChildren();

			forceReadTimer.start();
		}

		public function readFromCanvas(evt:Event):void
		{
			/* Only execute on the timer tick if we haven't loaded recently */
			if (evt.type == TimerEvent.TIMER && (getTimer() < (lastUpdate + 200)) ) return;

			if (evt.type == TimerEvent.TIMER) weaveTrace("timed out, jumpstarting canvas read");

			var content:String;

			/* TODO convert to raw ExternalInterface */
			if (sourceId) content = JavaScript.exec(
				{elementId: sourceId},
				"var canvas = document.getElementById(elementId);",
				"return canvas && canvas.toDataURL && canvas.toDataURL().split(',').pop();");

			if (sourceId && content)
			{
				setImage(content);
			}

		}

		public function setImage(base64:String):void
		{
			lastUpdate = getTimer();

			setChildIndex(buffers[buffer_index], 0);

			buffer_index = (buffer_index + 1) % 2;

			buffers[buffer_index].source = StandardLib.atob(base64);
		}
	}
}

package weave.ui
{
	import weave.compiler.StandardLib;
	import weave.api.core.ILinkableObject;
	import weave.core.LinkableString;
	import weave.api.newLinkableChild;

	import mx.containers.Canvas;
	import mx.controls.Image;

	import flash.events.Event;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import flash.events.TimerEvent;

	public class JavaScriptCanvas extends Canvas implements ILinkableObject
	{
		private var buffers:Vector.<Image> = new Vector.<Image>(2, true);
		private var buffer_index:int = 0;
		private var lastUpdate:int = 0;
		private var forceReadTimer:Timer;

		public const elementId:LinkableString = newLinkableChild(this, LinkableString);

		public function JavaScriptCanvas()
		{
			super();
		}

		override protected function createChildren():void
		{
			lastUpdate = getTimer();
			forceReadTimer = new Timer(250);
			buffers[0] = new Image();
			buffers[1] = new Image();

			buffers[0].addEventListener(Event.COMPLETE, readFromCanvas);
			buffers[1].addEventListener(Event.COMPLETE, readFromCanvas);
			forceReadTimer.addEventListener(TimerEvent.TIMER, readFromCanvas);

			addChild(buffers[0]);
			addChild(buffers[1]);

			super.createChildren();

			forceReadTimer.start();
		}

		public function readFromCanvas(evt:Event):void
		{
			/* Only execute on the timer tick if we haven't loaded recently */
			if (evt.type == TimerEvent.TIMER && (getTimer() < (lastUpdate + 200)) ) return;

			var content:String;

			/* TODO convert to raw ExternalInterface */
			if (elementId.value) content = JavaScript.exec(
				{elementId: elementId.value},
				"var canvas = document.getElementById(elementId);",
				"return canvas && canvas.toDataURL && canvas.toDataURL().split(',').pop();");

			if (elementId.value && content)
			{
				setImage(content);
			}
		}

		public function setImage(base64:String):void
		{
			lastUpdate = getTimer();

			setChildIndex(buffers[buffer_index], 0);

			buffer_index = (buffer_index + 1) % 2;

			buffers[buffer_index].source = StandardLib.atob(base64);
		}
	}
}

Make JavaScriptCanvas linkable

Make JavaScriptCanvas linkable


package dolly {

import dolly.core.dolly_internal;
import dolly.core.errors.CloningError;
import dolly.core.metadata.MetadataName;

import org.as3commons.reflect.Accessor;
import org.as3commons.reflect.Field;
import org.as3commons.reflect.IMetadataContainer;
import org.as3commons.reflect.Type;
import org.as3commons.reflect.Variable;

use namespace dolly_internal;

public class Cloner {

	private static function isTypeCloneable(type:Type):Boolean {
		return type.hasMetadata(MetadataName.CLONEABLE);
	}

	private static function isVariableCloneable(variable:Variable, skipMetadataChecking:Boolean = true):Boolean {
		return !variable.isStatic && (skipMetadataChecking || variable.hasMetadata(MetadataName.CLONEABLE));
	}

	private static function isAccessorCloneable(accessor:Accessor, skipMetadataChecking:Boolean = true):Boolean {
		return !accessor.isStatic && accessor.isReadable() && accessor.isWriteable() &&
				(skipMetadataChecking || accessor.hasMetadata(MetadataName.CLONEABLE));
	}

	dolly_internal static function getCloneableFieldsForType(type:Type):Vector.<Field> {
		const result:Vector.<Field> = new Vector.<Field>();

		var variable:Variable;
		var accessor:Accessor;

		const isClassCloneable:Boolean = isTypeCloneable(type);
		if (isClassCloneable) {
			for each(variable in type.variables) {
				if (isVariableCloneable(variable)) {
					result.push(variable);
				}
			}
			for each(accessor in type.accessors) {
				if (isAccessorCloneable(accessor)) {
					result.push(accessor);
				}
			}
		} else {
			const metadataContainers:Array = type.getMetadataContainers(MetadataName.CLONEABLE);
			for each(var metadataContainer:IMetadataContainer in metadataContainers) {
				if (metadataContainer is Variable) {
					variable = metadataContainer as Variable;
					if (isVariableCloneable(variable, false)) {
						result.push(variable);
					}
				} else if (metadataContainer is Accessor) {
					accessor = metadataContainer as Accessor;
					if (isAccessorCloneable(accessor, false)) {
						result.push(accessor);
					}
				}
			}
		}

		return result;
	}

	public static function clone(source:*):* {
		const type:Type = Type.forInstance(source);

		if (!isTypeCloneable(type)) {
			throw new CloningError(
					CloningError.CLASS_IS_NOT_CLONEABLE_MESSAGE,
					CloningError.CLASS_IS_NOT_CLONEABLE_CODE
			);
		}

		const clone:* = new (type.clazz)();

		// Find all public writable fields in a hierarchy of a source object
		// and assign their values to a clone object.
		const fieldsToClone:Vector.<Field> = getCloneableFieldsForType(type);
		var name:String;
		for each(var field:Field in fieldsToClone) {
			name = field.name;
			clone[name] = source[name];
		}

		return clone;
	}
}
}

package dolly {

import dolly.core.dolly_internal;
import dolly.core.errors.CloningError;
import dolly.core.metadata.MetadataName;

import org.as3commons.reflect.Accessor;
import org.as3commons.reflect.Field;
import org.as3commons.reflect.Type;
import org.as3commons.reflect.Variable;

use namespace dolly_internal;

public class Cloner {

	private static function isTypeCloneable(type:Type):Boolean {
		return type.hasMetadata(MetadataName.CLONEABLE);
	}

	private static function isVariableCloneable(variable:Variable, skipMetadataChecking:Boolean = true):Boolean {
		return !variable.isStatic && (skipMetadataChecking || variable.hasMetadata(MetadataName.CLONEABLE));
	}

	private static function isAccessorCloneable(accessor:Accessor, skipMetadataChecking:Boolean = true):Boolean {
		return !accessor.isStatic && accessor.isReadable() && accessor.isWriteable() &&
				(skipMetadataChecking || accessor.hasMetadata(MetadataName.CLONEABLE));
	}

	dolly_internal static function getCloneableFieldsForType(type:Type):Vector.<Field> {
		const result:Vector.<Field> = new Vector.<Field>();

		var variable:Variable;
		var accessor:Accessor;

		for each(variable in type.variables) {
			if (isVariableCloneable(variable)) {
				result.push(variable);
			}
		}
		for each(accessor in type.accessors) {
			if (isAccessorCloneable(accessor)) {
				result.push(accessor);
			}
		}

		return result;
	}

	public static function clone(source:*):* {
		const type:Type = Type.forInstance(source);

		if (!isTypeCloneable(type)) {
			throw new CloningError(
					CloningError.CLASS_IS_NOT_CLONEABLE_MESSAGE,
					CloningError.CLASS_IS_NOT_CLONEABLE_CODE
			);
		}

		const clone:* = new (type.clazz)();

		// Find all public writable fields in a hierarchy of a source object
		// and assign their values to a clone object.
		const fieldsToClone:Vector.<Field> = getCloneableFieldsForType(type);
		var name:String;
		for each(var field:Field in fieldsToClone) {
			name = field.name;
			clone[name] = source[name];
		}

		return clone;
	}
}
}

Remove checking for marking source as cloneable.


///////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011 Esri. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////
package widgets.Geoprocessing.parameters
{

import com.esri.ags.FeatureSet;
import com.esri.ags.SpatialReference;
import com.esri.ags.layers.FeatureLayer;
import com.esri.ags.layers.supportClasses.FeatureCollection;
import com.esri.ags.layers.supportClasses.LayerDetails;
import com.esri.ags.portal.PopUpRenderer;
import com.esri.ags.portal.supportClasses.PopUpInfo;
import com.esri.ags.renderers.ClassBreaksRenderer;
import com.esri.ags.renderers.IRenderer;
import com.esri.ags.renderers.SimpleRenderer;
import com.esri.ags.renderers.UniqueValueRenderer;
import com.esri.ags.symbols.Symbol;

import mx.core.ClassFactory;

public class FeatureLayerParameter extends BaseParameter implements IGPFeatureParameter
{
    //--------------------------------------------------------------------------
    //
    //  Constants
    //
    //--------------------------------------------------------------------------

    public static const DRAW_SOURCE:String = "drawtool";
    public static const LAYERS_SOURCE:String = "layers";
    public static const MAP_EXTENT_SOURCE:String = "extent";

    public static const POINT:String = "point";
    public static const POLYGON:String = "polygon";
    public static const POLYLINE:String = "polyline";

    public static const SIMPLE_MARKER:String = "simplemarker";
    public static const SIMPLE_FILL:String = "simplefill";
    public static const SIMPLE_LINE:String = "simpleline";
    public static const PICTURE_MARKER:String = "picturemarker";

    public static const SIMPLE_RENDERER:String = "simple";
    public static const CLASS_BREAKS_RENDERER:String = "classbreaks";
    public static const UNIQUE_VALUE_RENDERER:String = "uniquevalue";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    public function FeatureLayerParameter()
    {
        _layer = new FeatureLayer();
        _layer.featureCollection = new FeatureCollection(new FeatureSet([]), new LayerDetails());
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  geometryType
    //----------------------------------

    private var _geometryType:String;

    public function get geometryType():String
    {
        return _geometryType;
    }

    public function set geometryType(value:String):void
    {
        _geometryType = value;
    }

    //----------------------------------
    //  mode
    //----------------------------------

    private var _mode:String;

    public function get mode():String
    {
        return _mode;
    }

    public function set mode(value:String):void
    {
        _mode = value;
    }

    //----------------------------------
    //  layerNames
    //----------------------------------

    private var _layerNames:Array;

    public function get layerNames():Array
    {
        return _layerNames;
    }

    public function set layerNames(value:Array):void
    {
        _layerNames = value;
    }

    //----------------------------------
    //  popUpInfo
    //----------------------------------

    private var _popUpInfo:PopUpInfo;

    public function get popUpInfo():PopUpInfo
    {
        return _popUpInfo;
    }

    public function set popUpInfo(value:PopUpInfo):void
    {
        _popUpInfo = value;
    }

    //----------------------------------
    //  layer
    //----------------------------------

    private var _layer:FeatureLayer;

    public function get layer():FeatureLayer
    {
        return _layer;
    }

    //----------------------------------
    //  renderer
    //----------------------------------

    private var _renderer:IRenderer;

    public function get renderer():IRenderer
    {
        return _renderer;
    }

    public function set renderer(value:IRenderer):void
    {
        _renderer = value;
        _layer.renderer = value;
    }

    //----------------------------------
    //  layerName
    //----------------------------------

    private var _layerName:String;

    public function get layerName():String
    {
        return _layerName;
    }

    public function set layerName(value:String):void
    {
        _layerName = value;
        _layer.name = value;
    }

    //----------------------------------
    //  popUpRenderer
    //----------------------------------

    public function get popUpRenderer():ClassFactory
    {
        var popUpRenderer:ClassFactory;

        if (_popUpInfo)
        {
            popUpRenderer = new ClassFactory(PopUpRenderer);
            var popUpInfo:PopUpInfo = _popUpInfo;
            popUpRenderer.properties = { popUpInfo: popUpInfo };
        }

        return popUpRenderer;
    }

    //----------------------------------
    //  spatialReference
    //----------------------------------

    private var _spatialReference:SpatialReference;

    public function get spatialReference():SpatialReference
    {
        return _spatialReference;
    }

    public function set spatialReference(value:SpatialReference):void
    {
        _spatialReference = value;
    }

    //----------------------------------
    //  defaultSymbol
    //----------------------------------

    public function get defaultSymbol():Symbol
    {
        var symbol:Symbol;

        if (_renderer is SimpleRenderer)
        {
            symbol = (_renderer as SimpleRenderer).symbol;
        }
        else if (_renderer is ClassBreaksRenderer)
        {
            symbol = (_renderer as ClassBreaksRenderer).defaultSymbol;
        }
        else if (_renderer is UniqueValueRenderer)
        {
            symbol = (_renderer as UniqueValueRenderer).defaultSymbol;
        }

        return symbol;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  type
    //----------------------------------

    override public function get type():String
    {
        return GPParameterTypes.FEATURE_RECORD_SET_LAYER;
    }

    //----------------------------------
    //  name
    //----------------------------------

    override public function set name(value:String):void
    {
        super.name = value;
        _layer.id = value;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    override public function hasValidValue():Boolean
    {
        return _layer.featureCollection.featureSet.features.length > 0;
    }

    public override function getRequestObjectValue():Object
    {
        return _layer.featureCollection.featureSet;
    }
}

}

///////////////////////////////////////////////////////////////////////////
// Copyright (c) 2011 Esri. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////
package widgets.Geoprocessing.parameters
{

import com.esri.ags.FeatureSet;
import com.esri.ags.SpatialReference;
import com.esri.ags.layers.FeatureLayer;
import com.esri.ags.layers.supportClasses.FeatureCollection;
import com.esri.ags.layers.supportClasses.LayerDetails;
import com.esri.ags.portal.PopUpRenderer;
import com.esri.ags.portal.supportClasses.PopUpInfo;
import com.esri.ags.renderers.ClassBreaksRenderer;
import com.esri.ags.renderers.IRenderer;
import com.esri.ags.renderers.SimpleRenderer;
import com.esri.ags.renderers.UniqueValueRenderer;
import com.esri.ags.symbols.Symbol;

import mx.core.ClassFactory;

public class FeatureLayerParameter extends BaseParameter implements IGPFeatureParameter
{
    //--------------------------------------------------------------------------
    //
    //  Constants
    //
    //--------------------------------------------------------------------------

    public static const DRAW_SOURCE:String = "drawtool";
    public static const LAYERS_SOURCE:String = "layers";
    public static const MAP_EXTENT_SOURCE:String = "extent";

    public static const POINT:String = "point";
    public static const POLYGON:String = "polygon";
    public static const POLYLINE:String = "polyline";

    public static const SIMPLE_MARKER:String = "simplemarker";
    public static const SIMPLE_FILL:String = "simplefill";
    public static const SIMPLE_LINE:String = "simpleline";
    public static const PICTURE_MARKER:String = "picturemarker";

    public static const SIMPLE_RENDERER:String = "simple";
    public static const CLASS_BREAKS_RENDERER:String = "classbreaks";
    public static const UNIQUE_VALUE_RENDERER:String = "uniquevalue";

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    public function FeatureLayerParameter()
    {
        _layer = new FeatureLayer();
        _layer.featureCollection = new FeatureCollection(new FeatureSet([]), new LayerDetails());
        _layer.outFields = [ "*" ];
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  geometryType
    //----------------------------------

    private var _geometryType:String;

    public function get geometryType():String
    {
        return _geometryType;
    }

    public function set geometryType(value:String):void
    {
        _geometryType = value;
    }

    //----------------------------------
    //  mode
    //----------------------------------

    private var _mode:String;

    public function get mode():String
    {
        return _mode;
    }

    public function set mode(value:String):void
    {
        _mode = value;
    }

    //----------------------------------
    //  layerNames
    //----------------------------------

    private var _layerNames:Array;

    public function get layerNames():Array
    {
        return _layerNames;
    }

    public function set layerNames(value:Array):void
    {
        _layerNames = value;
    }

    //----------------------------------
    //  popUpInfo
    //----------------------------------

    private var _popUpInfo:PopUpInfo;

    public function get popUpInfo():PopUpInfo
    {
        return _popUpInfo;
    }

    public function set popUpInfo(value:PopUpInfo):void
    {
        _popUpInfo = value;
    }

    //----------------------------------
    //  layer
    //----------------------------------

    private var _layer:FeatureLayer;

    public function get layer():FeatureLayer
    {
        return _layer;
    }

    //----------------------------------
    //  renderer
    //----------------------------------

    private var _renderer:IRenderer;

    public function get renderer():IRenderer
    {
        return _renderer;
    }

    public function set renderer(value:IRenderer):void
    {
        _renderer = value;
        _layer.renderer = value;
    }

    //----------------------------------
    //  layerName
    //----------------------------------

    private var _layerName:String;

    public function get layerName():String
    {
        return _layerName;
    }

    public function set layerName(value:String):void
    {
        _layerName = value;
        _layer.name = value;
    }

    //----------------------------------
    //  popUpRenderer
    //----------------------------------

    public function get popUpRenderer():ClassFactory
    {
        var popUpRenderer:ClassFactory;

        if (_popUpInfo)
        {
            popUpRenderer = new ClassFactory(PopUpRenderer);
            var popUpInfo:PopUpInfo = _popUpInfo;
            popUpRenderer.properties = { popUpInfo: popUpInfo };
        }

        return popUpRenderer;
    }

    //----------------------------------
    //  spatialReference
    //----------------------------------

    private var _spatialReference:SpatialReference;

    public function get spatialReference():SpatialReference
    {
        return _spatialReference;
    }

    public function set spatialReference(value:SpatialReference):void
    {
        _spatialReference = value;
    }

    //----------------------------------
    //  defaultSymbol
    //----------------------------------

    public function get defaultSymbol():Symbol
    {
        var symbol:Symbol;

        if (_renderer is SimpleRenderer)
        {
            symbol = (_renderer as SimpleRenderer).symbol;
        }
        else if (_renderer is ClassBreaksRenderer)
        {
            symbol = (_renderer as ClassBreaksRenderer).defaultSymbol;
        }
        else if (_renderer is UniqueValueRenderer)
        {
            symbol = (_renderer as UniqueValueRenderer).defaultSymbol;
        }

        return symbol;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  type
    //----------------------------------

    override public function get type():String
    {
        return GPParameterTypes.FEATURE_RECORD_SET_LAYER;
    }

    //----------------------------------
    //  name
    //----------------------------------

    override public function set name(value:String):void
    {
        super.name = value;
        _layer.id = value;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods
    //
    //--------------------------------------------------------------------------

    override public function set paramInfo(value:Object):void
    {
        if (value)
        {
            super.paramInfo = value;
            if (value.defaultValue)
            {
                var featureSet:FeatureSet = FeatureSet.fromJSON(value.defaultValue);
                layer.featureCollection.layerDefinition.fields = featureSet.fields;
            }
        }
    }

    override public function hasValidValue():Boolean
    {
        return _layer.featureCollection.featureSet.features.length > 0;
    }

    public override function getRequestObjectValue():Object
    {
        return _layer.featureCollection.featureSet;
    }
}

}

Configure FeatureLayerParam out fields & layer definition fields.


//
// $Id$
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/nenya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.flash {

public interface Animation
{
    /**
     * The primary working method for your animation.
     */
    function updateAnimation (elapsed :Number) :void;
}
}

//
// $Id$
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/nenya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.flash {

public interface Animation
{
    /**
     * The primary working method for your animation. The argument indicates how
     * many milliseconds have passed since the previous update.
     */
    function updateAnimation (elapsed :Number) :void;
}
}

Clarify nature of argument.

Clarify nature of argument.

git-svn-id: b675b909355d5cf946977f44a8ec5a6ceb3782e4@315 ed5b42cb-e716-0410-a449-f6a68f950b19


package aerys.minko.render.shader
{
	import aerys.minko.Minko;
	import aerys.minko.ns.minko;
	import aerys.minko.render.renderer.state.RendererState;
	import aerys.minko.render.ressource.TextureRessource;
	import aerys.minko.render.shader.compiler.Compiler;
	import aerys.minko.render.shader.compiler.allocator.ParameterAllocation;
	import aerys.minko.render.shader.compiler.register.RegisterLimit;
	import aerys.minko.render.shader.compiler.register.RegisterType;
	import aerys.minko.render.shader.node.INode;
	import aerys.minko.render.shader.node.leaf.AbstractParameter;
	import aerys.minko.render.shader.node.leaf.StyleParameter;
	import aerys.minko.render.shader.node.leaf.TransformParameter;
	import aerys.minko.render.shader.node.leaf.WorldParameter;
	import aerys.minko.scene.visitor.data.LocalData;
	import aerys.minko.scene.visitor.data.StyleStack;
	import aerys.minko.type.log.DebugLevel;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Vector4;
	import aerys.minko.type.vertex.format.VertexComponent;

	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import aerys.minko.render.ressource.ShaderRessource;

	public class Shader extends ShaderRessource
	{
		use namespace minko;

		protected var _vsConstData	: Vector.<Number>;
		protected var _fsConstData	: Vector.<Number>;
		protected var _vsParams		: Vector.<ParameterAllocation>;
		protected var _fsParams		: Vector.<ParameterAllocation>;
		protected var _samplers		: Vector.<int>;

		public static function create(outputPosition	: INode,
									  outputColor		: INode) : Shader
		{
			var compiler : Compiler = new Compiler();

			compiler.load(outputPosition, outputColor);

			if (Minko.debugLevel & DebugLevel.SHADER_ATTR_ALLOC)
			{
				Minko.log(DebugLevel.SHADER_ATTR_ALLOC, compiler.writeAttributeAllocationSummary());
			}

			if (Minko.debugLevel & DebugLevel.SHADER_CONST_ALLOC)
			{
				Minko.log(DebugLevel.SHADER_CONST_ALLOC, compiler.writeConstantAllocationSummary(true));
				Minko.log(DebugLevel.SHADER_CONST_ALLOC, compiler.writeConstantAllocationSummary(false));
			}

			if (Minko.debugLevel & DebugLevel.SHADER_AGAL)
			{
				Minko.log(DebugLevel.SHADER_AGAL, compiler.compileAgalVertexShader(), compiler);
				Minko.log(DebugLevel.SHADER_AGAL, compiler.compileAgalFragmentShader(), compiler);
			}

			if (Minko.debugLevel & DebugLevel.SHADER_DOTTY)
			{
				Minko.log(DebugLevel.SHADER_DOTTY, compiler.writeDotGraph(), compiler);
			}

			return compiler.compileShader();
		}

		public function Shader(vertexShader					: ByteArray,
									  fragmentShader				: ByteArray,
									  vertexInput					: Vector.<VertexComponent>,
									  vertexShaderConstantData		: Vector.<Number>,
									  fragmentShaderConstantData	: Vector.<Number>,
									  vertexShaderParameters		: Vector.<ParameterAllocation>,
									  fragmentShaderParameters		: Vector.<ParameterAllocation>,
									  samplers						: Vector.<int>)
		{
			_vsConstData	= vertexShaderConstantData;
			_fsConstData	= fragmentShaderConstantData;
			_vsParams		= vertexShaderParameters;
			_fsParams		= fragmentShaderParameters;
			_samplers		= samplers;

			super(vertexShader, fragmentShader, vertexInput);

			if (_vsConstData.length > RegisterLimit.VS_MAX_CONSTANT * 4)
				throw new Error();
			if (_fsConstData.length > RegisterLimit.FG_MAX_CONSTANT * 4)
				throw new Error();
		}

		public function fillRenderState(state	: RendererState,
										style	: StyleStack,
										local	: LocalData,
										world	: Dictionary) : Boolean
		{
			setTextures(state, style, local, world);
			setConstants(state, style, local, world);

			state.shader = this;

			return true;
		}

		protected function setTextures(state		: RendererState,
									   styleStack	: StyleStack,
								   	   localData	: LocalData,
									   worldData	: Object) : void
		{
			var texture 		: TextureRessource	= null;
			var samplerStyleId 	: int				= 0;
			var samplerCount 	: uint 				= _samplers.length;

			for (var i : int = 0; i < samplerCount; ++i)
			{
				samplerStyleId = _samplers[i];
				texture = styleStack.get(samplerStyleId) as TextureRessource;
				state.setTextureAt(i, texture);
			}
		}

		protected function setConstants(state		: RendererState,
									    styleStack	: StyleStack,
										local		: LocalData,
										world		: Dictionary) : void
		{
			updateConstData(_vsConstData, _vsParams, styleStack, local, world);
			updateConstData(_fsConstData, _fsParams, styleStack, local, world);

			state.setVertexConstants(0, _vsConstData);
			state.setFragmentConstants(0, _fsConstData);
		}

		protected function updateConstData(constData	: Vector.<Number>,
										   paramsAllocs	: Vector.<ParameterAllocation>,
										   styleStack	: StyleStack,
										   local		: LocalData,
										   world		: Dictionary) : void
		{
			var paramLength	: int = paramsAllocs.length;

			for (var i : int = 0; i < paramLength; ++i)
			{
				var paramAlloc	: ParameterAllocation	= paramsAllocs[i];
				var param		: AbstractParameter		= paramAlloc._parameter;

				var data : Object = getParameterData(param, styleStack, local, world);

				loadParameterData(paramAlloc, constData, data);
			}
		}

		private function getParameterData(param			: AbstractParameter,
										  styleStack	: StyleStack,
										  local			: LocalData,
										  world			: Dictionary) : Object
		{
			if (param is StyleParameter)
			{
				if (param._index != -1)
				{
					return styleStack.get(param._key as int).getItem(param._index)[param._field];
				}
				else if (param._field != null)
				{
					return styleStack.get(param._key as int)[param._field];
				}
				else
				{
					return styleStack.get(param._key as int, null);
				}
			}
			else if (param is WorldParameter)
			{
				var paramClass : Class = WorldParameter(param)._class;

				if (param._index != -1)
				{
					return world[paramClass].getItem(param._index)[param._field];
				}
				else if (param._field != null)
				{
					return world[paramClass][param._field];
				}
				else
				{
					return world[paramClass];
				}
			}
			else if (param is TransformParameter)
			{
				return local[param._key];
			}
			else
				throw new Error('Unknown parameter type');
		}

		private function loadParameterData(paramAlloc	: ParameterAllocation,
										   constData	: Vector.<Number>,
										   data			: Object) : void
		{
			var offset	: uint	= paramAlloc._offset;
			var size	: uint	= paramAlloc._parameter._size;

			if (data is int)
			{
				var intData : int = data as int;

				if (size == 1)
				{
					constData[offset] = intData;
				}
				else if (size == 2)
				{
					constData[offset] = ((intData & 0xFFFF0000) >>> 16) / Number(0xffff);
					constData[int(offset + 2)] = (intData & 0x0000FFFF) / Number(0xffff);
				}
				else if (size == 3)
				{
					constData[offset] = ((intData & 0xFF0000) >>> 16) / 255.;
					constData[int(offset + 1)] = ((intData & 0x00FF00) >>> 8) / 255.;
					constData[int(offset + 2)] = (intData & 0x0000FF) / 255.;
				}
				else if (size == 4)
				{

					constData[offset] = ((intData & 0xFF000000) >>> 24) / 255.;
					constData[int(offset + 1)] = ((intData & 0x00FF0000) >>> 16) / 255.;
					constData[int(offset + 2)] = ((intData & 0x0000FF00) >>> 8) / 255.;
					constData[int(offset + 3)] = ((intData & 0x000000FF)) / 255.;
				}
			}
			else if (data is uint)
			{
				var uintData : uint = data as uint;

				if (size == 1)
				{
					constData[offset] = uintData;
				}
				else if (size == 2)
				{
					constData[offset] = ((uintData & 0xFFFF0000) >>> 16) / Number(0xffff);
					constData[int(offset + 2)] = (uintData & 0x0000FFFF) / Number(0xffff);
				}
				else if (size == 3)
				{
					constData[offset] = ((uintData & 0xFF0000) >>> 16) / 255.;
					constData[int(offset + 1)] = ((uintData & 0x00FF00) >>> 8) / 255.;
					constData[int(offset + 2)] = (uintData & 0x0000FF) / 255.;
				}
				else if (size == 4)
				{

					constData[offset] = ((uintData & 0xFF000000) >>> 24) / 255.;
					constData[int(offset + 1)] = ((uintData & 0x00FF0000) >>> 16) / 255.;
					constData[int(offset + 2)] = ((uintData & 0x0000FF00) >>> 8) / 255.;
					constData[int(offset + 3)] = ((uintData & 0x000000FF)) / 255.;
				}
			}
			else if (data is Number)
			{
				if (size != 1)
					throw new Error('Parameter ' + paramAlloc.toString() + ' is ' +
						'defined as size=' + size + ' but only a Number was found');

				constData[offset] = data as Number;
			}
			else if (data is Vector4)
			{
				var vectorData : Vector4 = data as Vector4;

				constData[offset] = vectorData.x;
				size >= 2 && (constData[int(offset + 1)] = vectorData.y);
				size >= 3 && (constData[int(offset + 2)] = vectorData.z);
				size >= 4 && (constData[int(offset + 3)] = vectorData.w);
			}
			else if (data is Matrix4x4)
			{
				(data as Matrix4x4).getRawData(constData, offset, true);
			}
			else if (data is Vector.<Vector4>)
			{
				var vectorVectorData		: Vector.<Vector4>	= data as Vector.<Vector4>;
				var vectorVectorDataLength	: uint				= vectorVectorData.length;

				for (var j : uint = 0; j < vectorVectorDataLength; ++j)
				{
					constData[offset + 4 * j] = vectorData.x;
					constData[int(offset + 4 * j + 1)] = vectorData.y;
					constData[int(offset + 4 * j + 2)] = vectorData.z;
					constData[int(offset + 4 * j + 3)] = vectorData.w;
				}
			}
			else if (data is Vector.<Matrix4x4>)
			{
				var matrixVectorData		: Vector.<Matrix4x4>	= data as Vector.<Matrix4x4>;
				var matrixVectorDataLength	: uint					= matrixVectorData.length;

				for (var i : uint = 0; i < matrixVectorDataLength; ++i)
					matrixVectorData[i].getRawData(constData, offset + i * 16, true);
			}
			else if (data == null)
			{
				throw new Error('Parameter ' + paramAlloc.toString() + ' is ' +
					'null and required by automatic shader');
			}
			else
			{
				throw new Error('Parameter ' + paramAlloc.toString() + ' is ' +
					'neither a int, a Number, a Vector4 or a Matrix4x4. Unable to ' +
					'map it to a shader constant.');
			}
		}

	}
}

package aerys.minko.render.shader
{
	import aerys.minko.Minko;
	import aerys.minko.ns.minko;
	import aerys.minko.render.renderer.state.RendererState;
	import aerys.minko.render.ressource.TextureRessource;
	import aerys.minko.render.shader.compiler.Compiler;
	import aerys.minko.render.shader.compiler.allocator.ParameterAllocation;
	import aerys.minko.render.shader.compiler.register.RegisterLimit;
	import aerys.minko.render.shader.compiler.register.RegisterType;
	import aerys.minko.render.shader.node.INode;
	import aerys.minko.render.shader.node.leaf.AbstractParameter;
	import aerys.minko.render.shader.node.leaf.StyleParameter;
	import aerys.minko.render.shader.node.leaf.TransformParameter;
	import aerys.minko.render.shader.node.leaf.WorldParameter;
	import aerys.minko.scene.visitor.data.LocalData;
	import aerys.minko.scene.visitor.data.StyleStack;
	import aerys.minko.type.log.DebugLevel;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Vector4;
	import aerys.minko.type.vertex.format.VertexComponent;

	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import aerys.minko.render.ressource.ShaderRessource;

	public class Shader extends ShaderRessource
	{
		use namespace minko;

		protected var _vsConstData	: Vector.<Number>;
		protected var _fsConstData	: Vector.<Number>;
		protected var _vsParams		: Vector.<ParameterAllocation>;
		protected var _fsParams		: Vector.<ParameterAllocation>;
		protected var _samplers		: Vector.<int>;

		public static function create(outputPosition	: INode,
									  outputColor		: INode) : Shader
		{
			var compiler : Compiler = new Compiler();

			compiler.load(outputPosition, outputColor);

			if (Minko.debugLevel & DebugLevel.SHADER_ATTR_ALLOC)
			{
				Minko.log(DebugLevel.SHADER_ATTR_ALLOC, compiler.writeAttributeAllocationSummary());
			}

			if (Minko.debugLevel & DebugLevel.SHADER_CONST_ALLOC)
			{
				Minko.log(DebugLevel.SHADER_CONST_ALLOC, compiler.writeConstantAllocationSummary(true));
				Minko.log(DebugLevel.SHADER_CONST_ALLOC, compiler.writeConstantAllocationSummary(false));
			}

			if (Minko.debugLevel & DebugLevel.SHADER_AGAL)
			{
				Minko.log(DebugLevel.SHADER_AGAL, compiler.compileAgalVertexShader(), compiler);
				Minko.log(DebugLevel.SHADER_AGAL, compiler.compileAgalFragmentShader(), compiler);
			}

			if (Minko.debugLevel & DebugLevel.SHADER_DOTTY)
			{
				Minko.log(DebugLevel.SHADER_DOTTY, compiler.writeDotGraph(), compiler);
			}

			return compiler.compileShader();
		}

		public function Shader(vertexShader					: ByteArray,
									  fragmentShader				: ByteArray,
									  vertexInput					: Vector.<VertexComponent>,
									  vertexShaderConstantData		: Vector.<Number>,
									  fragmentShaderConstantData	: Vector.<Number>,
									  vertexShaderParameters		: Vector.<ParameterAllocation>,
									  fragmentShaderParameters		: Vector.<ParameterAllocation>,
									  samplers						: Vector.<int>)
		{
			_vsConstData	= vertexShaderConstantData;
			_fsConstData	= fragmentShaderConstantData;
			_vsParams		= vertexShaderParameters;
			_fsParams		= fragmentShaderParameters;
			_samplers		= samplers;

			super(vertexShader, fragmentShader, vertexInput);

			if (_vsConstData.length > RegisterLimit.VS_MAX_CONSTANT * 4)
				throw new Error();
			if (_fsConstData.length > RegisterLimit.FG_MAX_CONSTANT * 4)
				throw new Error();
		}

		public function fillRenderState(state	: RendererState,
										style	: StyleStack,
										local	: LocalData,
										world	: Dictionary) : Boolean
		{
			setTextures(state, style, local, world);
			setConstants(state, style, local, world);

			state.shader = this;

			return true;
		}

		protected function setTextures(state		: RendererState,
									   styleStack	: StyleStack,
								   	   localData	: LocalData,
									   worldData	: Object) : void
		{
			var texture 		: TextureRessource	= null;
			var samplerStyleId 	: int				= 0;
			var samplerCount 	: uint 				= _samplers.length;

			for (var i : int = 0; i < samplerCount; ++i)
			{
				samplerStyleId = _samplers[i];
				texture = styleStack.get(samplerStyleId) as TextureRessource;
				state.setTextureAt(i, texture);
			}
		}

		protected function setConstants(state		: RendererState,
									    styleStack	: StyleStack,
										local		: LocalData,
										world		: Dictionary) : void
		{
			updateConstData(_vsConstData, _vsParams, styleStack, local, world);
			updateConstData(_fsConstData, _fsParams, styleStack, local, world);

			state.setVertexConstants(0, _vsConstData);
			state.setFragmentConstants(0, _fsConstData);
		}

		protected function updateConstData(constData	: Vector.<Number>,
										   paramsAllocs	: Vector.<ParameterAllocation>,
										   styleStack	: StyleStack,
										   local		: LocalData,
										   world		: Dictionary) : void
		{
			var paramLength	: int = paramsAllocs.length;

			for (var i : int = 0; i < paramLength; ++i)
			{
				var paramAlloc	: ParameterAllocation	= paramsAllocs[i];
				var param		: AbstractParameter		= paramAlloc._parameter;

				var data : Object = getParameterData(param, styleStack, local, world);

				loadParameterData(paramAlloc, constData, data);
			}
		}

		private function getParameterData(param			: AbstractParameter,
										  styleStack	: StyleStack,
										  local			: LocalData,
										  world			: Dictionary) : Object
		{
			if (param is StyleParameter)
			{
				if (param._index != -1)
				{
					return styleStack.get(param._key as int).getItem(param._index)[param._field];
				}
				else if (param._field != null)
				{
					return styleStack.get(param._key as int)[param._field];
				}
				else
				{
					return styleStack.get(param._key as int, null);
				}
			}
			else if (param is WorldParameter)
			{
				var paramClass : Class = WorldParameter(param)._class;

				if (param._index != -1)
				{
					return world[paramClass].getItem(param._index)[param._field];
				}
				else if (param._field != null)
				{
					return world[paramClass][param._field];
				}
				else
				{
					return world[paramClass];
				}
			}
			else if (param is TransformParameter)
			{
				return local[param._key];
			}
			else
				throw new Error('Unknown parameter type');
		}

		private function loadParameterData(paramAlloc	: ParameterAllocation,
										   constData	: Vector.<Number>,
										   data			: Object) : void
		{
			var offset	: uint	= paramAlloc._offset;
			var size	: uint	= paramAlloc._parameter._size;

			if (data is int)
			{
				var intData : int = data as int;

				if (size == 1)
				{
					constData[offset] = intData;
				}
				else if (size == 2)
				{
					constData[offset] = ((intData & 0xFFFF0000) >>> 16) / Number(0xffff);
					constData[int(offset + 2)] = (intData & 0x0000FFFF) / Number(0xffff);
				}
				else if (size == 3)
				{
					constData[offset] = ((intData & 0xFF0000) >>> 16) / 255.;
					constData[int(offset + 1)] = ((intData & 0x00FF00) >>> 8) / 255.;
					constData[int(offset + 2)] = (intData & 0x0000FF) / 255.;
				}
				else if (size == 4)
				{

					constData[offset] = ((intData & 0xFF000000) >>> 24) / 255.;
					constData[int(offset + 1)] = ((intData & 0x00FF0000) >>> 16) / 255.;
					constData[int(offset + 2)] = ((intData & 0x0000FF00) >>> 8) / 255.;
					constData[int(offset + 3)] = ((intData & 0x000000FF)) / 255.;
				}
			}
			else if (data is uint)
			{
				var uintData : uint = data as uint;

				if (size == 1)
				{
					constData[offset] = uintData;
				}
				else if (size == 2)
				{
					constData[offset] = ((uintData & 0xFFFF0000) >>> 16) / Number(0xffff);
					constData[int(offset + 2)] = (uintData & 0x0000FFFF) / Number(0xffff);
				}
				else if (size == 3)
				{
					constData[offset] = ((uintData & 0xFF0000) >>> 16) / 255.;
					constData[int(offset + 1)] = ((uintData & 0x00FF00) >>> 8) / 255.;
					constData[int(offset + 2)] = (uintData & 0x0000FF) / 255.;
				}
				else if (size == 4)
				{

					constData[offset] = ((uintData & 0xFF000000) >>> 24) / 255.;
					constData[int(offset + 1)] = ((uintData & 0x00FF0000) >>> 16) / 255.;
					constData[int(offset + 2)] = ((uintData & 0x0000FF00) >>> 8) / 255.;
					constData[int(offset + 3)] = ((uintData & 0x000000FF)) / 255.;
				}
			}
			else if (data is Number)
			{
				if (size != 1)
					throw new Error('Parameter ' + paramAlloc.toString() + ' is ' +
						'defined as size=' + size + ' but only a Number was found');

				constData[offset] = data as Number;
			}
			else if (data is Vector4)
			{
				var vectorData : Vector4 = data as Vector4;

				constData[offset] = vectorData.x;
				size >= 2 && (constData[int(offset + 1)] = vectorData.y);
				size >= 3 && (constData[int(offset + 2)] = vectorData.z);
				size >= 4 && (constData[int(offset + 3)] = vectorData.w);
			}
			else if (data is Matrix4x4)
			{
				(data as Matrix4x4).getRawData(constData, offset, true);
			}
			else if (data is Vector.<Vector4>)
			{
				var vectorVectorData		: Vector.<Vector4>	= data as Vector.<Vector4>;
				var vectorVectorDataLength	: uint				= vectorVectorData.length;

				for (var j : uint = 0; j < vectorVectorDataLength; ++j)
				{
					vectorData = vectorVectorData[j];

					constData[offset + 4 * j] = vectorData.x;
					constData[int(offset + 4 * j + 1)] = vectorData.y;
					constData[int(offset + 4 * j + 2)] = vectorData.z;
					constData[int(offset + 4 * j + 3)] = vectorData.w;
				}
			}
			else if (data is Vector.<Matrix4x4>)
			{
				var matrixVectorData		: Vector.<Matrix4x4>	= data as Vector.<Matrix4x4>;
				var matrixVectorDataLength	: uint					= matrixVectorData.length;

				for (var i : uint = 0; i < matrixVectorDataLength; ++i)
				{
					matrixVectorData[i].getRawData(constData, offset + i * 16, true);
				}
			}
			else if (data == null)
			{
				throw new Error('Parameter ' + paramAlloc.toString() + ' is ' +
					'null and required by automatic shader');
			}
			else
			{
				throw new Error('Parameter ' + paramAlloc.toString() + ' is ' +
					'neither a int, a Number, a Vector4 or a Matrix4x4. Unable to ' +
					'map it to a shader constant.');
			}
		}
	}
}

Fix bug on uploading vector4 arrays shader parameters to renderStates


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.core
{
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.system.Capabilities;

import mx.core.mx_internal;
import mx.managers.SystemManager;

use namespace mx_internal;

/**
 *  The RuntimeDPIProvider class provides the default mapping of
 *  similar device DPI values into predefined DPI classes.
 *  An Application may have its runtimeDPIProvider property set to a
 *  subclass of RuntimeDPIProvider to override Flex's default mappings.
 *  Overriding Flex's default mappings will cause changes in the Application's
 *  automatic scaling behavior.
 *
 *
Overriding Flex's default mappings is usually only necessary for devices
 *  that incorrectly report their screenDPI and for devices that may scale better
 *  in a different DPI class.

 *
 *
Flex's default mappings are:
 *

 *
160 DPI	<140 DPI

 *
160 DPI	>=140 DPI and <=200 DPI

 *
240 DPI	>=200 DPI and <=280 DPI

 *
320 DPI	>=280 DPI and <=400 DPI

 *
480 DPI	>=400 DPI and <=560 DPI

 *
640 DPI	>=640 DPI

 *

 *

 *
 *
 *
 *
Subclasses of RuntimeDPIProvider should only depend on runtime APIs
 *  and should not depend on any classes specific to the Flex framework except
 *  mx.core.DPIClassification.

 *
 *  @includeExample examples/RuntimeDPIProviderApp.mxml -noswf
 *  @includeExample examples/RuntimeDPIProviderExample.as -noswf
 *  @includeExample examples/views/RuntimeDPIProviderAppView.mxml -noswf
 *
 *  @see mx.core.DPIClassification
 *  @see spark.components.Application#applicationDPI
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class RuntimeDPIProvider
{
    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function RuntimeDPIProvider()
    {
    }

    /**
     *  Returns the runtime DPI of the current device by mapping its
     *  flash.system.Capabilities.screenDPI to one of several DPI
     *  values in mx.core.DPIClassification.
     *
     *  A number of devices can have slightly different DPI values and Flex maps these
     *  into the several DPI classes.
     *
     *  Flex uses this method to calculate the current DPI value when an Application
     *  authored for a specific DPI is adapted to the current one through scaling.
     *
     *
 Exceptions:

     *

     *
All non-retina iPads  receive 160 DPI

     *
All retina iPads  receive 320 DPI

     *

     *
     *  @param dpi The DPI value.
     *  @return The corresponding DPIClassification value.
     *                                                                               isI
     *  @see flash.system.Capabilities
     *  @see mx.core.DPIClassification
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */

    public function get runtimeDPI():Number
    {

        var isIOS:Boolean = Capabilities.version.indexOf("IOS") == 0;
        var screenDPI : Number= Capabilities.screenDPI;

        if (isIOS) {

            var root:DisplayObject = SystemManager.getSWFRoot(this);
            if (root != null )  {
                var stage:Stage = root.stage;
                if (stage != null){
                    var scX:Number = stage.fullScreenWidth;
                    var scY:Number = stage.fullScreenHeight;
                    /*  as of Dec 2013,  iPad (resp. iPad retina)   are the only iOS devices to have 1024 (resp. 2048) screen width or height
                     cf http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density#Apple
                     * */
                    if ((scX == 2048 || scY == 2048))
                        return DPIClassification.DPI_320;
                    else if (scX == 1024 || scY == 1024)
                        return DPIClassification.DPI_160;
                }
            }
        }
        return classifyDPI(screenDPI);

    }

    /**
     *  @private
     *  Matches the specified DPI to a DPIClassification value.
     *  A number of devices can have slightly different DPI values and classifyDPI
     *  maps these into the several DPI classes.
     *
     *  This method is specifically kept for Design View. Flex uses RuntimeDPIProvider
     *  to calculate DPI classes.
     *
     *  @param dpi The DPI value.
     *  @return The corresponding DPIClassification value.
     */
    mx_internal static function classifyDPI(dpi:Number):Number
    {
		if (dpi <= 140)
			return DPIClassification.DPI_120;

        if (dpi <= 200)
            return DPIClassification.DPI_160;

        if (dpi <= 280)
            return DPIClassification.DPI_240;

		if (dpi <= 400)
			return DPIClassification.DPI_320;

		if (dpi <= 560)
			return DPIClassification.DPI_480;

        return DPIClassification.DPI_640;
    }
}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package mx.core
{
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.system.Capabilities;

import mx.core.mx_internal;
import mx.managers.SystemManager;

use namespace mx_internal;

/**
 *  The RuntimeDPIProvider class provides the default mapping of
 *  similar device DPI values into predefined DPI classes.
 *  An Application may have its runtimeDPIProvider property set to a
 *  subclass of RuntimeDPIProvider to override Flex's default mappings.
 *  Overriding Flex's default mappings will cause changes in the Application's
 *  automatic scaling behavior.
 *
 *
Overriding Flex's default mappings is usually only necessary for devices
 *  that incorrectly report their screenDPI and for devices that may scale better
 *  in a different DPI class.

 *
 *
Flex's default mappings are:
 *

 *
160 DPI	<140 DPI

 *
160 DPI	>=140 DPI and <=200 DPI

 *
240 DPI	>=200 DPI and <=280 DPI

 *
320 DPI	>=280 DPI and <=400 DPI

 *
480 DPI	>=400 DPI and <=560 DPI

 *
640 DPI	>=640 DPI

 *

 *

 *
 *
 *
 *
Subclasses of RuntimeDPIProvider should only depend on runtime APIs
 *  and should not depend on any classes specific to the Flex framework except
 *  mx.core.DPIClassification.

 *
 *  @includeExample examples/RuntimeDPIProviderApp.mxml -noswf
 *  @includeExample examples/RuntimeDPIProviderExample.as -noswf
 *  @includeExample examples/views/RuntimeDPIProviderAppView.mxml -noswf
 *
 *  @see mx.core.DPIClassification
 *  @see spark.components.Application#applicationDPI
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
public class RuntimeDPIProvider
{

    mx_internal static const IPAD_MAX_EXTENT:int = 1024;
    mx_internal static const IPAD_RETINA_MAX_EXTENT: int = 2048;

    /**
     *  Constructor.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function RuntimeDPIProvider()
    {
    }

    /**
     *  Returns the runtime DPI of the current device by mapping its
     *  flash.system.Capabilities.screenDPI to one of several DPI
     *  values in mx.core.DPIClassification.
     *
     *  A number of devices can have slightly different DPI values and Flex maps these
     *  into the several DPI classes.
     *
     *  Flex uses this method to calculate the current DPI value when an Application
     *  authored for a specific DPI is adapted to the current one through scaling.
     *
     *
 Exceptions:

     *

     *
All non-retina iPads  receive 160 DPI

     *
All retina iPads  receive 320 DPI

     *

     *
     *  @param dpi The DPI value.
     *  @return The corresponding DPIClassification value.
     *                                                                               isI
     *  @see flash.system.Capabilities
     *  @see mx.core.DPIClassification
     *
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */

    public function get runtimeDPI():Number
    {

        var isIOS:Boolean = Capabilities.version.indexOf("IOS") == 0;
        var screenDPI : Number= Capabilities.screenDPI;

        if (isIOS) {

            var root:DisplayObject = SystemManager.getSWFRoot(this);
            if (root != null )  {
                var stage:Stage = root.stage;
                if (stage != null){
                    var scX:Number = stage.fullScreenWidth;
                    var scY:Number = stage.fullScreenHeight;
                    /*  as of Dec 2013,  iPad (resp. iPad retina)   are the only iOS devices to have 1024 (resp. 2048) screen width or height
                     cf http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density#Apple
                     * */
                    if ((scX == IPAD_RETINA_MAX_EXTENT || scY == IPAD_RETINA_MAX_EXTENT))
                        return DPIClassification.DPI_320;
                    else if (scX == IPAD_MAX_EXTENT || scY == IPAD_MAX_EXTENT)
                        return DPIClassification.DPI_160;
                }
            }
        }
        return classifyDPI(screenDPI);

    }

    /**
     *  @private
     *  Matches the specified DPI to a DPIClassification value.
     *  A number of devices can have slightly different DPI values and classifyDPI
     *  maps these into the several DPI classes.
     *
     *  This method is specifically kept for Design View. Flex uses RuntimeDPIProvider
     *  to calculate DPI classes.
     *
     *  @param dpi The DPI value.
     *  @return The corresponding DPIClassification value.
     */
    mx_internal static function classifyDPI(dpi:Number):Number
    {
		if (dpi <= 140)
			return DPIClassification.DPI_120;

        if (dpi <= 200)
            return DPIClassification.DPI_160;

        if (dpi <= 280)
            return DPIClassification.DPI_240;

		if (dpi <= 400)
			return DPIClassification.DPI_320;

		if (dpi <= 560)
			return DPIClassification.DPI_480;

        return DPIClassification.DPI_640;
    }
}
}

UPDATE FIX FLEX-33861 Flex Incorrectly Scaling Down Application set 1024 and 2048 as static vars so that they can be changed if needed