////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.binding
{
	import flash.events.IEventDispatcher;
	import flash.events.Event;

	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IDocument;

    /**
     *  The SimpleBinding class is lightweight data-binding class that
     *  is optimized for simple assignments of one object's property to
     *  another object's property.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class SimpleBinding implements IBead, IDocument
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function SimpleBinding()
		{
		}

        /**
         *  The source object that dispatches an event
         *  when the property changes
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var source:IEventDispatcher;

        /**
         *  The host mxml document for the source and
         *  destination objects.  The source object
         *  is either this document for simple bindings
         *  like {foo} where foo is a property on
         *  the mxml documnet, or found as document[sourceID]
         *  for simple bindings like {someid.someproperty}
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        protected var document:Object;

        /**
         *  The destination object.  It is always the same
         *  as the strand.  SimpleBindings are attached to
         *  the strand of the destination object.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var destination:Object;

        /**
         *  If not null, the id of the mxml tag who's property
         *  is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var sourceID:String;

        /**
         *  If not null, the name of a property on the
         *  mxml document that is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var sourcePropertyName:String;

        /**
         *  The event name that is dispatched when the source
         *  property changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var eventName:String;

        /**
         *  The name of the property on the strand that
         *  is set when the source property changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var destinationPropertyName:String;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function set strand(value:IStrand):void
		{
			if (destination == null)
                destination = value;
            if (sourceID != null)
    			source = document[sourceID] as IEventDispatcher;
            else
                source = document as IEventDispatcher;
			source.addEventListener(eventName, changeHandler);
			destination[destinationPropertyName] = source[sourcePropertyName];
		}

        /**
         *  @copy org.apache.flex.core.IDocument#setDocument()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function setDocument(document:Object, id:String = null):void
		{
			this.document = document;
		}

		private function changeHandler(event:Event):void
		{
			destination[destinationPropertyName] = source[sourcePropertyName];
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  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 org.apache.flex.binding
{
	import flash.events.IEventDispatcher;
	import flash.events.Event;

	import org.apache.flex.core.IBead;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IDocument;
    import org.apache.flex.events.ValueChangeEvent;

    /**
     *  The SimpleBinding class is lightweight data-binding class that
     *  is optimized for simple assignments of one object's property to
     *  another object's property.
     *
     *  @langversion 3.0
     *  @playerversion Flash 10.2
     *  @playerversion AIR 2.6
     *  @productversion FlexJS 0.0
     */
	public class SimpleBinding implements IBead, IDocument
	{
        /**
         *  Constructor.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function SimpleBinding()
		{
		}

        /**
         *  The source object that dispatches an event
         *  when the property changes
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		protected var source:IEventDispatcher;

        /**
         *  The host mxml document for the source and
         *  destination objects.  The source object
         *  is either this document for simple bindings
         *  like {foo} where foo is a property on
         *  the mxml documnet, or found as document[sourceID]
         *  for simple bindings like {someid.someproperty}
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        protected var document:Object;

        /**
         *  The destination object.  It is always the same
         *  as the strand.  SimpleBindings are attached to
         *  the strand of the destination object.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var destination:Object;

        /**
         *  If not null, the id of the mxml tag who's property
         *  is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var sourceID:String;

        /**
         *  If not null, the name of a property on the
         *  mxml document that is being watched for changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
        public var sourcePropertyName:String;

        /**
         *  The event name that is dispatched when the source
         *  property changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var eventName:String;

        /**
         *  The name of the property on the strand that
         *  is set when the source property changes.
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public var destinationPropertyName:String;

        /**
         *  @copy org.apache.flex.core.IBead#strand
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function set strand(value:IStrand):void
		{
			if (destination == null)
                destination = value;
            if (sourceID != null)
            {
    			source = document[sourceID] as IEventDispatcher;
                if (source == null)
                {
                    document.addEventListener("valueChange",
                        sourceChangeHandler);
                    return;
                }
            }
            else
                source = document as IEventDispatcher;
			source.addEventListener(eventName, changeHandler);
			destination[destinationPropertyName] = source[sourcePropertyName];
		}

        /**
         *  @copy org.apache.flex.core.IDocument#setDocument()
         *
         *  @langversion 3.0
         *  @playerversion Flash 10.2
         *  @playerversion AIR 2.6
         *  @productversion FlexJS 0.0
         */
		public function setDocument(document:Object, id:String = null):void
		{
			this.document = document;
		}

		private function changeHandler(event:Event):void
		{
			destination[destinationPropertyName] = source[sourcePropertyName];
		}

        private function sourceChangeHandler(event:ValueChangeEvent):void
        {
            if (event.propertyName != sourceID)
                return;

            if (source)
                source.removeEventListener(eventName, changeHandler);

            source = document[sourceID] as IEventDispatcher;
            if (source)
            {
                source.addEventListener(eventName, changeHandler);
                destination[destinationPropertyName] = source[sourcePropertyName];
            }
        }
	}
}

handle source changes

handle source changes


package krewfw.core {

    import starling.animation.Transitions;

    /**
     * Expand tween transition functions of Starling.
     */
    //------------------------------------------------------------
    public class KrewTransition {

        // Already exists in starling
        public static const EASE_IN_QUAD :String = "krew.easeInQuad";  // quadratic
        public static const EASE_OUT_QUAD:String = "krew.easeOutQuad";

        //------------------------------------------------------------
        public static function registerExtendedTransitions():void {
            Transitions.register(EASE_IN_QUAD,  _easeInQuad);
            Transitions.register(EASE_OUT_QUAD, _easeOutQuad);
        }

        private static function _easeInQuad(ratio:Number):Number {
            return ratio * ratio;
        }

        private static function _easeOutQuad(ratio:Number):Number {
            var invRatio:Number = ratio - 1.0;
            return (-invRatio * invRatio) + 1;
        }

    }
}

package krewfw.core {

    import starling.animation.Transitions;

    /**
     * Expand tween transition functions of Starling.
     */
    //------------------------------------------------------------
    public class KrewTransition {

        // Already exists in starling
        public static const EASE_IN_QUAD :String = "krew.easeInQuad";  // quadratic
        public static const EASE_OUT_QUAD:String = "krew.easeOutQuad";
        public static const SWING        :String = "krew.swing";

        //------------------------------------------------------------
        public static function registerExtendedTransitions():void {
            Transitions.register(EASE_IN_QUAD,  _easeInQuad);
            Transitions.register(EASE_OUT_QUAD, _easeOutQuad);
            Transitions.register(SWING,         _swing);
        }

        private static function _easeInQuad(ratio:Number):Number {
            return ratio * ratio;
        }

        private static function _easeOutQuad(ratio:Number):Number {
            var invRatio:Number = ratio - 1.0;
            return (-invRatio * invRatio) + 1;
        }

        private static function _swing(ratio:Number):Number {
            var swing:Number = 1 + (Math.sin(ratio * 8 * Math.PI) * (1 - ratio));

            if (ratio < 0.3) {
                var initInvRatio:Number = (ratio / 0.3) - 1.0;
                var initEaseOut:Number  = (-initInvRatio * initInvRatio) + 1;
                swing *= initEaseOut;
            }

            return swing;
        }

    }
}

Add transition

Add transition


package aerys.minko.type.loader
{
	import aerys.minko.render.geometry.Geometry;
	import aerys.minko.render.material.Material;
	import aerys.minko.render.material.basic.BasicMaterial;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.type.Signal;

	public final class AssetsLibrary
	{
		private var _numGeometries 	: uint 						= 0;
		private var _numMaterials	: uint 						= 0;
		private var _numTextures	: uint 						= 0;

		private var _geometryList	: Vector.<Geometry> 		= new Vector.<Geometry>();
		private var _materialList	: Vector.<Material> 		= new Vector.<Material>();
		private var _textureList	: Vector.<TextureResource> 	= new Vector.<TextureResource>();

		private var _geometries		: Object;
		private var _textures		: Object;
		private var _materials		: Object;
		private var _layers			: Vector.<String>;
		private var _nameToLayer	: Object;

		private var _geometryAdded	: Signal;
		private var _textureAdded	: Signal;
		private var _materialAdded	: Signal;
		private var _layerAdded		: Signal;

		public function AssetsLibrary()
		{
			initialize();
			initializeSignals();
		}

		public function get numTextures() : uint
		{
			return _numTextures;
		}

		public function get numGeometries() : uint
		{
			return _numGeometries;
		}

		public function get numMaterials() : uint
		{
			return _numMaterials;
		}

		public function getMaterialAt(index : uint): Material
		{
			return _materialList[index];
		}

		public function getGeometryAt(index : uint): Geometry
		{
			return _geometryList[index];
		}

		public function getTextureAt(index : uint): TextureResource
		{
			return _textureList[index];
		}

		public function getMaterialByName(name : String) : Material
		{
			return _materials[name];
		}

		public function getTextureByName(name : String) : TextureResource
		{
			return _textures[name];
		}

		public function getGeometryByName(name : String) : Geometry
		{
			return _geometries[name];
		}

		private function initialize() : void
		{
			_geometries		= {};
			_textures		= {};
			_materials		= {};

			_layers			= new Vector.<String>(32, true);
			_layers[0]		= 'Default';
			for (var i : uint = 1; i < _layers.length; ++i)
				_layers[i]	= 'Layer_' + i;

			_nameToLayer	= {};
		}

		private function initializeSignals() : void
		{
			_geometryAdded	= new Signal('AssetsLibrary.geometryAdded');
			_textureAdded	= new Signal('AssetsLibrary.textureAdded');
			_materialAdded	= new Signal('AssetsLibrary.materialAdded');
			_layerAdded		= new Signal('AssetsLibrary.layerAdded');
		}

		public function get layerAdded() : Signal
		{
			return _layerAdded;
		}

		public function get materialAdded() : Signal
		{
			return _materialAdded;
		}

		public function get textureAdded() : Signal
		{
			return _textureAdded;
		}

		public function get geometryAdded() : Signal
		{
			return _geometryAdded;
		}

		public function setGeometry(name : String, geometry : Geometry) : void
		{
			if (_geometryList.indexOf(geometry) == -1)
			{
				++_numGeometries;
				_geometryList.push(geometry);
				_geometries[name] = geometry;
				_geometryAdded.execute(this, name, geometry);
			}
		}

		public function setTexture(name : String, texture : TextureResource) : void
		{
			if (_textureList.indexOf(texture) == -1)
			{
				++_numTextures;
				_textureList.push(texture);
				_textures[name] = texture;
				_textureAdded.execute(this, name, texture);
			}
		}

		public function setMaterial(name : String, material : Material) : void
		{
			material ||= new BasicMaterial();
			name ||= material.name;

			if (_materialList.indexOf(material) == -1)
			{
				++_numMaterials;
				_materialList.push(material);
				_materials[name] = material;
				_materialAdded.execute(this, name, material);
			}
		}

		public function setLayer(name : String, layer : uint) : void
		{
			name ||= 'Layer_' + layer;
			_layers[layer] = name;
			_layerAdded.execute(this, name, layer);
		}

		public function getLayerTag(name : String, ... params) : uint
		{
			var tag	: uint	= 0;

			if (_nameToLayer[name])
			{
				tag |= 1 << _nameToLayer[name];
			}

			for each (name in params)
			{
				if (_nameToLayer[name])
				{
					tag |= 1 << _nameToLayer[name];
				}
			}

			return tag;
		}

		public function getLayerName(tag : uint) : String
		{
			var names	: Vector.<String>	= new <String>[];
			var name	: String 			= null;
			var i		: uint				= 0;

			for (i = 0; i < 32; ++i)
			{
				if (tag & (1 << i))
					names.push(_layers[i]);
			}
			name = names.join('|');

			return name;
		}

		public function merge(other : AssetsLibrary) : AssetsLibrary
		{
			var name	: String	= null;
			var i		: uint		= 0;

			for (name in other._geometries)
				setGeometry(name, other._geometries[name]);
			for (name in other._materials)
				setMaterial(name, other._materials[name]);
			for (name in other._textures)
				setTexture(name, other._textures[name]);
			for each (name in other._layers)
				setLayer(name, i++);

			return this;
		}
	}
}

package aerys.minko.type.loader
{
	import aerys.minko.render.geometry.Geometry;
	import aerys.minko.render.material.Material;
	import aerys.minko.render.material.basic.BasicMaterial;
	import aerys.minko.render.resource.texture.TextureResource;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.Signal;

	public final class AssetsLibrary
	{
		private var _numGeometries 	: uint 						= 0;
		private var _numMaterials	: uint 						= 0;
		private var _numTextures	: uint 						= 0;
		private var _numSymbols		: uint 						= 0;

		private var _geometryList	: Vector.<Geometry> 		= new Vector.<Geometry>();
		private var _materialList	: Vector.<Material> 		= new Vector.<Material>();
		private var _textureList	: Vector.<TextureResource> 	= new Vector.<TextureResource>();
		private var _symbolList		: Vector.<ISceneNode>		= new Vector.<ISceneNode>();

		private var _geometries		: Object;
		private var _symbols		: Object;
		private var _textures		: Object;
		private var _materials		: Object;
		private var _layers			: Vector.<String>;
		private var _nameToLayer	: Object;

		private var _geometryAdded	: Signal;
		private var _symbolAdded	: Signal;
		private var _textureAdded	: Signal;
		private var _materialAdded	: Signal;
		private var _layerAdded		: Signal;

		public function AssetsLibrary()
		{
			initialize();
			initializeSignals();
		}

		public function get numSymbols() : uint
		{
			return _numSymbols;
		}

		public function get numTextures() : uint
		{
			return _numTextures;
		}

		public function get numGeometries() : uint
		{
			return _numGeometries;
		}

		public function get numMaterials() : uint
		{
			return _numMaterials;
		}

		public function getSymbolAt(index : uint) : ISceneNode
		{
			return _symbolList[index];
		}

		public function getMaterialAt(index : uint): Material
		{
			return _materialList[index];
		}

		public function getGeometryAt(index : uint): Geometry
		{
			return _geometryList[index];
		}

		public function getTextureAt(index : uint): TextureResource
		{
			return _textureList[index];
		}

		public function getSymbolByName(name : String) : ISceneNode
		{
			return _symbols[name];
		}

		public function getMaterialByName(name : String) : Material
		{
			return _materials[name];
		}

		public function getTextureByName(name : String) : TextureResource
		{
			return _textures[name];
		}

		public function getGeometryByName(name : String) : Geometry
		{
			return _geometries[name];
		}

		private function initialize() : void
		{
			_geometries		= {};
			_textures		= {};
			_materials		= {};
			_symbols		= {};

			_layers			= new Vector.<String>(32, true);
			_layers[0]		= 'Default';
			for (var i : uint = 1; i < _layers.length; ++i)
				_layers[i]	= 'Layer_' + i;

			_nameToLayer	= {};
		}

		private function initializeSignals() : void
		{
			_geometryAdded	= new Signal('AssetsLibrary.geometryAdded');
			_textureAdded	= new Signal('AssetsLibrary.textureAdded');
			_materialAdded	= new Signal('AssetsLibrary.materialAdded');
			_layerAdded		= new Signal('AssetsLibrary.layerAdded');
			_symbolAdded	= new Signal('AssetsLibrary.symbolAdded');
		}

		public function get layerAdded() : Signal
		{
			return _layerAdded;
		}

		public function get materialAdded() : Signal
		{
			return _materialAdded;
		}

		public function get textureAdded() : Signal
		{
			return _textureAdded;
		}

		public function get geometryAdded() : Signal
		{
			return _geometryAdded;
		}

		public function get symbolAdded() : Signal
		{
			return _symbolAdded;
		}

		public function setSymbol(name : String, node : ISceneNode) : void
		{
			if (_symbolList.indexOf(node) == -1)
			{
				++_numSymbols;
				_symbolList.push(node);
				_symbols[name] = node;
				_symbolAdded.execute(this, name, node);
			}
		}

		public function setGeometry(name : String, geometry : Geometry) : void
		{
			if (_geometryList.indexOf(geometry) == -1)
			{
				++_numGeometries;
				_geometryList.push(geometry);
				_geometries[name] = geometry;
				_geometryAdded.execute(this, name, geometry);
			}
		}

		public function setTexture(name : String, texture : TextureResource) : void
		{
			if (_textureList.indexOf(texture) == -1)
			{
				++_numTextures;
				_textureList.push(texture);
				_textures[name] = texture;
				_textureAdded.execute(this, name, texture);
			}
		}

		public function setMaterial(name : String, material : Material) : void
		{
			material ||= new BasicMaterial();
			name ||= material.name;

			if (_materialList.indexOf(material) == -1)
			{
				++_numMaterials;
				_materialList.push(material);
				_materials[name] = material;
				_materialAdded.execute(this, name, material);
			}
		}

		public function setLayer(name : String, layer : uint) : void
		{
			name ||= 'Layer_' + layer;
			_layers[layer] = name;
			_layerAdded.execute(this, name, layer);
		}

		public function getLayerTag(name : String, ... params) : uint
		{
			var tag	: uint	= 0;

			if (_nameToLayer[name])
			{
				tag |= 1 << _nameToLayer[name];
			}

			for each (name in params)
			{
				if (_nameToLayer[name])
				{
					tag |= 1 << _nameToLayer[name];
				}
			}

			return tag;
		}

		public function getLayerName(tag : uint) : String
		{
			var names	: Vector.<String>	= new <String>[];
			var name	: String 			= null;
			var i		: uint				= 0;

			for (i = 0; i < 32; ++i)
			{
				if (tag & (1 << i))
					names.push(_layers[i]);
			}
			name = names.join('|');

			return name;
		}

		public function merge(other : AssetsLibrary) : AssetsLibrary
		{
			var name	: String	= null;
			var i		: uint		= 0;

			for (name in other._geometries)
				setGeometry(name, other._geometries[name]);
			for (name in other._materials)
				setMaterial(name, other._materials[name]);
			for (name in other._textures)
				setTexture(name, other._textures[name]);
			for each (name in other._layers)
				setLayer(name, i++);

			return this;
		}
	}
}

Add symbols

Add symbols


/*****************************************************
*
*  Copyright 2009 Adobe Systems Incorporated.  All Rights Reserved.
*
*****************************************************
*  The contents of this file are subject to the Mozilla Public License
*  Version 1.1 (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.mozilla.org/MPL/
*
*  Software distributed under the License is distributed on an "AS IS"
*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
*  License for the specific language governing rights and limitations
*  under the License.
*
*
*  The Initial Developer of the Original Code is Adobe Systems Incorporated.
*  Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems
*  Incorporated. All Rights Reserved.
*
*****************************************************/
package org.osmf.net.httpstreaming.flv
{
	import flash.utils.ByteArray;
	import flash.utils.IDataInput;
	import flash.utils.IDataOutput;

	[ExcludeClass]

	/**
	 * @private
	 */
  	public class FLVTag
	{
		// arguably these should move to their own class...
		public static const TAG_TYPE_AUDIO:int = 8;
		public static const TAG_TYPE_VIDEO:int = 9;
		public static const TAG_TYPE_SCRIPTDATAOBJECT:int = 18;

		// TODO: Do we call this "filtered" or "encrypted" or "DRM" or "protected"?
		public static const TAG_FLAG_ENCRYPTED:int = 0x20;
		public static const TAG_TYPE_ENCRYPTED_AUDIO:int = TAG_TYPE_AUDIO + TAG_FLAG_ENCRYPTED;
		public static const TAG_TYPE_ENCRYPTED_VIDEO:int = TAG_TYPE_VIDEO + TAG_FLAG_ENCRYPTED;
		public static const TAG_TYPE_ENCRYPTED_SCRIPTDATAOBJECT:int = TAG_TYPE_SCRIPTDATAOBJECT + TAG_FLAG_ENCRYPTED;

		// but these are good here...
		public static const TAG_HEADER_BYTE_COUNT:int = 11;
		public static const PREV_TAG_BYTE_COUNT:int = 4;

		public function FLVTag(type:int)
		{
			super();

			bytes = new ByteArray();
			bytes.length = TAG_HEADER_BYTE_COUNT;
			bytes[0] = type;
		}

		public function read(input:IDataInput):void
		{
			// Reads a complete Tag, overwriting type.
			readType(input);
			readRemainingHeader(input);
			readData(input);
			readPrevTag(input);
		}

		public function readType(input:IDataInput):void
		{
			if (input.bytesAvailable < 1)
			{
				throw new Error("FLVTag.readType() input too short");
			}

			input.readBytes(bytes, 0, 1);	// just the type field, 1 byte
		}

		public function readRemaining(input:IDataInput):void
		{
			// Note that the TYPE must have already been read in order to
			// construct us.
			readRemainingHeader(input);
			readData(input);
			readPrevTag(input);
		}

		public function readRemainingHeader(input:IDataInput):void
		{
			if (input.bytesAvailable < 10)
			{
				throw new Error("FLVTag.readHeader() input too short");
			}

			input.readBytes(bytes, 1, TAG_HEADER_BYTE_COUNT - 1);	// skipping type field at first byte
		}

		public function readData(input:IDataInput):void
		{
			if (dataSize > 0)
			{
				if (input.bytesAvailable < dataSize)
				{
					throw new Error("FLVTag().readData input shorter than dataSize");
				}

				input.readBytes(bytes, TAG_HEADER_BYTE_COUNT, dataSize); // starting immediately after header, for computed size
			}
		}

		public function readPrevTag(input:IDataInput):void
		{
			if (input.bytesAvailable < 4)
			{
				throw new Error("FLVTag.readPrevTag() input too short");
			}

			input.readUnsignedInt();	// discard, because we can regenerate and we also don't care if value is correct
		}

		public function write(output:IDataOutput):void
		{
			output.writeBytes(bytes, 0, TAG_HEADER_BYTE_COUNT + dataSize);
			output.writeUnsignedInt(TAG_HEADER_BYTE_COUNT + dataSize); // correct prevTagSize, even though many things don't care
		}

		public function get tagType():uint
		{
			return bytes[0];
		}

		public function set tagType(value:uint):void
		{
			bytes[0] = value;
		}

		public function get isEncrpted():Boolean
		{
			return((bytes[0] & TAG_FLAG_ENCRYPTED) ? true : false);
		}

		public function get dataSize():uint
		{
			return (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]);
		}

		public function set dataSize(value:uint):void
		{
			bytes[1] = (value >> 16) & 0xff;
			bytes[2] = (value >> 8) & 0xff;
			bytes[3] = (value) & 0xff;
			bytes.length = TAG_HEADER_BYTE_COUNT + value;	// truncate/grow as necessary
		}

		public function get timestamp():uint
		{
			// noting the unusual order
			return (bytes[7] << 24) | (bytes[4] << 16) | (bytes[5] << 8) | (bytes[6]);
		}

		private var _cachedTimestamp:Number = -1;

		public function get cachedTimestamp():uint
		{
			if(_cachedTimestamp == -1)
				_cachedTimestamp = timestamp;
			return _cachedTimestamp;
		}

		public function set timestamp(value:uint):void
		{
			bytes[7] = (value >> 24) & 0xff; // extended byte in unusual location
			bytes[4] = (value >> 16) & 0xff;
			bytes[5] = (value >> 8) & 0xff;
			bytes[6] = (value) & 0xff;
			_cachedTimestamp = -1;
		}

		public function get data():ByteArray
		{
			var data:ByteArray = new ByteArray();
			data.writeBytes(bytes, TAG_HEADER_BYTE_COUNT, dataSize);
			return data;
		}

		public function set data(value:ByteArray):void
		{
			_cachedTimestamp = -1;
			bytes.length = TAG_HEADER_BYTE_COUNT + value.length;	// resize first
			bytes.position = TAG_HEADER_BYTE_COUNT;
			bytes.writeBytes(value, 0, value.length); // copy in
			dataSize = value.length;	// set dataSize field to new payload length
		}
		protected var bytes:ByteArray = null;
	}
}

/*****************************************************
*
*  Copyright 2009 Adobe Systems Incorporated.  All Rights Reserved.
*
*****************************************************
*  The contents of this file are subject to the Mozilla Public License
*  Version 1.1 (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.mozilla.org/MPL/
*
*  Software distributed under the License is distributed on an "AS IS"
*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
*  License for the specific language governing rights and limitations
*  under the License.
*
*
*  The Initial Developer of the Original Code is Adobe Systems Incorporated.
*  Portions created by Adobe Systems Incorporated are Copyright (C) 2009 Adobe Systems
*  Incorporated. All Rights Reserved.
*
*****************************************************/
package org.osmf.net.httpstreaming.flv
{
	import flash.utils.ByteArray;
	import flash.utils.IDataInput;
	import flash.utils.IDataOutput;

	[ExcludeClass]

	/**
	 * @private
	 */
  	public class FLVTag
	{
		// arguably these should move to their own class...
		public static const TAG_TYPE_AUDIO:int = 8;
		public static const TAG_TYPE_VIDEO:int = 9;
		public static const TAG_TYPE_SCRIPTDATAOBJECT:int = 18;

		// TODO: Do we call this "filtered" or "encrypted" or "DRM" or "protected"?
		public static const TAG_FLAG_ENCRYPTED:int = 0x20;
		public static const TAG_TYPE_ENCRYPTED_AUDIO:int = TAG_TYPE_AUDIO + TAG_FLAG_ENCRYPTED;
		public static const TAG_TYPE_ENCRYPTED_VIDEO:int = TAG_TYPE_VIDEO + TAG_FLAG_ENCRYPTED;
		public static const TAG_TYPE_ENCRYPTED_SCRIPTDATAOBJECT:int = TAG_TYPE_SCRIPTDATAOBJECT + TAG_FLAG_ENCRYPTED;

		// but these are good here...
		public static const TAG_HEADER_BYTE_COUNT:int = 11;
		public static const PREV_TAG_BYTE_COUNT:int = 4;

		public function FLVTag(type:int)
		{
			super();

			bytes = new ByteArray();
			bytes.length = TAG_HEADER_BYTE_COUNT;
			bytes[0] = type;
		}

		public function read(input:IDataInput):void
		{
			// Reads a complete Tag, overwriting type.
			readType(input);
			readRemainingHeader(input);
			readData(input);
			readPrevTag(input);
		}

		public function readType(input:IDataInput):void
		{
			if (input.bytesAvailable < 1)
			{
				throw new Error("FLVTag.readType() input too short");
			}

			input.readBytes(bytes, 0, 1);	// just the type field, 1 byte
		}

		public function readRemaining(input:IDataInput):void
		{
			// Note that the TYPE must have already been read in order to
			// construct us.
			readRemainingHeader(input);
			readData(input);
			readPrevTag(input);
		}

		public function readRemainingHeader(input:IDataInput):void
		{
			if (input.bytesAvailable < 10)
			{
				throw new Error("FLVTag.readHeader() input too short");
			}

			input.readBytes(bytes, 1, TAG_HEADER_BYTE_COUNT - 1);	// skipping type field at first byte
		}

		public function readData(input:IDataInput):void
		{
			if (dataSize > 0)
			{
				if (input.bytesAvailable < dataSize)
				{
					throw new Error("FLVTag().readData input shorter than dataSize");
				}

				input.readBytes(bytes, TAG_HEADER_BYTE_COUNT, dataSize); // starting immediately after header, for computed size
			}
		}

		public function readPrevTag(input:IDataInput):void
		{
			if (input.bytesAvailable < 4)
			{
				throw new Error("FLVTag.readPrevTag() input too short");
			}

			input.readUnsignedInt();	// discard, because we can regenerate and we also don't care if value is correct
		}

		public function write(output:IDataOutput):void
		{
			output.writeBytes(bytes, 0, TAG_HEADER_BYTE_COUNT + dataSize);
			output.writeUnsignedInt(TAG_HEADER_BYTE_COUNT + dataSize); // correct prevTagSize, even though many things don't care
		}

		public function get tagType():uint
		{
			return bytes[0];
		}

		public function set tagType(value:uint):void
		{
			bytes[0] = value;
		}

		public function get isEncrpted():Boolean
		{
			return((bytes[0] & TAG_FLAG_ENCRYPTED) ? true : false);
		}

		public function get dataSize():uint
		{
			return (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]);
		}

		public function set dataSize(value:uint):void
		{
			bytes[1] = (value >> 16) & 0xff;
			bytes[2] = (value >> 8) & 0xff;
			bytes[3] = (value) & 0xff;
			bytes.length = TAG_HEADER_BYTE_COUNT + value;	// truncate/grow as necessary
		}

		public function get timestamp():uint
		{
			// noting the unusual order
			return (bytes[7] << 24) | (bytes[4] << 16) | (bytes[5] << 8) | (bytes[6]);
		}

		public function set timestamp(value:uint):void
		{
			bytes[7] = (value >> 24) & 0xff; // extended byte in unusual location
			bytes[4] = (value >> 16) & 0xff;
			bytes[5] = (value >> 8) & 0xff;
			bytes[6] = (value) & 0xff;
		}

		public function get data():ByteArray
		{
			var data:ByteArray = new ByteArray();
			data.writeBytes(bytes, TAG_HEADER_BYTE_COUNT, dataSize);
			return data;
		}

		public function set data(value:ByteArray):void
		{
			bytes.length = TAG_HEADER_BYTE_COUNT + value.length;	// resize first
			bytes.position = TAG_HEADER_BYTE_COUNT;
			bytes.writeBytes(value, 0, value.length); // copy in
			dataSize = value.length;	// set dataSize field to new payload length
		}
		protected var bytes:ByteArray = null;
	}
}

Revert changes to OSMF.

Revert changes to OSMF.


/**
  * LFCApplication.as
  *
  * @copyright Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.
  *            Use is subject to license terms.
  *
  * @topic Kernel
  * @subtopic swf9
  * @author Henry Minsky <hminsky@laszlosystems.com>
  */

public class LFCApplication extends Sprite {

    // This serves as the superclass of DefaultApplication, currently that is where
    // the compiler puts top level code to run.

    #passthrough (toplevel:true) {
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;
    import flash.text.*;
    import flash.system.*;
    import flash.net.*;
    import flash.ui.*;
    import flash.text.Font;
    }#

    // Allow anyone access to the stage object (see ctor below)
    public static var stage:Stage = null;

    // Allow anyone access to write to the debugger
    public static var write:Function;

    public function LFCApplication () {

        // Allow anyone to access the stage object
        LFCApplication.stage = this.stage;
        LFCApplication.write = this.write;

        // trace("LFCApplication.stage = " + LFCApplication.stage);
        // trace("  loaderInfo.loaderURL = " + LFCApplication.stage.loaderInfo.loaderURL);

        var idleTimerPeriod = 14; // msecs

        //trace('idle timer period = ', idleTimerPeriod , 'msecs');
        LzIdleKernel.startTimer( idleTimerPeriod );

        stage.addEventListener(KeyboardEvent.KEY_DOWN,reportKeyDown);
        stage.addEventListener(KeyboardEvent.KEY_UP,reportKeyUp);

        // necessary for consistent behavior - in netscape browsers HTML is ignored
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
        //Stage.align = ('canvassalign' in global && global.canvassalign != null) ? global.canvassalign : "LT";
        //Stage.scaleMode = ('canvasscale' in global && global.canvasscale != null) ? global.canvasscale : "noScale";

        stage.addEventListener(Event.RESIZE, resizeHandler);

        // Register for callbacks from the kernel
        LzMouseKernel.setCallback(LzModeManager, 'rawMouseEvent');

        /* TODO [hqm 2008-01] Do we want to do anything with other
         * events, like click, or mousewheel ?

           stage.addEventListener(MouseEvent.CLICK, reportClick);
           stage.addEventListener(MouseEvent.MOUSE_WHEEL, reportWheel);
        */

        LzKeyboardKernel.setCallback(LzKeys, '__keyEvent');

        ////////////////////////////////////////////////////////////////
        // cheapo debug console
        lzconsole = this;
        var tfield:TextField = new TextField();
        tfield.background = true;
        tfield.backgroundColor = 0xcccccc;
        tfield.x = 0;
        tfield.y = 400;
        tfield.wordWrap = true;
        tfield.multiline = true;
        tfield.width = 800;
        tfield.height = 160;
        tfield.border = true;
        consoletext = tfield;

        var ci:TextField =  new TextField();
        consoleinputtext = ci;
        ci.background = true;
        ci.backgroundColor = 0xffcccc;
        ci.x = 0;
        ci.y = 560;
        ci.wordWrap = false;
        ci.multiline = false;
        ci.width = 800;
        ci.height = 20;
        ci.border = true;
        ci.type = TextFieldType.INPUT;
        ci.addEventListener(KeyboardEvent.KEY_DOWN, consoleInputHandler);

        /*        var allFonts:Array = Font.enumerateFonts(true);
        allFonts.sortOn("fontName", Array.CASEINSENSITIVE);

        var embeddedFonts:Array = Font.enumerateFonts(false);
        embeddedFonts.sortOn("fontName", Array.CASEINSENSITIVE);

        */

        var newFormat:TextFormat = new TextFormat();
        newFormat.size = 11;
        newFormat.font = "Verdana";
        ci.defaultTextFormat = newFormat;
        consoletext.defaultTextFormat = newFormat;

        ////////////////////////////////////////////////////////////////

        ////////////////////////////////////////////////////////////////
        // Testing runtime code loading
        ////////////////////////////////////////////////////////////////

    }

    var debugloader:Loader;

    // Debugger loader completion handler
    function debugEvalListener (e:Event):void {
        debugloader.unload();
        //DebugExec(e.target.content).doit();
    }

    function consoleInputHandler (event:KeyboardEvent ){
        if (event.charCode == Keyboard.ENTER) {
            var expr = consoleinputtext.text;
            write(expr);
            consoleinputtext.text = "";

            debugloader = new Loader();
            debugloader.contentLoaderInfo.addEventListener(Event.INIT, debugEvalListener);

            // Send EVAL request to LPS server
            // It doesn't matter what path/filename we use, as long as it has ".lzx" suffix, so it is
            // handled by the LPS. The lzt=eval causes the request to be served by the EVAL Responder.
            var url = "hello.lzx?lzr=swf9&lz_load=false&lzt=eval&lz_script=" + encodeURIComponent(expr)+"&lzbc=" +(new Date()).getTime();
            debugloader.load(new URLRequest(url),
                             new LoaderContext(false,
                                               new ApplicationDomain(ApplicationDomain.currentDomain)));
        }
    }

    ////////////////////////////////////////////////////////////////
    // A crude debugger output window for now
    public var consoletext:TextField;
    public var consoleinputtext:TextField;

    public function write (...args) {
        consoletext.appendText( "\n" + args.join(" "));
        consoletext.scrollV = consoletext.maxScrollV;
    }
    ////////////////////////////////////////////////////////////////

    function reportWheel(event:MouseEvent):void {
        /*
        Debug.write(event.currentTarget.toString() +
              " dispatches MouseWheelEvent. delta = " + event.delta); */
        LzKeys.__mousewheelEvent(event.delta);
    }

    function resizeHandler(event:Event):void {
        //trace('LFCApplication.resizeHandler stage width/height = ', stage.stageWidth, stage.stageHeight);
        LzScreenKernel.handleResizeEvent();
    }

    function reportKeyUp(event:KeyboardEvent):void {
        /*
          trace("Key Released: " + String.fromCharCode(event.charCode) +
              " (key code: " + event.keyCode + " character code: " +
              event.charCode + ")");
        */
        LzKeyboardKernel.__keyboardEvent(event.charCode, 'onkeyup');
    }

    function reportKeyDown(event:KeyboardEvent):void {
        /*
          trace("Key Pressed: " + String.fromCharCode(event.charCode) +
              " (key code: " + event.keyCode + " character code: "
              + event.charCode + ")");
        */
        LzKeyboardKernel.__keyboardEvent(event.charCode, 'onkeydown');
    }
}

// Resource library
// contains {ptype, class, frames, width, height}
// ptype is one of "ar" (app relative) or "sr" (system relative)
var LzResourceLibrary = {};
var lzconsole;

/**
  * LFCApplication.as
  *
  * @copyright Copyright 2007, 2008 Laszlo Systems, Inc.  All Rights Reserved.
  *            Use is subject to license terms.
  *
  * @topic Kernel
  * @subtopic swf9
  * @author Henry Minsky <hminsky@laszlosystems.com>
  */

public class LFCApplication extends Sprite {

    // This serves as the superclass of DefaultApplication, currently that is where
    // the compiler puts top level code to run.

    #passthrough (toplevel:true) {
    import flash.display.*;
    import flash.events.*;
    import flash.utils.*;
    import flash.text.*;
    import flash.system.*;
    import flash.net.*;
    import flash.ui.*;
    import flash.text.Font;
    }#

    // Allow anyone access to the stage object (see ctor below)
    public static var stage:Stage = null;

    // Allow anyone access to write to the debugger
    public static var write:Function;

    public function LFCApplication () {

        // Allow anyone to access the stage object
        LFCApplication.stage = this.stage;
        LFCApplication.write = this.write;

        // trace("LFCApplication.stage = " + LFCApplication.stage);
        // trace("  loaderInfo.loaderURL = " + LFCApplication.stage.loaderInfo.loaderURL);

        var idleTimerPeriod = 14; // msecs

        //trace('idle timer period = ', idleTimerPeriod , 'msecs');
        LzIdleKernel.startTimer( idleTimerPeriod );

        stage.addEventListener(KeyboardEvent.KEY_DOWN,reportKeyDown);
        stage.addEventListener(KeyboardEvent.KEY_UP,reportKeyUp);

        // necessary for consistent behavior - in netscape browsers HTML is ignored
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;
        //Stage.align = ('canvassalign' in global && global.canvassalign != null) ? global.canvassalign : "LT";
        //Stage.scaleMode = ('canvasscale' in global && global.canvasscale != null) ? global.canvasscale : "noScale";

        stage.addEventListener(Event.RESIZE, resizeHandler);

        // Register for callbacks from the kernel
        LzMouseKernel.setCallback(LzModeManager, 'rawMouseEvent');

        /* TODO [hqm 2008-01] Do we want to do anything with other
         * events, like click, or mousewheel ?

           stage.addEventListener(MouseEvent.CLICK, reportClick);
           stage.addEventListener(MouseEvent.MOUSE_WHEEL, reportWheel);
        */

        LzKeyboardKernel.setCallback(LzKeys, '__keyEvent');

        ////////////////////////////////////////////////////////////////
        // cheapo debug console
        lzconsole = this;
        var tfield:TextField = new TextField();
        tfield.visible = false;
        tfield.background = true;
        tfield.backgroundColor = 0xcccccc;
        tfield.x = 0;
        tfield.y = 400;
        tfield.wordWrap = true;
        tfield.multiline = true;
        tfield.width = 800;
        tfield.height = 160;
        tfield.border = true;
        consoletext = tfield;

        var ci:TextField =  new TextField();
        consoleinputtext = ci;
        ci.visible = false;
        ci.background = true;
        ci.backgroundColor = 0xffcccc;
        ci.x = 0;
        ci.y = 560;
        ci.wordWrap = false;
        ci.multiline = false;
        ci.width = 800;
        ci.height = 20;
        ci.border = true;
        ci.type = TextFieldType.INPUT;
        ci.addEventListener(KeyboardEvent.KEY_DOWN, consoleInputHandler);

        /*        var allFonts:Array = Font.enumerateFonts(true);
        allFonts.sortOn("fontName", Array.CASEINSENSITIVE);

        var embeddedFonts:Array = Font.enumerateFonts(false);
        embeddedFonts.sortOn("fontName", Array.CASEINSENSITIVE);

        */

        var newFormat:TextFormat = new TextFormat();
        newFormat.size = 11;
        newFormat.font = "Verdana";
        ci.defaultTextFormat = newFormat;
        consoletext.defaultTextFormat = newFormat;

        ////////////////////////////////////////////////////////////////

        ////////////////////////////////////////////////////////////////
        // Testing runtime code loading
        ////////////////////////////////////////////////////////////////

    }

    var debugloader:Loader;

    // Debugger loader completion handler
    function debugEvalListener (e:Event):void {
        debugloader.unload();
        //DebugExec(e.target.content).doit();
    }

    function consoleInputHandler (event:KeyboardEvent ){
        if (event.charCode == Keyboard.ENTER) {
            var expr = consoleinputtext.text;
            write(expr);
            consoleinputtext.text = "";

            debugloader = new Loader();
            debugloader.contentLoaderInfo.addEventListener(Event.INIT, debugEvalListener);

            // Send EVAL request to LPS server
            // It doesn't matter what path/filename we use, as long as it has ".lzx" suffix, so it is
            // handled by the LPS. The lzt=eval causes the request to be served by the EVAL Responder.
            var url = "hello.lzx?lzr=swf9&lz_load=false&lzt=eval&lz_script=" + encodeURIComponent(expr)+"&lzbc=" +(new Date()).getTime();
            debugloader.load(new URLRequest(url),
                             new LoaderContext(false,
                                               new ApplicationDomain(ApplicationDomain.currentDomain)));
        }
    }

    ////////////////////////////////////////////////////////////////
    // A crude debugger output window for now
    public var consoletext:TextField;
    public var consoleinputtext:TextField;

    public function write (...args) {
        consoletext.visible = true;
        consoleinputtext.visible = true;
        consoletext.appendText( "\n" + args.join(" "));
        consoletext.scrollV = consoletext.maxScrollV;
    }
    ////////////////////////////////////////////////////////////////

    function reportWheel(event:MouseEvent):void {
        /*
        Debug.write(event.currentTarget.toString() +
              " dispatches MouseWheelEvent. delta = " + event.delta); */
        LzKeys.__mousewheelEvent(event.delta);
    }

    function resizeHandler(event:Event):void {
        //trace('LFCApplication.resizeHandler stage width/height = ', stage.stageWidth, stage.stageHeight);
        LzScreenKernel.handleResizeEvent();
    }

    function reportKeyUp(event:KeyboardEvent):void {
        /*
          trace("Key Released: " + String.fromCharCode(event.charCode) +
              " (key code: " + event.keyCode + " character code: " +
              event.charCode + ")");
        */
        LzKeyboardKernel.__keyboardEvent(event.charCode, 'onkeyup');
    }

    function reportKeyDown(event:KeyboardEvent):void {
        /*
          trace("Key Pressed: " + String.fromCharCode(event.charCode) +
              " (key code: " + event.keyCode + " character code: "
              + event.charCode + ")");
        */
        LzKeyboardKernel.__keyboardEvent(event.charCode, 'onkeydown');
    }
}

// Resource library
// contains {ptype, class, frames, width, height}
// ptype is one of "ar" (app relative) or "sr" (system relative)
var LzResourceLibrary = {};
var lzconsole;

Change 20080429-maxcarlson-I by maxcarlson@Roboto on 2008-04-29 10:54:55 PDT
    in /Users/maxcarlson/openlaszlo/trunk-clean
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: Hide the swf9 debugger until messages need to be shown

New Features:

Bugs Fixed:

Technical Reviewer: hminsky
QA Reviewer: promanik
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details: Hide debugger text and inputtext  until write() is called.

Tests: The debugger text and inputtext start hidden, until write() is called.

git-svn-id: d62bde4b5aa582fdf07c8d403e53e0399a7ed285@8902 fa20e4f9-1d0a-0410-b5f3-dc9c16b8b17c


package krewfw.starling_utility {

    import flash.geom.Point;
    import starling.display.Image;
    import starling.textures.Texture;

    /**
     * Tiled Map Editor (http://www.mapeditor.org/) の tmx ファイルから
     * 出力した json をもとに各マスの Image を返すユーティリティ
     */
    //------------------------------------------------------------
    public class TileMapHelper {

        // avoid instantiation cost
        private static var _point:Point = new Point(0, 0);

        /**
         * Tiled Map Editor で出力した json による Object を使って、
         * 指定されたマスに対応するテクスチャを持つ Image を返す。
         * orientation: "orthogonal" 専用。spacing に対応.
         *
         * Tiled Map Editor では空タイルは 0 と表現される。
         * ソースのタイル画像の一番左上は 1 から始まる。
         * 指定したマスが 0 の場合は null を返す.
         *
         * [Note] 以下のタイル画像のフォーマットでテスト：
         * <pre>
         *     - Canvas size: 512 x 512
         *     - Tile size: 32 x 32
         *     - spacing: 2
         * </pre>
         */
        public static function getTileImage(tileMapInfo:Object, tileLayer:Object, tileSet:Object,
                                            tilesTexture:Texture, col:uint, row:uint):Image
        {
            // calculate UV coord
            var numMapCol:uint = tileLayer.width;
            var tileIndex:int  = tileLayer.data[(row * numMapCol) + col] - 1;
            if (tileIndex < 0) { return null; }

            // * consider spacing
            var tileWidth :Number = (tileSet.tilewidth  + tileSet.spacing);
            var tileHeight:Number = (tileSet.tileheight + tileSet.spacing);

            var numTileImageCol:uint = tileSet.imagewidth  / tileWidth;
            var numTileImageRow:uint = tileSet.imageheight / tileHeight;
            var tileImageCol:uint = tileIndex % numTileImageCol;
            var tileImageRow:uint = tileIndex / numTileImageCol;

            var uvLeft:Number = (tileWidth  * tileImageCol) / tileSet.imagewidth;
            var uvTop :Number = (tileHeight * tileImageRow) / tileSet.imageheight;
            var uvSize:Number = tileSet.tilewidth / tileSet.imagewidth;

            // make Image with UV
            var image:Image = new Image(tilesTexture);
            image.width  = tileMapInfo.tilewidth;
            image.height = tileMapInfo.tileheight;

            _point.setTo(uvLeft,          uvTop         );  image.setTexCoords(0, _point);
            _point.setTo(uvLeft + uvSize, uvTop         );  image.setTexCoords(1, _point);
            _point.setTo(uvLeft,          uvTop + uvSize);  image.setTexCoords(2, _point);
            _point.setTo(uvLeft + uvSize, uvTop + uvSize);  image.setTexCoords(3, _point);

            var padding:Number = 0.0005;  // そのまま UV 指定するとタイル間にわずかな隙間が見えてしまったので
            _setUv(image, 0, uvLeft         , uvTop         ,  padding,  padding);
            _setUv(image, 1, uvLeft + uvSize, uvTop         , -padding,  padding);
            _setUv(image, 2, uvLeft         , uvTop + uvSize,  padding, -padding);
            _setUv(image, 3, uvLeft + uvSize, uvTop + uvSize, -padding, -padding);

            return image;
        }

        /**
         * vertices index:
         *   0 - 1
         *   | / |
         *   2 - 3
         */
        private static function _setUv(image:Image, vertexId:int, x:Number, y:Number,
                                       paddingX:Number=0, paddingY:Number=0):void
        {
            _point.setTo(x + paddingX, y + paddingY);
            image.setTexCoords(vertexId, _point);
        }

    }
}

package krewfw.starling_utility {

    import flash.geom.Point;
    import starling.display.Image;
    import starling.textures.Texture;

    import krewfw.utility.KrewUtil;

    /**
     * Tiled Map Editor (http://www.mapeditor.org/) の tmx ファイルから
     * 出力した json をもとに各マスの Image を返すユーティリティ
     */
    //------------------------------------------------------------
    public class TileMapHelper {

        // avoid instantiation cost
        private static var _point:Point = new Point(0, 0);

        /**
         * Tiled Map Editor で出力した json の Object から、
         * 名前でレイヤーのデータを取得する。名前がヒットしなかった場合は null を返す
         */
        public static function getLayerByName(tileMapInfo:Object, layerName:String):Object {
            for each (var layerData:Object in tileMapInfo.layers) {
                if (layerData.name == layerName) {
                    return layerData;
                }
            }
            KrewUtil.fwlog("[TileMapHelpr] Layer not found: " + layerName);
            return null;
        }

        /**
         * Tiled Map Editor で出力した json による Object を使って、
         * 指定されたマスに対応するテクスチャを持つ Image を返す。
         * orientation: "orthogonal" 専用。spacing に対応.
         *
         * Tiled Map Editor では空タイルは 0 と表現される。
         * ソースのタイル画像の一番左上は 1 から始まる。
         * 指定したマスが 0 の場合は null を返す.
         *
         * [Note] 以下のタイル画像のフォーマットでテスト：
         * <pre>
         *     - Canvas size: 512 x 512
         *     - Tile size: 32 x 32
         *     - spacing: 2
         * </pre>
         */
        public static function getTileImage(tileMapInfo:Object, tileLayer:Object, tileSet:Object,
                                            tilesTexture:Texture, col:uint, row:uint):Image
        {
            // calculate UV coord
            var numMapCol:uint = tileLayer.width;
            var tileIndex:int  = tileLayer.data[(row * numMapCol) + col] - 1;
            if (tileIndex < 0) { return null; }

            // * consider spacing
            var tileWidth :Number = (tileSet.tilewidth  + tileSet.spacing);
            var tileHeight:Number = (tileSet.tileheight + tileSet.spacing);

            var numTileImageCol:uint = tileSet.imagewidth  / tileWidth;
            var numTileImageRow:uint = tileSet.imageheight / tileHeight;
            var tileImageCol:uint = tileIndex % numTileImageCol;
            var tileImageRow:uint = tileIndex / numTileImageCol;

            var uvLeft:Number = (tileWidth  * tileImageCol) / tileSet.imagewidth;
            var uvTop :Number = (tileHeight * tileImageRow) / tileSet.imageheight;
            var uvSize:Number = tileSet.tilewidth / tileSet.imagewidth;

            // make Image with UV
            var image:Image = new Image(tilesTexture);
            image.width  = tileMapInfo.tilewidth;
            image.height = tileMapInfo.tileheight;

            _point.setTo(uvLeft,          uvTop         );  image.setTexCoords(0, _point);
            _point.setTo(uvLeft + uvSize, uvTop         );  image.setTexCoords(1, _point);
            _point.setTo(uvLeft,          uvTop + uvSize);  image.setTexCoords(2, _point);
            _point.setTo(uvLeft + uvSize, uvTop + uvSize);  image.setTexCoords(3, _point);

            var padding:Number = 0.0005;  // そのまま UV 指定するとタイル間にわずかな隙間が見えてしまったので
            _setUv(image, 0, uvLeft         , uvTop         ,  padding,  padding);
            _setUv(image, 1, uvLeft + uvSize, uvTop         , -padding,  padding);
            _setUv(image, 2, uvLeft         , uvTop + uvSize,  padding, -padding);
            _setUv(image, 3, uvLeft + uvSize, uvTop + uvSize, -padding, -padding);

            return image;
        }

        /**
         * vertices index:
         *   0 - 1
         *   | / |
         *   2 - 3
         */
        private static function _setUv(image:Image, vertexId:int, x:Number, y:Number,
                                       paddingX:Number=0, paddingY:Number=0):void
        {
            _point.setTo(x + paddingX, y + paddingY);
            image.setTexCoords(vertexId, _point);
        }

    }
}

Resolve conflict

Resolve conflict


package aerys.minko.scene.controller
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.render.Viewport;
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.math.Matrix4x4;

	import flash.display.BitmapData;
	import flash.utils.Dictionary;

	use namespace minko_math;

	/**
	 * The TransformController handles the batched update of all the local to world matrices
	 * of a sub-scene. As such, it will only be active on the root node of a sub-scene and will
	 * automatically disable itself on other nodes.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class TransformController extends AbstractController
	{
		private var _target					: ISceneNode;

		private var _invalidList			: Boolean;

		private var _nodeToId				: Dictionary;
		private var _idToNode				: Vector.<ISceneNode>
		private var _transforms				: Vector.<Matrix4x4>;
		private var _localToWorldTransforms : Vector.<Matrix4x4>;
		private var _numChildren			: Vector.<uint>;
		private var _firstChildId			: Vector.<uint>;
		private var _parentId				: Vector.<int>;

		public function TransformController()
		{
			super();

			targetAdded.add(targetAddedHandler);
			targetRemoved.add(targetRemovedHandler);
		}

		private function renderingBeginHandler(scene			: Scene,
										  viewport		: Viewport,
										  destination	: BitmapData,
										  time			: Number) : void
		{
			if (_invalidList)
				updateTransformsList();

			if (_transforms.length)
			{
				var rootTransform 	: Matrix4x4	= _transforms[0];
				var isDirty			: Boolean	= rootTransform._hasChanged;

				if (isDirty)
				{
					_localToWorldTransforms[0].copyFrom(rootTransform);
					rootTransform._hasChanged = false;
				}

				updateLocalToWorld();
			}
		}

		private function updateLocalToWorld(nodeId : uint = 0) : void
		{
			var numNodes 		: uint 	= _transforms.length;
			var childrenOffset	: uint	= 1;

			for (; nodeId < numNodes; ++nodeId)
			{
				var localToWorld 	: Matrix4x4	= _localToWorldTransforms[nodeId];
				var numChildren		: uint		= _numChildren[nodeId];
				var isDirty			: Boolean	= localToWorld._hasChanged;
				var firstChildId	: uint		= _firstChildId[nodeId];
				var lastChildId		: uint		= firstChildId + numChildren;

				localToWorld._hasChanged = false;

				for (var childId : uint = firstChildId; childId < lastChildId; ++childId)
				{
					var childTransform		: Matrix4x4		= _transforms[childId];
					var childLocalToWorld	: Matrix4x4		= _localToWorldTransforms[childId];
					var childIsDirty		: Boolean		= isDirty || childTransform._hasChanged;

					if (childIsDirty)
					{
						var child	: ISceneNode	= _idToNode[childId];

						childLocalToWorld
							.copyFrom(childTransform)
							.append(localToWorld);

						childTransform._hasChanged = false;

						child.localToWorldTransformChanged.execute(child, childLocalToWorld);
					}
				}
			}
		}

		private function updateAncestorsAndSelfLocalToWorld(nodeId : int) : void
		{
			var dirtyRoot : int = nodeId;

			while (nodeId >= 0)
			{
				if ((_transforms[nodeId] as Matrix4x4)._hasChanged)
					dirtyRoot = nodeId;

				nodeId = _parentId[nodeId];
			}

			if (dirtyRoot >= 0)
				updateLocalToWorld(dirtyRoot);
		}

		private function targetAddedHandler(ctrl	: TransformController,
											target	: ISceneNode) : void
		{
			if (_target)
				throw new Error('The TransformController cannot have more than one target.');

			_target = target;
			_invalidList = true;

			if (target is Scene)
			{
				(target as Scene).renderingBegin.add(renderingBeginHandler);
				return;
			}

			if (target is Group)
			{
				var targetGroup : Group = target as Group;

				targetGroup.descendantAdded.add(descendantAddedHandler);
				targetGroup.descendantRemoved.add(descendantRemovedHandler);
			}

			target.added.add(addedHandler);
		}

		private function targetRemovedHandler(ctrl		: TransformController,
											  target	: ISceneNode) : void
		{
			target.added.remove(addedHandler);

			if (target is Group)
			{
				var targetGroup : Group = target as Group;

				targetGroup.descendantAdded.remove(descendantAddedHandler);
				targetGroup.descendantRemoved.remove(descendantRemovedHandler);
			}

			_invalidList = false;
			_target = null;

			_nodeToId = null;
			_transforms = null;
			_localToWorldTransforms = null;
			_numChildren = null;
			_idToNode = null;
			_parentId = null;
		}

		private function addedHandler(target : ISceneNode, ancestor : Group) : void
		{
			// the controller will remove itself from the node when it's not its own root anymore
			// but it will watch for the 'removed' signal to add itself back if the node becomes
			// its own root again
			_target.removed.add(removedHandler);
			_target.removeController(this);
		}

		private function removedHandler(target : ISceneNode, ancestor : Group) : void
		{
			if (target.root == target)
			{
				target.removed.remove(removedHandler);
				target.addController(this);
			}
		}

		private function descendantAddedHandler(root		: Group,
												descendant	: ISceneNode) : void
		{
			_invalidList = true;
		}

		private function descendantRemovedHandler(root			: Group,
												  descendant	: ISceneNode) : void
		{
			_invalidList = true;
		}

		private function updateTransformsList() : void
		{
			var root 	: ISceneNode 			= _target.root;
			var nodes 	: Vector.<ISceneNode> 	= new <ISceneNode>[root];
			var nodeId 	: uint 					= 0;

			_nodeToId = new Dictionary(true);
			_transforms = new <Matrix4x4>[];
			_localToWorldTransforms = new <Matrix4x4>[];
			_numChildren = new <uint>[];
			_firstChildId = new <uint>[];
			_idToNode = new <ISceneNode>[];
			_parentId = new <int>[-1];

			while (nodes.length)
			{
				var node 	: ISceneNode 	= nodes.shift();
				var group 	: Group 		= node as Group;

				_nodeToId[node] = nodeId;
				_idToNode[nodeId] = node;
				_transforms[nodeId] = node.transform;
				_localToWorldTransforms[nodeId] = new Matrix4x4().lock();

				if (group)
				{
					var numChildren 	: uint = group.numChildren;
					var firstChildId 	: uint = nodeId + nodes.length + 1;

					_numChildren[nodeId] = numChildren;
					_firstChildId[nodeId] = firstChildId;
					for (var childId : uint = 0; childId < numChildren; ++childId)
					{
						_parentId[uint(firstChildId + childId)] = nodeId;
						nodes.push(group.getChildAt(childId));
					}
				}
				else
				{
					_numChildren[nodeId] = 0;
					_firstChildId[nodeId] = 0;
				}

				++nodeId;
			}

			_invalidList = false;
		}

		public function getLocalToWorldTransform(node 			: ISceneNode,
												 forceUpdate 	: Boolean = false) : Matrix4x4
		{
			if (_invalidList || _nodeToId[node] == undefined)
				updateTransformsList();

			var nodeId : uint = _nodeToId[node];

			if (forceUpdate)
				updateAncestorsAndSelfLocalToWorld(nodeId);

			return _localToWorldTransforms[nodeId];
		}
	}
}

package aerys.minko.scene.controller
{
	import aerys.minko.ns.minko_math;
	import aerys.minko.render.Viewport;
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.math.Matrix4x4;

	import flash.display.BitmapData;
	import flash.utils.Dictionary;

	use namespace minko_math;

	/**
	 * The TransformController handles the batched update of all the local to world matrices
	 * of a sub-scene. As such, it will only be active on the root node of a sub-scene and will
	 * automatically disable itself on other nodes.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class TransformController extends AbstractController
	{
		private var _target					: ISceneNode;

		private var _invalidList			: Boolean;

		private var _nodeToId				: Dictionary;
		private var _idToNode				: Vector.<ISceneNode>
		private var _transforms				: Vector.<Matrix4x4>;
		private var _localToWorldTransforms : Vector.<Matrix4x4>;
        private var _worldToLocalTransforms : Vector.<Matrix4x4>;
		private var _numChildren			: Vector.<uint>;
		private var _firstChildId			: Vector.<uint>;
		private var _parentId				: Vector.<int>;

		public function TransformController()
		{
			super();

			targetAdded.add(targetAddedHandler);
			targetRemoved.add(targetRemovedHandler);
		}

		private function renderingBeginHandler(scene			: Scene,
										  viewport		: Viewport,
										  destination	: BitmapData,
										  time			: Number) : void
		{
			if (_invalidList)
				updateTransformsList();

			if (_transforms.length)
			{
				var rootTransform 	: Matrix4x4	= _transforms[0];
				var isDirty			: Boolean	= rootTransform._hasChanged;

				if (isDirty)
				{
					_localToWorldTransforms[0].copyFrom(rootTransform);
					rootTransform._hasChanged = false;
				}

				updateLocalToWorld();
			}
		}

		private function updateLocalToWorld(nodeId : uint = 0) : void
		{
			var numNodes 		: uint 	= _transforms.length;
			var childrenOffset	: uint	= 1;

			for (; nodeId < numNodes; ++nodeId)
			{
				var localToWorld 	: Matrix4x4	= _localToWorldTransforms[nodeId];
				var numChildren		: uint		= _numChildren[nodeId];
				var isDirty			: Boolean	= localToWorld._hasChanged;
				var firstChildId	: uint		= _firstChildId[nodeId];
				var lastChildId		: uint		= firstChildId + numChildren;

				localToWorld._hasChanged = false;

				for (var childId : uint = firstChildId; childId < lastChildId; ++childId)
				{
					var childTransform		: Matrix4x4		= _transforms[childId];
					var childLocalToWorld	: Matrix4x4		= _localToWorldTransforms[childId];
					var childIsDirty		: Boolean		= isDirty || childTransform._hasChanged;

					if (childIsDirty)
					{
						var child	: ISceneNode	= _idToNode[childId];

						childLocalToWorld
							.copyFrom(childTransform)
							.append(localToWorld);

						childTransform._hasChanged = false;

						child.localToWorldTransformChanged.execute(child, childLocalToWorld);
					}
				}
			}
		}

        private function getDirtyRoot(nodeId : int) : int
        {
            var dirtyRoot : int = nodeId;

            while (nodeId >= 0)
            {
                if ((_transforms[nodeId] as Matrix4x4)._hasChanged)
                    dirtyRoot = nodeId;

                nodeId = _parentId[nodeId];
            }

            return dirtyRoot;
        }

		private function targetAddedHandler(ctrl	: TransformController,
											target	: ISceneNode) : void
		{
			if (_target)
				throw new Error('The TransformController cannot have more than one target.');

			_target = target;
			_invalidList = true;

			if (target is Scene)
			{
				(target as Scene).renderingBegin.add(renderingBeginHandler);
				return;
			}

			if (target is Group)
			{
				var targetGroup : Group = target as Group;

				targetGroup.descendantAdded.add(descendantAddedHandler);
				targetGroup.descendantRemoved.add(descendantRemovedHandler);
			}

			target.added.add(addedHandler);
		}

		private function targetRemovedHandler(ctrl		: TransformController,
											  target	: ISceneNode) : void
		{
			target.added.remove(addedHandler);

			if (target is Group)
			{
				var targetGroup : Group = target as Group;

				targetGroup.descendantAdded.remove(descendantAddedHandler);
				targetGroup.descendantRemoved.remove(descendantRemovedHandler);
			}

			_invalidList = false;
			_target = null;

			_nodeToId = null;
			_transforms = null;
			_localToWorldTransforms = null;
            _worldToLocalTransforms = null;
			_numChildren = null;
			_idToNode = null;
			_parentId = null;
		}

		private function addedHandler(target : ISceneNode, ancestor : Group) : void
		{
			// the controller will remove itself from the node when it's not its own root anymore
			// but it will watch for the 'removed' signal to add itself back if the node becomes
			// its own root again
			_target.removed.add(removedHandler);
			_target.removeController(this);
		}

		private function removedHandler(target : ISceneNode, ancestor : Group) : void
		{
			if (target.root == target)
			{
				target.removed.remove(removedHandler);
				target.addController(this);
			}
		}

		private function descendantAddedHandler(root		: Group,
												descendant	: ISceneNode) : void
		{
			_invalidList = true;
		}

		private function descendantRemovedHandler(root			: Group,
												  descendant	: ISceneNode) : void
		{
			_invalidList = true;
		}

		private function updateTransformsList() : void
		{
			var root 	: ISceneNode 			= _target.root;
			var nodes 	: Vector.<ISceneNode> 	= new <ISceneNode>[root];
			var nodeId 	: uint 					= 0;

			_nodeToId = new Dictionary(true);
			_transforms = new <Matrix4x4>[];
			_localToWorldTransforms = new <Matrix4x4>[];
            _worldToLocalTransforms = new <Matrix4x4>[];
			_numChildren = new <uint>[];
			_firstChildId = new <uint>[];
			_idToNode = new <ISceneNode>[];
			_parentId = new <int>[-1];

			while (nodes.length)
			{
				var node 	: ISceneNode 	= nodes.shift();
				var group 	: Group 		= node as Group;

				_nodeToId[node] = nodeId;
				_idToNode[nodeId] = node;
				_transforms[nodeId] = node.transform;
				_localToWorldTransforms[nodeId] = new Matrix4x4().lock();

				if (group)
				{
					var numChildren 	: uint = group.numChildren;
					var firstChildId 	: uint = nodeId + nodes.length + 1;

					_numChildren[nodeId] = numChildren;
					_firstChildId[nodeId] = firstChildId;
					for (var childId : uint = 0; childId < numChildren; ++childId)
					{
						_parentId[uint(firstChildId + childId)] = nodeId;
						nodes.push(group.getChildAt(childId));
					}
				}
				else
				{
					_numChildren[nodeId] = 0;
					_firstChildId[nodeId] = 0;
				}

				++nodeId;
			}

            _worldToLocalTransforms.length = _localToWorldTransforms.length;
			_invalidList = false;
		}

		public function getLocalToWorldTransform(node 			: ISceneNode,
												 forceUpdate 	: Boolean = false) : Matrix4x4
		{
			if (_invalidList || _nodeToId[node] == undefined)
				updateTransformsList();

			var nodeId : uint = _nodeToId[node];

			if (forceUpdate)
            {
                var dirtyRoot : int = getDirtyRoot(nodeId);

                if (dirtyRoot >= 0)
                    updateLocalToWorld(dirtyRoot);
            }

			return _localToWorldTransforms[nodeId];
		}

        public function getWorldToLocalTransform(node           : ISceneNode,
                                                 forceUpdate    : Boolean   = false) : Matrix4x4
        {
            if (_invalidList || _nodeToId[node] == undefined)
                updateTransformsList();

            var nodeId                  : uint      = _nodeToId[node];
            var worldToLocalTransform   : Matrix4x4 = _worldToLocalTransforms[nodeId];

            if (!worldToLocalTransform)
            {
                _worldToLocalTransforms[nodeId] = worldToLocalTransform = new Matrix4x4();
                if (!forceUpdate)
                    worldToLocalTransform.copyFrom(_localToWorldTransforms[nodeId]).invert();
            }

            if (forceUpdate)
            {
                var dirtyRoot : int = getDirtyRoot(nodeId);

                if (dirtyRoot >= 0)
                {
                    updateLocalToWorld(dirtyRoot);

                    worldToLocalTransform
                        .copyFrom(_localToWorldTransforms[nodeId])
                        .invert();
                }
            }

            return worldToLocalTransform;
        }
	}
}

add TransformController.getWorldToLocalTransform() to get cached/lazy world to local transform


package {
	//Translation of Destructable class only.
	//(untested)

	import nape.geom.Vec2;
	import nape.phys.Body;
	import nape.geom.MarchingSquares;
	import nape.geom.GeomPoly;
	import nape.geom.GeomPolyList;
	import nape.shape.Polygon;

	public class Destructible {
		private static const granularity = new Vec2(5,5);

		static public function cut(body:Body, inside:Function):Vector.<Body> {
			var iso:Function = function(x:Number,y:Number):Number {
				var p:Vec2 = new Vec2(x,y);
				return (body.contains(p) && !inside(x,y)) ? -1.0 : 1.0;
			};

			var npolys:GeomPolyList = MarchingSquares.run(iso, body.bounds, granularity, 8);
			if(npolys.length==0) return new Vector.<Body>();

			body.shapes.clear();
			body.position.setxy(0,0);
			body.rotation = 0;

			if(npolys.length==1) {
				var qolys:GeomPolyList = npolys.at(0).convex_decomposition();
				qolys.foreach(function (q:GeomPoly):void {
					body.shapes.add(new Polygon(q));
				});

				body.align();

				return null;
			}else {
				var ret:Vector.<Body> = new Vector.<Body>();

				npolys.foreach(function (p:GeomPoly):void {
					var nbody:Body = body.copy();
					var qolys:GeomPolyList = p.convex_decomposition();
					qolys.foreach(function (q:GeomPoly):void {
						nbody.shapes.add(new Polygon(q));
					});
					nbody.align();
					ret.push(nbody);
				});

				return ret;
			}
		}
	}
}

add AS3 translation of Destructible in dynamic destruction demo


/*
#
# Copyright (c) 2007-2011 rPath, Inc.
#
# All rights reserved
#
*/

package com.rpath.xobj
{
import flash.utils.Dictionary;

import mx.collections.ArrayCollection;

public class XObjArrayCollection extends ArrayCollection implements IXObjCollection
{
    public function XObjArrayCollection(source:Array=null, typeMap:*=null)
    {
        super(source);

        if (!typeMap)
            this.type = {};

        this.type = typeMap;
    }

    // the type of objects we expect in the collection
    // null means unknown type. Can be a single Class
    // or a Dictionary of typeMap entries
    [xobjTransient]
    public function get type():*
    {
        return _type;
    }

    private var _type:*;

    public function set type(t:*):void
    {
        _type = t;
    }

    public function elementType():Class
    {
        return (type as Class);
    }

    public function typeMap():Dictionary
    {
        return (type as Dictionary);
    }

    public function elementTypeForElementName(name:String):Class
    {
        return XObjTypeMap.elementTypeForElementName(type, name);
    }

    public function elementTagForMember(member:*):String
    {
        return XObjTypeMap.elementTagForMember(type, member);
    }

    public function addItemIfAbsent(value:Object):Boolean
    {
        return XObjUtils.addItemIfAbsent(this, value);
    }

    public function removeItemIfPresent(object:Object):Boolean
    {
        return XObjUtils.removeItemIfPresent(this, public);
    }

    public function isElementMember(propName:String):Boolean
    {
       return XObjUtils.isElementMember(this, propName);
    }

    [xobjTransient]
    public function get isByReference():Boolean
    {
        return _isByReference;
    }

    private var _isByReference:Boolean;

    public function set isByReference(b:Boolean):void
    {
        _isByReference = b;
    }

}
}

/*
#
# Copyright (c) 2007-2011 rPath, Inc.
#
# All rights reserved
#
*/

package com.rpath.xobj
{
import flash.utils.Dictionary;

import mx.collections.ArrayCollection;

public class XObjArrayCollection extends ArrayCollection implements IXObjCollection
{
    public function XObjArrayCollection(source:Array=null, typeMap:*=null)
    {
        super(source);

        if (!typeMap)
            this.type = {};

        this.type = typeMap;
    }

    // the type of objects we expect in the collection
    // null means unknown type. Can be a single Class
    // or a Dictionary of typeMap entries
    [xobjTransient]
    public function get type():*
    {
        return _type;
    }

    private var _type:*;

    public function set type(t:*):void
    {
        _type = t;
    }

    public function elementType():Class
    {
        return (type as Class);
    }

    public function typeMap():Dictionary
    {
        return (type as Dictionary);
    }

    public function elementTypeForElementName(name:String):Class
    {
        return XObjTypeMap.elementTypeForElementName(type, name);
    }

    public function elementTagForMember(member:*):String
    {
        return XObjTypeMap.elementTagForMember(type, member);
    }

    public function addItemIfAbsent(value:Object):Boolean
    {
        if (getItemIndex(value) == -1)
        {
            addItem(value);
            return true;
        }
        return false;
    }

    public function removeItemIfPresent(object:Object):Boolean
    {
        return XObjUtils.removeItemIfPresent(this, object);
    }

    public function isElementMember(propName:String):Boolean
    {
       return XObjUtils.isElementMember(this, propName);
    }

    [xobjTransient]
    public function get isByReference():Boolean
    {
        return _isByReference;
    }

    private var _isByReference:Boolean;

    public function set isByReference(b:Boolean):void
    {
        _isByReference = b;
    }

}
}

Fix bug in new XObjArrayCollection class


package aerys.minko.type.loader.parser
{
	import aerys.minko.render.effect.Effect;
	import aerys.minko.type.loader.ILoader;
	import aerys.minko.type.loader.SceneLoader;
	import aerys.minko.type.loader.TextureLoader;

	import flash.net.URLRequest;

	/**
	 * ParserOptions objects provide properties and function references
	 * to customize how a LoaderGroup object will load and interpret
	 * content.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class ParserOptions
	{
		private var _loadDependencies			: Boolean	= false;
		private var _dependencyLoaderClosure	: Function	= defaultDependencyLoaderClosure;
        private var _loadSkin                   : Boolean   = false;
		private var _mipmapTextures				: Boolean	= true;
		private var _meshEffect					: Effect	= null;
		private var _vertexStreamUsage			: uint		= 0;
		private var _indexStreamUsage			: uint		= 0;
		private var _parser						: Class		= null;

		public function get parser() : Class
		{
			return _parser;
		}

		public function set parser(value : Class) : void
		{
			_parser = value;
		}

		public function get indexStreamUsage() : uint
		{
			return _indexStreamUsage;
		}

		public function set indexStreamUsage(value : uint) : void
		{
			_indexStreamUsage = value;
		}

		public function get vertexStreamUsage() : uint
		{
			return _vertexStreamUsage;
		}

		public function set vertexStreamUsage(value : uint) : void
		{
			_vertexStreamUsage = value;
		}

		public function get effect() : Effect
		{
			return _meshEffect;
		}

		public function set effect(value : Effect) : void
		{
			_meshEffect = value;
		}

		public function get mipmapTextures() : Boolean
		{
			return _mipmapTextures;
		}

		public function set mipmapTextures(value : Boolean) : void
		{
			_mipmapTextures = value;
		}

		public function get dependencyLoaderClosure() : Function
		{
			return _dependencyLoaderClosure;
		}

		public function set dependencyLoaderClosure(value : Function) : void
		{
			_dependencyLoaderClosure = value;
		}

		public function get loadDependencies() : Boolean
		{
			return _loadDependencies;
		}

		public function set loadDependencies(value : Boolean) : void
		{
			_loadDependencies = value;
		}

        public function get loadSkin() : Boolean
        {
            return _loadSkin;
        }

        public function set loadSkin(value : Boolean) : void
        {
            _loadSkin = value;
        }

		public function clone() : ParserOptions
		{
			return new ParserOptions(
				_loadDependencies,
				_dependencyLoaderClosure,
                _loadSkin,
				_mipmapTextures,
				_meshEffect,
				_vertexStreamUsage,
				_indexStreamUsage,
				_parser
			);
		}

		public function ParserOptions(loadDependencies			: Boolean 	= false,
									  dependencyLoaderClosure	: Function 	= null,
                                      loadSkin                  : Boolean 	= true,
									  mipmapTextures			: Boolean 	= true,
									  meshEffect				: Effect 	= null,
									  vertexStreamUsage			: uint 		= 0,
									  indexStreamUsage			: uint 		= 0,
									  parser					: Class 	= null)
		{
			_loadDependencies			= loadDependencies;
			_dependencyLoaderClosure	= dependencyLoaderClosure || _dependencyLoaderClosure;
            _loadSkin                   = loadSkin;
			_mipmapTextures				= mipmapTextures;
			_meshEffect					= meshEffect;
			_vertexStreamUsage			= vertexStreamUsage;
			_indexStreamUsage			= indexStreamUsage;
			_parser						= parser;
		}

		private function defaultDependencyLoaderClosure(dependencyPath	: String,
														isTexture		: Boolean,
														options			: ParserOptions) : ILoader
		{
			var loader : ILoader;

			if (isTexture)
			{
				loader = new TextureLoader(true);
				loader.load(new URLRequest(dependencyPath));
			}
			else
			{
				loader = new SceneLoader(options);
				loader.load(new URLRequest(dependencyPath));
			}

			return loader;
		}

    }
}

package aerys.minko.type.loader.parser
{
	import aerys.minko.render.effect.Effect;
	import aerys.minko.scene.node.mesh.Mesh;
	import aerys.minko.type.loader.ILoader;
	import aerys.minko.type.loader.SceneLoader;
	import aerys.minko.type.loader.TextureLoader;

	import flash.net.URLRequest;

	/**
	 * ParserOptions objects provide properties and function references
	 * to customize how a LoaderGroup object will load and interpret
	 * content.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public final class ParserOptions
	{
		private var _loadDependencies			: Boolean	= false;
		private var _dependencyLoaderClosure	: Function	= defaultDependencyLoaderClosure;
        private var _loadSkin                   : Boolean   = false;
		private var _mipmapTextures				: Boolean	= true;
		private var _meshEffect					: Effect	= null;
		private var _vertexStreamUsage			: uint		= 0;
		private var _indexStreamUsage			: uint		= 0;
		private var _parser						: Class		= null;

		public function get parser() : Class
		{
			return _parser;
		}

		public function set parser(value : Class) : void
		{
			_parser = value;
		}

		public function get indexStreamUsage() : uint
		{
			return _indexStreamUsage;
		}

		public function set indexStreamUsage(value : uint) : void
		{
			_indexStreamUsage = value;
		}

		public function get vertexStreamUsage() : uint
		{
			return _vertexStreamUsage;
		}

		public function set vertexStreamUsage(value : uint) : void
		{
			_vertexStreamUsage = value;
		}

		public function get effect() : Effect
		{
			return _meshEffect;
		}

		public function set effect(value : Effect) : void
		{
			_meshEffect = value;
		}

		public function get mipmapTextures() : Boolean
		{
			return _mipmapTextures;
		}

		public function set mipmapTextures(value : Boolean) : void
		{
			_mipmapTextures = value;
		}

		public function get dependencyLoaderClosure() : Function
		{
			return _dependencyLoaderClosure;
		}

		public function set dependencyLoaderClosure(value : Function) : void
		{
			_dependencyLoaderClosure = value;
		}

		public function get loadDependencies() : Boolean
		{
			return _loadDependencies;
		}

		public function set loadDependencies(value : Boolean) : void
		{
			_loadDependencies = value;
		}

        public function get loadSkin() : Boolean
        {
            return _loadSkin;
        }

        public function set loadSkin(value : Boolean) : void
        {
            _loadSkin = value;
        }

		public function clone() : ParserOptions
		{
			return new ParserOptions(
				_loadDependencies,
				_dependencyLoaderClosure,
                _loadSkin,
				_mipmapTextures,
				_meshEffect,
				_vertexStreamUsage,
				_indexStreamUsage,
				_parser
			);
		}

		public function ParserOptions(loadDependencies			: Boolean 	= false,
									  dependencyLoaderClosure	: Function 	= null,
                                      loadSkin                  : Boolean 	= true,
									  mipmapTextures			: Boolean 	= true,
									  meshEffect				: Effect 	= null,
									  vertexStreamUsage			: uint 		= 0,
									  indexStreamUsage			: uint 		= 0,
									  parser					: Class 	= null)
		{
			_loadDependencies			= loadDependencies;
			_dependencyLoaderClosure	= dependencyLoaderClosure || _dependencyLoaderClosure;
            _loadSkin                   = loadSkin;
			_mipmapTextures				= mipmapTextures;
			_meshEffect					= meshEffect || Mesh.DEFAULT_EFFECT;
			_vertexStreamUsage			= vertexStreamUsage;
			_indexStreamUsage			= indexStreamUsage;
			_parser						= parser;
		}

		private function defaultDependencyLoaderClosure(dependencyPath	: String,
														isTexture		: Boolean,
														options			: ParserOptions) : ILoader
		{
			var loader : ILoader;

			if (isTexture)
			{
				loader = new TextureLoader(true);
				loader.load(new URLRequest(dependencyPath));
			}
			else
			{
				loader = new SceneLoader(options);
				loader.load(new URLRequest(dependencyPath));
			}

			return loader;
		}

    }
}

use Mesh.DEFAULT_EFFECT as the fallback value for ParserOptions.effect


package aerys.minko.scene.controller
{
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.Signal;
	import aerys.minko.type.animation.TimeLabel;
	import aerys.minko.type.animation.timeline.ITimeline;

	import flash.utils.getTimer;

	/**
	 * The AnimationController uses timelines to animate properties of scene nodes.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public class AnimationController extends AbstractController
	{

		public function get currentTime():int
		{
			return _currentTime;
		}

		public function get isPlaying():Boolean
		{
			return _isPlaying;
		}

		public static var DEFAULT_TIME_FUNCTION	: Function = getTimer;

		private var _timelines		: Vector.<ITimeline>	= new Vector.<ITimeline>();
		private var _isPlaying		: Boolean				= false;
		private var _loopBeginTime	: int					= 0;
		private var _loopEndTime	: int					= 0;
		private var _looping		: Boolean				= true;
		private var _currentTime	: int					= 0;
		private var _totalTime		: int					= 0;

		private var _timeFunction	: Function				= DEFAULT_TIME_FUNCTION;
		private var _labels			: Vector.<TimeLabel>	= null;

		private var _lastTime		: Number				= 0;

		private var _looped			: Signal 				= new Signal();
		private var _started		: Signal				= new Signal();
		private var _stopped		: Signal				= new Signal();

		public function get started():Signal
		{
			return _started;
		}

		public function get stopped() : Signal
		{
			return _stopped;
		}

		public function get looped():Signal
		{
			return _looped;
		}

		public function get totalTime() : int
		{
			return _totalTime;
		}

		public function get looping() : Boolean
		{
			return _looping;
		}
		public function set looping(value : Boolean) : void
		{
			_looping = value;
		}

		public function get isPlaying():Boolean
		{
			return _isPlaying;
		}

		public function set isPlaying(value:Boolean):void
		{
			_isPlaying = value;
		}

		public function get currentTime():int
		{
			return _currentTime;
		}

		public function set currentTime(value:int):void
		{
			_currentTime = value;
		}

		public function AnimationController(timelines	: Vector.<ITimeline>)
		{
			super();

			_timelines = timelines;

			initialize();
		}

		public function getTimeline(index : uint = 0) : ITimeline
		{
			return _timelines[index];
		}

		private function initialize() : void
		{
			var numTimelines : uint = _timelines.length;

			for (var timelineId : uint = 0; timelineId < numTimelines; ++timelineId)
				if (_totalTime < _timelines[timelineId].duration)
					_totalTime = _timelines[timelineId].duration;

			setPlaybackWindow(0, _totalTime);
			gotoAndPlay(0);
		}

		public function gotoAndPlay(time : Object) : void
		{
			var timeValue : uint = getAnimationTime(time);

			if (timeValue < _loopBeginTime || timeValue > _loopEndTime)
				throw new Error('Time value is outside of playback window. To reset playback window, call resetPlaybackWindow.');

			_currentTime = timeValue;
			_lastTime = _timeFunction != null ? _timeFunction() : getTimer();
			play();
		}

		public function gotoAndStop(time : Object) : void
		{
			var timeValue : uint = getAnimationTime(time);

			if (timeValue < _loopBeginTime || timeValue > _loopEndTime)
				throw new Error('Time value is outside of playback window. To reset playback window, call resetPlaybackWindow.');

			_currentTime = timeValue;
			_lastTime = _timeFunction != null ? _timeFunction() : getTimer();
			stop();
		}

		public function play() : void
		{
			_isPlaying = true;
			_started.execute(this);
		}

		public function stop() : void
		{
			_isPlaying = false;
			_stopped.execute(this);
		}

		public function setPlaybackWindow(beginTime	: Object = null,
										  endTime	: Object = null) : void
		{
			_loopBeginTime	= beginTime != null ? getAnimationTime(beginTime) : 0;
			_loopEndTime	= endTime != null ? getAnimationTime(endTime) : _totalTime;

			if (_currentTime < _loopBeginTime || _currentTime > _loopEndTime)
				_currentTime = _loopBeginTime;
		}

		public function resetPlaybackWindow() : void
		{
			setPlaybackWindow();
		}

		private function getAnimationTime(time : Object) : uint
		{
			var timeValue : uint;

			if (time is uint || time is int || time is Number)
			{
				timeValue = uint(time);
			}
			else if (time is String)
			{
				var labelCount : uint = _labels.length;

				for (var labelId : uint = 0; labelId < labelCount; ++labelId)
					if (_labels[labelId].name == time)
						timeValue = _labels[labelId].time;
			}
			else
			{
				throw new Error('Invalid argument type. Must be uint or String');
			}

			return timeValue;
		}

		override protected function updateOnTime(time : Number) : Boolean
		{
			if (_isPlaying)
			{
				if (_timeFunction != null)
					time = _timeFunction();

				var deltaT 			: Number = time - _lastTime;
				var lastCurrentTime : Number = _currentTime;

				_currentTime = _loopBeginTime
					+ (_currentTime + deltaT - _loopBeginTime)
					% (_loopEndTime - _loopBeginTime);

				if (lastCurrentTime > _currentTime)
				{
					if (_looping)
						_looped.execute(this);
					else
					{
						_currentTime = _totalTime;
						stop();

						return true;
					}
				}
			}

			_lastTime = time;

			return _isPlaying;
		}

		override protected function updateTarget(target : ISceneNode) : void
		{
			var numTimelines 	: int 	= _timelines.length;
			var group			: Group	= target as Group;

			for (var i : int = 0; i < numTimelines; ++i)
			{
				var timeline : ITimeline = _timelines[i] as ITimeline;

				timeline.updateAt(
					_currentTime % (timeline.duration + 1),
					target
				);
			}
		}
	}
}

package aerys.minko.scene.controller
{
	import aerys.minko.scene.node.Group;
	import aerys.minko.scene.node.ISceneNode;
	import aerys.minko.type.Signal;
	import aerys.minko.type.animation.TimeLabel;
	import aerys.minko.type.animation.timeline.ITimeline;

	import flash.utils.getTimer;

	/**
	 * The AnimationController uses timelines to animate properties of scene nodes.
	 *
	 * @author Jean-Marc Le Roux
	 *
	 */
	public class AnimationController extends AbstractController
	{

		public static var DEFAULT_TIME_FUNCTION	: Function = getTimer;

		private var _timelines		: Vector.<ITimeline>	= new Vector.<ITimeline>();
		private var _isPlaying		: Boolean				= false;
		private var _loopBeginTime	: int					= 0;
		private var _loopEndTime	: int					= 0;
		private var _looping		: Boolean				= true;
		private var _currentTime	: int					= 0;
		private var _totalTime		: int					= 0;

		private var _timeFunction	: Function				= DEFAULT_TIME_FUNCTION;
		private var _labels			: Vector.<TimeLabel>	= null;

		private var _lastTime		: Number				= 0;

		private var _looped			: Signal 				= new Signal();
		private var _started		: Signal				= new Signal();
		private var _stopped		: Signal				= new Signal();

		public function get started():Signal
		{
			return _started;
		}

		public function get stopped() : Signal
		{
			return _stopped;
		}

		public function get looped():Signal
		{
			return _looped;
		}

		public function get totalTime() : int
		{
			return _totalTime;
		}

		public function get looping() : Boolean
		{
			return _looping;
		}
		public function set looping(value : Boolean) : void
		{
			_looping = value;
		}

		public function get isPlaying():Boolean
		{
			return _isPlaying;
		}

		public function set isPlaying(value:Boolean):void
		{
			_isPlaying = value;
		}

		public function get currentTime():int
		{
			return _currentTime;
		}

		public function set currentTime(value:int):void
		{
			_currentTime = value;
		}

		public function AnimationController(timelines	: Vector.<ITimeline>)
		{
			super();

			_timelines = timelines;

			initialize();
		}

		public function getTimeline(index : uint = 0) : ITimeline
		{
			return _timelines[index];
		}

		private function initialize() : void
		{
			var numTimelines : uint = _timelines.length;

			for (var timelineId : uint = 0; timelineId < numTimelines; ++timelineId)
				if (_totalTime < _timelines[timelineId].duration)
					_totalTime = _timelines[timelineId].duration;

			setPlaybackWindow(0, _totalTime);
			gotoAndPlay(0);
		}

		public function gotoAndPlay(time : Object) : void
		{
			var timeValue : uint = getAnimationTime(time);

			if (timeValue < _loopBeginTime || timeValue > _loopEndTime)
				throw new Error('Time value is outside of playback window. To reset playback window, call resetPlaybackWindow.');

			_currentTime = timeValue;
			_lastTime = _timeFunction != null ? _timeFunction() : getTimer();
			play();
		}

		public function gotoAndStop(time : Object) : void
		{
			var timeValue : uint = getAnimationTime(time);

			if (timeValue < _loopBeginTime || timeValue > _loopEndTime)
				throw new Error('Time value is outside of playback window. To reset playback window, call resetPlaybackWindow.');

			_currentTime = timeValue;
			_lastTime = _timeFunction != null ? _timeFunction() : getTimer();
			stop();
		}

		public function play() : void
		{
			_isPlaying = true;
			_started.execute(this);
		}

		public function stop() : void
		{
			_isPlaying = false;
			_stopped.execute(this);
		}

		public function setPlaybackWindow(beginTime	: Object = null,
										  endTime	: Object = null) : void
		{
			_loopBeginTime	= beginTime != null ? getAnimationTime(beginTime) : 0;
			_loopEndTime	= endTime != null ? getAnimationTime(endTime) : _totalTime;

			if (_currentTime < _loopBeginTime || _currentTime > _loopEndTime)
				_currentTime = _loopBeginTime;
		}

		public function resetPlaybackWindow() : void
		{
			setPlaybackWindow();
		}

		private function getAnimationTime(time : Object) : uint
		{
			var timeValue : uint;

			if (time is uint || time is int || time is Number)
			{
				timeValue = uint(time);
			}
			else if (time is String)
			{
				var labelCount : uint = _labels.length;

				for (var labelId : uint = 0; labelId < labelCount; ++labelId)
					if (_labels[labelId].name == time)
						timeValue = _labels[labelId].time;
			}
			else
			{
				throw new Error('Invalid argument type. Must be uint or String');
			}

			return timeValue;
		}

		override protected function updateOnTime(time : Number) : Boolean
		{
			if (_isPlaying)
			{
				if (_timeFunction != null)
					time = _timeFunction();

				var deltaT 			: Number = time - _lastTime;
				var lastCurrentTime : Number = _currentTime;

				_currentTime = _loopBeginTime
					+ (_currentTime + deltaT - _loopBeginTime)
					% (_loopEndTime - _loopBeginTime);

				if (lastCurrentTime > _currentTime)
				{
					if (_looping)
						_looped.execute(this);
					else
					{
						_currentTime = _totalTime;
						stop();

						return true;
					}
				}
			}

			_lastTime = time;

			return _isPlaying;
		}

		override protected function updateTarget(target : ISceneNode) : void
		{
			var numTimelines 	: int 	= _timelines.length;
			var group			: Group	= target as Group;

			for (var i : int = 0; i < numTimelines; ++i)
			{
				var timeline : ITimeline = _timelines[i] as ITimeline;

				timeline.updateAt(
					_currentTime % (timeline.duration + 1),
					target
				);
			}
		}
	}
}

Fix double getter on totalTime and isPlaying after the merge