package net.iab.vpaid.core
{

	/**
	 * Contains ad configuration parameters
	 * @author Andrei Andreev
	 */
	public class AdData extends Object
	{
		private var _params:Object = {};
		/**
		 *
		 * @param	params at runtime typically LoaderInfo.parameters
		 */
		public function AdData(params:Object = null)
		{
			init(params);
		}

		private function init(params:Object = null):void
		{
			var url:String = escape("http://services.mediamind.com/instream/IAB/videos/ad-video-canal.mp4");
			_params.advideo = unescape(url);
			_params.skipOffset = 5;
			_params.ovvBeaconURL = "http://localhost/iab/OVVBeacon.swf";
			this.params = params;
		}

		/**
		 * Iterates through argument properties and stored key/value pairs. Passing of null does not nullify individual properties.
		 */
		public function set params(value:Object):void
		{
			for (var property:String in value)
				_params[property] = unescape(value[property]);
		}

		/**
		 * Looks up property by proeprty name and returns corresponding value as a primitive Object. It is consumer's responsibility to validate/cast to specific value data type.
		 * @param	property name of the key in key/value pair
		 * @return	primitive typeless Object
		 */
		public function getParam(property:String):Object
		{
			return _params[property];
		}

	}

}

package net.iab.vpaid.core
{

	/**
	 * Contains ad configuration parameters
	 * @author Andrei Andreev
	 */
	public class AdData extends Object
	{
		private var _params:Object = {};
		/**
		 *
		 * @param	params at runtime typically LoaderInfo.parameters
		 */
		public function AdData(params:Object = null)
		{
			init(params);
		}

		private function init(params:Object = null):void
		{
			var url:String = escape("http://services.mediamind.com/instream/IAB/videos/ad-video-canal.mp4");
			_params.advideo = unescape(url);
			_params.skipOffset = 5;
			//_params.ovvBeaconURL = "http://localhost/iab/OVVBeacon.swf";
			_params.ovvBeaconURL = "/ad/OVVBeacon.swf";
			this.params = params;
		}

		/**
		 * Iterates through argument properties and stored key/value pairs. Passing of null does not nullify individual properties.
		 */
		public function set params(value:Object):void
		{
			for (var property:String in value)
				_params[property] = unescape(value[property]);
		}

		/**
		 * Looks up property by proeprty name and returns corresponding value as a primitive Object. It is consumer's responsibility to validate/cast to specific value data type.
		 * @param	property name of the key in key/value pair
		 * @return	primitive typeless Object
		 */
		public function getParam(property:String):Object
		{
			return _params[property];
		}

	}

}

Recompile for default OVVBeacon location


package com.threerings.ezgame.client {

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;

import flash.events.Event;

import flash.utils.Dictionary;

import mx.containers.Canvas;
import mx.containers.VBox;

import mx.core.Container;
import mx.core.IChildList;

import mx.utils.DisplayUtil;

import com.threerings.util.MediaContainer;

import com.threerings.mx.controls.ChatDisplayBox;

import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.util.CrowdContext;

import com.threerings.ezgame.data.EZGameConfig;
import com.threerings.ezgame.data.EZGameObject;

import com.threerings.ezgame.Game;

public class EZGamePanel extends VBox
    implements PlaceView
{
    public function EZGamePanel (ctx :CrowdContext, ctrl :EZGameController)
    {
        _ctx = ctx;
        _ctrl = ctrl;

        // add a listener so that we hear about all new children
        addEventListener(Event.ADDED, childAdded);
        addEventListener(Event.REMOVED, childRemoved);

        var cfg :EZGameConfig = (ctrl.getPlaceConfig() as EZGameConfig);
        _gameView = new MediaContainer(cfg.configData); // TODO
        addChild(_gameView);

        addChild(new ChatDisplayBox(ctx));
    }

    // from PlaceView
    public function willEnterPlace (plobj :PlaceObject) :void
    {
        // don't start notifying anything of the game until we've
        // notified the game manager that we're in the game
        // (done in GameController, and it uses callLater, so we do it twice!)
        _ctx.getClient().callLater(function () :void {
            _ctx.getClient().callLater(function () :void {
                _ezObj = (plobj as EZGameObject);

                notifyOfGame(_gameView);
            });
        });
    }

    // from PlaceView
    public function didLeavePlace (plobj :PlaceObject) :void
    {
        removeListeners(_gameView);
        _ezObj = null;
    }

    /**
     * Handle ADDED events.
     */
    protected function childAdded (event :Event) :void
    {
        if (_ezObj != null) {
            notifyOfGame(event.target as DisplayObject);
        }
    }

    /**
     * Handle REMOVED events.
     */
    protected function childRemoved (event :Event) :void
    {
        if (_ezObj != null) {
            removeListeners(event.target as DisplayObject);
        }
    }

    /**
     * Find any children of the specified object that implement
     * com.metasoy.game.Game and provide them with the GameObject.
     */
    protected function notifyOfGame (root :DisplayObject) :void
    {
        DisplayUtil.walkDisplayObjects(root,
            function (disp :DisplayObject) :void
            {
                if (disp is Game) {
                    // only notify the Game if we haven't seen it before
                    if (null == _seenGames[disp]) {
                        (disp as Game).setGameObject(_ctrl.gameObjImpl);
                        _seenGames[disp] = true;
                    }
                }
                // always check to see if it's a listener
                _ctrl.gameObjImpl.registerListener(disp);
            });
    }

    protected function removeListeners (root :DisplayObject) :void
    {
        DisplayUtil.walkDisplayObjects(root,
            function (disp :DisplayObject) :void
            {
                _ctrl.gameObjImpl.unregisterListener(disp);
            });
    }

    protected var _ctx :CrowdContext;
    protected var _ctrl :EZGameController;

    protected var _gameView :MediaContainer;

    /** A weak-key hash of the Game interfaces we've already seen. */
    protected var _seenGames :Dictionary = new Dictionary(true);

    protected var _ezObj :EZGameObject;
}
}

package com.threerings.ezgame.client {

import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;

import flash.events.Event;

import flash.utils.Dictionary;

import mx.containers.Canvas;
import mx.containers.VBox;

import mx.core.Container;
import mx.core.IChildList;

import mx.utils.DisplayUtil;

import com.threerings.util.MediaContainer;

import com.threerings.mx.controls.ChatDisplayBox;

import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.util.CrowdContext;

import com.threerings.ezgame.data.EZGameConfig;
import com.threerings.ezgame.data.EZGameObject;

import com.threerings.ezgame.Game;

public class EZGamePanel extends VBox
    implements PlaceView
{
    public function EZGamePanel (ctx :CrowdContext, ctrl :EZGameController)
    {
        _ctx = ctx;
        _ctrl = ctrl;

        // add a listener so that we hear about all new children
        addEventListener(Event.ADDED, childAdded);
        addEventListener(Event.REMOVED, childRemoved);

        var cfg :EZGameConfig = (ctrl.getPlaceConfig() as EZGameConfig);
        _gameView = new MediaContainer(cfg.configData); // TODO
        addChild(_gameView);

        //addChild(new ChatDisplayBox(ctx));
    }

    // from PlaceView
    public function willEnterPlace (plobj :PlaceObject) :void
    {
        // don't start notifying anything of the game until we've
        // notified the game manager that we're in the game
        // (done in GameController, and it uses callLater, so we do it twice!)
        _ctx.getClient().callLater(function () :void {
            _ctx.getClient().callLater(function () :void {
                _ezObj = (plobj as EZGameObject);

                notifyOfGame(_gameView);
            });
        });
    }

    // from PlaceView
    public function didLeavePlace (plobj :PlaceObject) :void
    {
        removeListeners(_gameView);
        _ezObj = null;
    }

    /**
     * Handle ADDED events.
     */
    protected function childAdded (event :Event) :void
    {
        if (_ezObj != null) {
            notifyOfGame(event.target as DisplayObject);
        }
    }

    /**
     * Handle REMOVED events.
     */
    protected function childRemoved (event :Event) :void
    {
        if (_ezObj != null) {
            removeListeners(event.target as DisplayObject);
        }
    }

    /**
     * Find any children of the specified object that implement
     * com.metasoy.game.Game and provide them with the GameObject.
     */
    protected function notifyOfGame (root :DisplayObject) :void
    {
        DisplayUtil.walkDisplayObjects(root,
            function (disp :DisplayObject) :void
            {
                if (disp is Game) {
                    // only notify the Game if we haven't seen it before
                    if (null == _seenGames[disp]) {
                        (disp as Game).setGameObject(_ctrl.gameObjImpl);
                        _seenGames[disp] = true;
                    }
                }
                // always check to see if it's a listener
                _ctrl.gameObjImpl.registerListener(disp);
            });
    }

    protected function removeListeners (root :DisplayObject) :void
    {
        DisplayUtil.walkDisplayObjects(root,
            function (disp :DisplayObject) :void
            {
                _ctrl.gameObjImpl.unregisterListener(disp);
            });
    }

    protected var _ctx :CrowdContext;
    protected var _ctrl :EZGameController;

    protected var _gameView :MediaContainer;

    /** A weak-key hash of the Game interfaces we've already seen. */
    protected var _seenGames :Dictionary = new Dictionary(true);

    protected var _ezObj :EZGameObject;
}
}

Remove giant obnoxious game-blocking chat display.

git-svn-id: a3e1eb16dde062992de22c830ed8045c8013209a@134 c613c5cb-e716-0410-b11b-feb51c14d237


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

package com.threerings.media.image {

import com.threerings.util.Log;
import com.threerings.util.Map;
import com.threerings.util.Maps;
import com.threerings.util.RandomUtil;
import com.threerings.util.StringUtil;

public class ClassRecord
{
    private const log :Log = Log.getLog(ClassRecord);

    /** An integer identifier for this class. */
    public var classId :int;

    /** The name of the color class. */
    public var name :String;

    /** The source color to use when recoloring colors in this class. */
    public var source :uint;

    /** Data identifying the range of colors around the source color
     * that will be recolored when recoloring using this class. */
    public var range :Array;

    /** The default starting legality value for this color class. See
     * {@link ColorRecord#starter}. */
    public var starter :Boolean;

    /** The default colorId to use for recoloration in this class, or
     * 0 if there is no default defined. */
    public var defaultId :int;

    /** A table of target colors included in this class. */
    public var colors :Map = Maps.newMapOf(int);

    /** Used when parsing the color definitions. */
    public function addColor (record :ColorRecord) :void
    {
        // validate the color id
        if (record.colorId > 127) {
            log.warning("Refusing to add color record; colorId > 127",
                        "class", this, "record", record);
        } else if (colors.containsKey(record.colorId)) {
            log.warning("Refusing to add duplicate colorId",
                        "class", this, "record", record, "existing", colors.get(record.colorId));
        } else {
            record.cclass = this;
            colors.put(record.colorId, record);
        }
    }

    /**
     * Translates a color identified in string form into the id that should be used to look up
     * its information. Throws an exception if no color could be found that associates with
     * that name.
     */
    public function getColorId (name :String) :int
    {
        // Check if the string is itself a number
        var id :int = name as int;
        if (colors.containsKey(id)) {
            return id;
        }

        // Look for name matches among all colors
        for each (var color :ColorRecord in colors) {
                if (StringUtil.compareIgnoreCase(color.name, name) == 0) {
                return color.colorId;
            }
        }

        // That input wasn't a color
        throw new Error("No color named '" + name + "'", 0);
    }

    /** Returns a random starting id from the entries in this class. */
    public function randomStartingColor () :ColorRecord
    {
        // figure out our starter ids if we haven't already
        if (_starters == null) {
            _starters = [];
            for each (var color :ColorRecord in colors) {
                if (color.starter) {
                    _starters.push(color);
                }
            }
        }

        // sanity check
        if (_starters.length < 1) {
            log.warning("Requested random starting color from colorless component class",
                        "class", this);
            return null;
        }

        // return a random entry from the array
        return RandomUtil.pickRandom(_starters);
    }

    /**
     * Get the default ColorRecord defined for this color class, or
     * null if none.
     */
    public function getDefault () :ColorRecord
    {
        return colors.get(defaultId);
    }

    public function toString () :String
    {
        return "[id=" + classId + ", name=" + name + ", source=#" +
            StringUtil.toHex(source & 0xFFFFFF, 6) +
            ", range=" + StringUtil.toString(range) +
            ", starter=" + starter + ", colors=" +
            StringUtil.toString(colors.values()) + "]";
    }

    public static function fromXml (xml :XML) :ClassRecord
    {
        var rec :ClassRecord = new ClassRecord();
        rec.classId = xml.@classId;
        for each (var colorXml :XML in xml.color) {
            rec.colors.put(int(colorXml.@colorId), ColorRecord.fromXml(colorXml, rec));
        }

        rec.name = xml.@name;
        var srcStr :String = xml.@source;
        rec.source = parseInt(srcStr.substr(1, srcStr.length - 1), 16);
        rec.range = toNumArray(xml.@range);
        rec.defaultId = xml.@defaultId;

        return rec;
    }

    protected static function toNumArray (str :String) :Array
    {
        if (str == null) {
            return null;
        }

        return str.split(",").map(function(element :*, index :int, arr :Array) :Number {
            return Number(element);
        });
    }

    protected var _starters :Array;
}
}

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

package com.threerings.media.image {

import com.threerings.util.Log;
import com.threerings.util.Map;
import com.threerings.util.Maps;
import com.threerings.util.RandomUtil;
import com.threerings.util.StringUtil;

public class ClassRecord
{
    private const log :Log = Log.getLog(ClassRecord);

    /** An integer identifier for this class. */
    public var classId :int;

    /** The name of the color class. */
    public var name :String;

    /** The source color to use when recoloring colors in this class. */
    public var source :uint;

    /** Data identifying the range of colors around the source color
     * that will be recolored when recoloring using this class. */
    public var range :Array;

    /** The default starting legality value for this color class. See
     * {@link ColorRecord#starter}. */
    public var starter :Boolean;

    /** The default colorId to use for recoloration in this class, or
     * 0 if there is no default defined. */
    public var defaultId :int;

    /** A table of target colors included in this class. */
    public var colors :Map = Maps.newMapOf(int);

    /** Used when parsing the color definitions. */
    public function addColor (record :ColorRecord) :void
    {
        // validate the color id
        if (record.colorId > 127) {
            log.warning("Refusing to add color record; colorId > 127",
                        "class", this, "record", record);
        } else if (colors.containsKey(record.colorId)) {
            log.warning("Refusing to add duplicate colorId",
                        "class", this, "record", record, "existing", colors.get(record.colorId));
        } else {
            record.cclass = this;
            colors.put(record.colorId, record);
        }
    }

    /**
     * Translates a color identified in string form into the id that should be used to look up
     * its information. Throws an exception if no color could be found that associates with
     * that name.
     */
    public function getColorId (name :String) :int
    {
        // Check if the string is itself a number
        var id :int = name as int;
        if (colors.containsKey(id)) {
            return id;
        }

        // Look for name matches among all colors
        for each (var color :ColorRecord in colors.values()) {
                if (StringUtil.compareIgnoreCase(color.name, name) == 0) {
                return color.colorId;
            }
        }

        // That input wasn't a color
        throw new Error("No color named '" + name + "'", 0);
    }

    /** Returns a random starting id from the entries in this class. */
    public function randomStartingColor () :ColorRecord
    {
        // figure out our starter ids if we haven't already
        if (_starters == null) {
            _starters = [];
            for each (var color :ColorRecord in colors) {
                if (color.starter) {
                    _starters.push(color);
                }
            }
        }

        // sanity check
        if (_starters.length < 1) {
            log.warning("Requested random starting color from colorless component class",
                        "class", this);
            return null;
        }

        // return a random entry from the array
        return RandomUtil.pickRandom(_starters);
    }

    /**
     * Get the default ColorRecord defined for this color class, or
     * null if none.
     */
    public function getDefault () :ColorRecord
    {
        return colors.get(defaultId);
    }

    public function toString () :String
    {
        return "[id=" + classId + ", name=" + name + ", source=#" +
            StringUtil.toHex(source & 0xFFFFFF, 6) +
            ", range=" + StringUtil.toString(range) +
            ", starter=" + starter + ", colors=" +
            StringUtil.toString(colors.values()) + "]";
    }

    public static function fromXml (xml :XML) :ClassRecord
    {
        var rec :ClassRecord = new ClassRecord();
        rec.classId = xml.@classId;
        for each (var colorXml :XML in xml.color) {
            rec.colors.put(int(colorXml.@colorId), ColorRecord.fromXml(colorXml, rec));
        }

        rec.name = xml.@name;
        var srcStr :String = xml.@source;
        rec.source = parseInt(srcStr.substr(1, srcStr.length - 1), 16);
        rec.range = toNumArray(xml.@range);
        rec.defaultId = xml.@defaultId;

        return rec;
    }

    protected static function toNumArray (str :String) :Array
    {
        if (str == null) {
            return null;
        }

        return str.split(",").map(function(element :*, index :int, arr :Array) :Number {
            return Number(element);
        });
    }

    protected var _starters :Array;
}
}

Fix bug in getting colorizations by name.

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


class Mastermind {

    Hub @hub;
    Entity @self;

	Entity@ slot1 = null;
	Entity@ slot2 = null;
	Entity@ slot3 = null;
	Entity@ slot4 = null;

    Entity@ slot1Key;
    Entity@ slot2Key;
    Entity@ slot3Key;
    Entity@ slot4Key;

	Entity @light1;
	Entity @light2;
	Entity @light3;
	Entity @light4;

    Entity @flickeringLights;
	Entity @roundabout;

    Mastermind(Entity @entity){
        @hub = Managers();
        @self = @entity;
        @slot1Key = GetEntityByGUID(1511964701); // GreenPropp
        @slot2Key = GetEntityByGUID(1511964823); // RedPropp
        @slot3Key = GetEntityByGUID(1511964915); // YellowPropp
        @slot4Key = GetEntityByGUID(1511964754); // PinkPropp

        // Remove this if updates are not desired.
        RegisterUpdate();
    }

    // Called by the engine for each frame.
    void Update(float deltaTime) {
        if (puzzleSolved)
            return;

        CheckSolution();

		for(int i = 0; i < correct; i++){
            TurnOnLight(100, vec3(0,255,0));
		}

		for(int i = 0; i < rightColors; i++){
            TurnOnLight(100, vec3(255,0,0));
		}

		if(puzzleSolved){

		}
        else{

        }

    }

	bool puzzleSolved = false;
	int correct = 0;
	int rightColors = 0;

	void CheckSolution(){
		correct = 0;
		rightColors = 0;
		puzzleSolved = false;
        TurnOffLights();

		if (@slot1 != null && @slot2 != null && @slot3 != null && @slot4 != null) {

			if (slot1 is slot1Key)
				correct = correct + 1;
			else if (slot1 is slot2Key || slot1 is slot3Key || slot1 is slot4Key)
				rightColors = rightColors + 1;

			if (slot2 is slot2Key)
				correct = correct + 1;
			else if (slot2 is slot1Key || slot2 is slot3Key || slot2 is slot4Key)
				rightColors = rightColors + 1;

			if (slot3 is slot3Key)
				correct = correct + 1;
			else if (slot3 is slot1Key || slot3 is slot2Key || slot3 is slot4Key)
				rightColors = rightColors + 1;

			if (slot4 is slot4Key)
				correct = correct + 1;
			else if (slot4 is slot1Key || slot4 is slot2Key || slot4 is slot3Key)
				rightColors = rightColors + 1;

			if (correct == 4) {
				puzzleSolved = true;
                SendMessage(roundabout, 2);
		    }
		}

	}

    void TurnOnLight(int intensity, vec3 lightColor){

        if(light1.GetSpotLight().intensity == 0){
            light1.GetSpotLight().intensity = intensity;
            light1.GetSpotLight().color = lightColor;
        }
        else if(light2.GetSpotLight().intensity == 0){
            light2.GetSpotLight().intensity = intensity;
            light2.GetSpotLight().color = lightColor;
        }
        else if(light3.GetSpotLight().intensity == 0){
            light3.GetSpotLight().intensity = intensity;
            light3.GetSpotLight().color = lightColor;
        }
        else if(light4.GetSpotLight().intensity == 0){
            light4.GetSpotLight().intensity = intensity;
            light4.GetSpotLight().color = lightColor;
        }

    }
    void TurnOffLights(){

        light1.GetSpotLight().intensity = 0;
        light2.GetSpotLight().intensity = 0;
        light3.GetSpotLight().intensity = 0;
        light4.GetSpotLight().intensity = 0;

    }

    void ReceiveMessage(Entity @sender, int signal) {

        if(signal < 4)
            AddToSlot(signal, sender);
        else
            RemoveFromSlot(signal - 4);

    }

    void AddToSlot(int slot, Entity@ fuse) {
        // First remove any existing fuse in this slot.
        RemoveFromSlot(slot);

        switch(slot){

            case 0: {
                @slot1 = @fuse;
                break;
            }
            case 1: {
                @slot2 = @fuse;
                break;
            }
            case 2: {
                @slot3 = @fuse;
                break;
            }
            case 3: {
                @slot4 = @fuse;
                break;
            }

        }

    }
    void RemoveFromSlot(int slot){

        switch(slot){

            case 0: {
                if (@slot1 != null) {
                    SendMessage(slot1, 0);
                }
                @slot1 = null;
                break;
            }
            case 1: {
                if (@slot2 != null) {
                    SendMessage(slot2, 0);
                }
                @slot2 = null;
                break;
            }
            case 2: {
                if (@slot3 != null) {
                    SendMessage(slot3, 0);
                }
                @slot3 = null;
                break;
            }
            case 3: {
                if (@slot4 != null) {
                    SendMessage(slot4, 0);
                }
                @slot4 = null;
                break;
            }

        }

    }

}

class Mastermind {
    Hub @hub;
    Entity @self;

    Entity@ slot1 = null;
    Entity@ slot2 = null;
    Entity@ slot3 = null;
    Entity@ slot4 = null;

    Entity@ slot1Key;
    Entity@ slot2Key;
    Entity@ slot3Key;
    Entity@ slot4Key;

    Entity @light1;
    Entity @light2;
    Entity @light3;
    Entity @light4;

    Entity @flickeringLights;
    Entity @roundabout;

    bool puzzleSolved = false;
    int correct = 0;
    int rightColors = 0;

    Mastermind(Entity @entity) {
        @hub = Managers();
        @self = @entity;
        @slot1Key = GetEntityByGUID(1511964701); // GreenPropp
        @slot2Key = GetEntityByGUID(1511964823); // RedPropp
        @slot3Key = GetEntityByGUID(1511964915); // YellowPropp
        @slot4Key = GetEntityByGUID(1511964754); // PinkPropp

        // Remove this if updates are not desired.
        RegisterUpdate();
    }

    // Called by the engine for each frame.
    void Update(float deltaTime) {
        if (puzzleSolved)
            return;

        CheckSolution();

        for (int i = 0; i < correct; i++) {
            TurnOnLight(100, vec3(0, 255, 0));
        }

        for (int i = 0; i < rightColors; i++) {
            TurnOnLight(100, vec3(255, 0, 0));
        }
    }

    void CheckSolution() {
        correct = 0;
        rightColors = 0;
        puzzleSolved = false;
        TurnOffLights();

        if (@slot1 != null && @slot2 != null && @slot3 != null && @slot4 != null) {
            if (slot1 is slot1Key)
                correct = correct + 1;
            else if (slot1 is slot2Key || slot1 is slot3Key || slot1 is slot4Key)
                rightColors = rightColors + 1;

            if (slot2 is slot2Key)
                correct = correct + 1;
            else if (slot2 is slot1Key || slot2 is slot3Key || slot2 is slot4Key)
                rightColors = rightColors + 1;

            if (slot3 is slot3Key)
                correct = correct + 1;
            else if (slot3 is slot1Key || slot3 is slot2Key || slot3 is slot4Key)
                rightColors = rightColors + 1;

            if (slot4 is slot4Key)
                correct = correct + 1;
            else if (slot4 is slot1Key || slot4 is slot2Key || slot4 is slot3Key)
                rightColors = rightColors + 1;

            if (correct == 4) {
                puzzleSolved = true;
                SendMessage(roundabout, 2);
            }
        }
    }

    void TurnOnLight(int intensity, vec3 lightColor) {
        if (light1.GetSpotLight().intensity == 0) {
            light1.GetSpotLight().intensity = intensity;
            light1.GetSpotLight().color = lightColor;
        }
        else if (light2.GetSpotLight().intensity == 0) {
            light2.GetSpotLight().intensity = intensity;
            light2.GetSpotLight().color = lightColor;
        }
        else if (light3.GetSpotLight().intensity == 0) {
            light3.GetSpotLight().intensity = intensity;
            light3.GetSpotLight().color = lightColor;
        }
        else if (light4.GetSpotLight().intensity == 0) {
            light4.GetSpotLight().intensity = intensity;
            light4.GetSpotLight().color = lightColor;
        }
    }

    void TurnOffLights() {
        light1.GetSpotLight().intensity = 0;
        light2.GetSpotLight().intensity = 0;
        light3.GetSpotLight().intensity = 0;
        light4.GetSpotLight().intensity = 0;
    }

    void ReceiveMessage(Entity @sender, int signal) {
        if (signal < 4)
            AddToSlot(signal, sender);
        else
            RemoveFromSlot(signal - 4);
    }

    void AddToSlot(int slot, Entity@ fuse) {
        // First remove any existing fuse in this slot.
        RemoveFromSlot(slot);

        switch(slot) {
            case 0: {
                @slot1 = @fuse;
                break;
            }
            case 1: {
                @slot2 = @fuse;
                break;
            }
            case 2: {
                @slot3 = @fuse;
                break;
            }
            case 3: {
                @slot4 = @fuse;
                break;
            }
        }
    }

    void RemoveFromSlot(int slot) {
        switch(slot) {
            case 0: {
                if (@slot1 != null) {
                    SendMessage(slot1, 0);
                }
                @slot1 = null;
                break;
            }
            case 1: {
                if (@slot2 != null) {
                    SendMessage(slot2, 0);
                }
                @slot2 = null;
                break;
            }
            case 2: {
                if (@slot3 != null) {
                    SendMessage(slot3, 0);
                }
                @slot3 = null;
                break;
            }
            case 3: {
                if (@slot4 != null) {
                    SendMessage(slot4, 0);
                }
                @slot4 = null;
                break;
            }
        }
    }
}

Clean mastermind script in terms of tabs, spacing, and newlines.


// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2011 , Yang Bo All rights reserved.
//
// Author: Yang Bo (pop.atry@gmail.com)
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.
package com.netease.protobuf {
	import flash.errors.IllegalOperationError
	import flash.utils.getDefinitionByName;
	import flash.utils.IDataInput
	/**
	 * @private
	 */
	public class BaseFieldDescriptor implements IFieldDescriptor {
		public var fullName:String
		protected var _name:String
		public final function get name():String {
			return _name
		}
		protected var tag:uint
		public final function get tagNumber():uint {
			return tag >>> 7
		}
		public function get type():Class {
			throw new IllegalOperationError("Not Implemented!")
		}
		public function readSingleField(input:IDataInput):* {
			throw new IllegalOperationError("Not Implemented!")
		}
		public function writeSingleField(output:WritingBuffer, value:*):void {
			throw new IllegalOperationError("Not Implemented!")
		}
		public function write(destination:WritingBuffer, source:Message):void {
			throw new IllegalOperationError("Not Implemented!")
		}
		private static const ACTIONSCRIPT_KEYWORDS:Object = {
			"as" : true,		"break" : true,		"case" : true,
			"catch" : true,		"class" : true,		"const" : true,
			"continue" : true,	"default" : true,	"delete" : true,
			"do" : true,		"else" : true,		"extends" : true,
			"false" : true,		"finally" : true,	"for" : true,
			"function" : true,	"if" : true,		"implements" : true,
			"import" : true,	"in" : true,		"instanceof" : true,
			"interface" : true,	"internal" : true,	"is" : true,
			"native" : true,	"new" : true,		"null" : true,
			"package" : true,	"private" : true,	"protected" : true,
			"public" : true,	"return" : true,	"super" : true,
			"switch" : true,	"this" : true,		"throw" : true,
			"to" : true,		"true" : true,		"try" : true,
			"typeof" : true,	"use" : true,		"var" : true,
			"void" : true,		"while" : true,		"with" : true
		}

		public function toString():String {
			return name
		}

		internal static function getExtensionByName(
				name:String):BaseFieldDescriptor {
			const fieldPosition:int = name.lastIndexOf('/')
			if (fieldPosition == -1) {
				return BaseFieldDescriptor(getDefinitionByName(name))
			} else {
				return getDefinitionByName(name.substring(0, fieldPosition))[
						name.substring(fieldPosition + 1)]
			}
		}
	}

}
function regexToUpperCase(matched:String, index:int, whole:String):String {
	return matched.charAt(1).toUpperCase()
}

// vim: tabstop=4 shiftwidth=4

// Copyright (c) 2011 , Yang Bo All rights reserved.
//
// Author: Yang Bo (pop.atry@gmail.com)
//
// Use, modification and distribution are subject to the "New BSD License"
// as listed at <url: http://www.opensource.org/licenses/bsd-license.php >.
package com.netease.protobuf {
	import flash.errors.IllegalOperationError
	import flash.utils.getDefinitionByName;
	import flash.utils.IDataInput
	/**
	 * @private
	 */
	public class BaseFieldDescriptor implements IFieldDescriptor {
		public var fullName:String
		protected var _name:String
		public final function get name():String {
			return _name
		}
		protected var tag:uint
		public final function get tagNumber():uint {
			return tag >>> 3
		}
		public function get type():Class {
			throw new IllegalOperationError("Not Implemented!")
		}
		public function readSingleField(input:IDataInput):* {
			throw new IllegalOperationError("Not Implemented!")
		}
		public function writeSingleField(output:WritingBuffer, value:*):void {
			throw new IllegalOperationError("Not Implemented!")
		}
		public function write(destination:WritingBuffer, source:Message):void {
			throw new IllegalOperationError("Not Implemented!")
		}
		private static const ACTIONSCRIPT_KEYWORDS:Object = {
			"as" : true,		"break" : true,		"case" : true,
			"catch" : true,		"class" : true,		"const" : true,
			"continue" : true,	"default" : true,	"delete" : true,
			"do" : true,		"else" : true,		"extends" : true,
			"false" : true,		"finally" : true,	"for" : true,
			"function" : true,	"if" : true,		"implements" : true,
			"import" : true,	"in" : true,		"instanceof" : true,
			"interface" : true,	"internal" : true,	"is" : true,
			"native" : true,	"new" : true,		"null" : true,
			"package" : true,	"private" : true,	"protected" : true,
			"public" : true,	"return" : true,	"super" : true,
			"switch" : true,	"this" : true,		"throw" : true,
			"to" : true,		"true" : true,		"try" : true,
			"typeof" : true,	"use" : true,		"var" : true,
			"void" : true,		"while" : true,		"with" : true
		}

		public function toString():String {
			return name
		}

		internal static function getExtensionByName(
				name:String):BaseFieldDescriptor {
			const fieldPosition:int = name.lastIndexOf('/')
			if (fieldPosition == -1) {
				return BaseFieldDescriptor(getDefinitionByName(name))
			} else {
				return getDefinitionByName(name.substring(0, fieldPosition))[
						name.substring(fieldPosition + 1)]
			}
		}
	}

}
function regexToUpperCase(matched:String, index:int, whole:String):String {
	return matched.charAt(1).toUpperCase()
}

修复bug：tagID应该右移3位


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

package org.apache.flex.core.graphics
{
	import org.apache.flex.core.graphics.utils.CompoundTransform;

	public class GradientBase
	{

		protected var colors:Array /* of uint */ = [];

		protected var ratios:Array /* of Number */ = [];

		protected var alphas:Array /* of Number */ = [];

		/**
		 *  Holds the matrix and the convenience transform properties (x, y, and rotation).
		 *  The compoundTransform is only created when the matrix property is set.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 9
		 *  @playerversion AIR 1.1
		 */
		protected var compoundTransform:CompoundTransform;

		/**
		 *  Value of the width and height of the untransformed gradient
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 */
		public static const GRADIENT_DIMENSION:Number = 1638.4;

		/**
		 *  Storage for the angle property.
		 */
		private var _angle:Number;

		/**
		 *  By default, the LinearGradientStroke defines a transition
		 *  from left to right across the control.
		 *  Use the angle property to control the transition direction.
		 *  For example, a value of 180.0 causes the transition
		 *  to occur from right to left, rather than from left to right.
		 *
		 *  @default 0.0
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 9
		 *  @playerversion AIR 1.1
		 */
		public function get angle():Number
		{
			return _angle / Math.PI * 180;
		}

		/**
		 *  @private
		 */
		public function set angle(value:Number):void
		{
			_angle = value / 180 * Math.PI;
		}

		/**
		 *  Storage for the entries property.
		 */
		private var _entries:Array = [];

		/**
		 *  @private
		 *  Storage for the rotation property.
		 */
		private var _rotation:Number = 0.0;

		/**
		 *  An Array of GradientEntry objects
		 *  defining the fill patterns for the gradient fill.
		 *
		 */
		public function get entries():Array
		{
			return _entries;
		}

		/**
		 *  @private
		 */
		public function set entries(value:Array):void
		{
			_entries = value;
			processEntries();
		}

		/**
		 *  By default, the LinearGradientStroke defines a transition
		 *  from left to right across the control.
		 *  Use the rotation property to control the transition direction.
		 *  For example, a value of 180.0 causes the transition
		 *  to occur from right to left, rather than from left to right.
		 *
		 *  @default 0.0
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 9
		 *  @playerversion AIR 1.1
		 *  @productversion Flex 3
		 */
		public function get rotation():Number
		{
			return _rotation;
		}

		/**
		 *  @private
		 */
		public function set rotation(value:Number):void
		{
			_rotation = value;
		}

		private var _x:Number = 0;

		/**
		 *  The distance by which to translate each point along the x axis.
		 */
		public function get x():Number
		{
			return _x;
		}

		/**
		 *  @private
		 */
		public function set x(value:Number):void
		{
			_x = value;
		}

		private var _y:Number = 0;

		/**
		 *  The distance by which to translate each point along the y axis.
		 */
		public function get y():Number
		{
			return _y;
		}

		/**
		 *  @private
		 */
		public function set y(value:Number):void
		{
			_y = value;
		}

		protected function toRad(a:Number):Number {
			return a*Math.PI/180;
		}

		protected function get rotationInRadians():Number
		{
			return rotation / 180 * Math.PI;
		}

		/**
		 *  @private
		 *  Extract the gradient information in the public entries
		 *  Array into the internal colors, ratios,
		 *  and alphas arrays.
		 */
		private function processEntries():void
		{
			colors = [];
			ratios = [];
			alphas = [];

			if (!_entries || _entries.length == 0)
				return;

			var ratioConvert:Number = 255;

			var i:int;

			var n:int = _entries.length;
			for (i = 0; i < n; i++)
			{
				var e:GradientEntry = _entries[i];
				colors.push(e.color);
				alphas.push(e.alpha);
				ratios.push(e.ratio * ratioConvert);
			}

			if (isNaN(ratios[0]))
				ratios[0] = 0;

			if (isNaN(ratios[n - 1]))
				ratios[n - 1] = 255;

			i = 1;

			while (true)
			{
				while (i < n && !isNaN(ratios[i]))
				{
					i++;
				}

				if (i == n)
					break;

				var start:int = i - 1;

				while (i < n && isNaN(ratios[i]))
				{
					i++;
				}

				var br:Number = ratios[start];
				var tr:Number = ratios[i];

				for (var j:int = 1; j < i - start; j++)
				{
					ratios[j] = br + j * (tr - br) / (i - start);
				}
			}
		}

	}
}

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

package org.apache.flex.core.graphics
{
	import org.apache.flex.core.graphics.utils.CompoundTransform;

	public class GradientBase
	{

		protected var colors:Array /* of uint */ = [];

		protected var ratios:Array /* of Number */ = [];

		protected var alphas:Array /* of Number */ = [];

		/**
		 *  Holds the matrix and the convenience transform properties (x, y, and rotation).
		 *  The compoundTransform is only created when the matrix property is set.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 9
		 *  @playerversion AIR 1.1
		 */
		protected var compoundTransform:CompoundTransform;

		/**
		 *  Value of the width and height of the untransformed gradient
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 */
		public static const GRADIENT_DIMENSION:Number = 1638.4;

		/**
		 *  Storage for the entries property.
		 */
		private var _entries:Array = [];

		/**
		 *  @private
		 *  Storage for the rotation property.
		 */
		private var _rotation:Number = 0.0;

		/**
		 *  An Array of GradientEntry objects
		 *  defining the fill patterns for the gradient fill.
		 *
		 */
		public function get entries():Array
		{
			return _entries;
		}

		/**
		 *  @private
		 */
		public function set entries(value:Array):void
		{
			_entries = value;
			processEntries();
		}

		/**
		 *  By default, the LinearGradientStroke defines a transition
		 *  from left to right across the control.
		 *  Use the rotation property to control the transition direction.
		 *  For example, a value of 180.0 causes the transition
		 *  to occur from right to left, rather than from left to right.
		 *
		 *  @default 0.0
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 9
		 *  @playerversion AIR 1.1
		 *  @productversion Flex 3
		 */
		public function get rotation():Number
		{
			return _rotation;
		}

		/**
		 *  @private
		 */
		public function set rotation(value:Number):void
		{
			_rotation = value;
		}

		private var _x:Number = 0;

		/**
		 *  The distance by which to translate each point along the x axis.
		 */
		public function get x():Number
		{
			return _x;
		}

		/**
		 *  @private
		 */
		public function set x(value:Number):void
		{
			_x = value;
		}

		private var _y:Number = 0;

		/**
		 *  The distance by which to translate each point along the y axis.
		 */
		public function get y():Number
		{
			return _y;
		}

		/**
		 *  @private
		 */
		public function set y(value:Number):void
		{
			_y = value;
		}

		protected function toRad(a:Number):Number {
			return a*Math.PI/180;
		}

		protected function get rotationInRadians():Number
		{
			return rotation / 180 * Math.PI;
		}

		/**
		 *  @private
		 *  Extract the gradient information in the public entries
		 *  Array into the internal colors, ratios,
		 *  and alphas arrays.
		 */
		private function processEntries():void
		{
			colors = [];
			ratios = [];
			alphas = [];

			if (!_entries || _entries.length == 0)
				return;

			var ratioConvert:Number = 255;

			var i:int;

			var n:int = _entries.length;
			for (i = 0; i < n; i++)
			{
				var e:GradientEntry = _entries[i];
				colors.push(e.color);
				alphas.push(e.alpha);
				ratios.push(e.ratio * ratioConvert);
			}

			if (isNaN(ratios[0]))
				ratios[0] = 0;

			if (isNaN(ratios[n - 1]))
				ratios[n - 1] = 255;

			i = 1;

			while (true)
			{
				while (i < n && !isNaN(ratios[i]))
				{
					i++;
				}

				if (i == n)
					break;

				var start:int = i - 1;

				while (i < n && isNaN(ratios[i]))
				{
					i++;
				}

				var br:Number = ratios[start];
				var tr:Number = ratios[i];

				for (var j:int = 1; j < i - start; j++)
				{
					ratios[j] = br + j * (tr - br) / (i - start);
				}
			}
		}

	}
}

Remove angle property and its getter/setter. The rotation property should be used to specify the gradient's rotation.


/**
 * Copyright (c) 2009 Digital Primates IT Consulting Group
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * @author     Alan Stearns - astearns@adobe.com
 * 			   Michael Labriola - labriola@digitalprimates.net
 * 			   David Wolever - david@wolever.net
 * @version
 *
 **/

package org.flexunit.runners
{
	import flex.lang.reflect.Field;

	import org.flexunit.constants.AnnotationConstants;
	import org.flexunit.internals.dependency.ExternalDependencyResolver;
	import org.flexunit.internals.dependency.IExternalDependencyResolver;
	import org.flexunit.internals.dependency.IExternalRunnerDependencyWatcher;
	import org.flexunit.internals.runners.ErrorReportingRunner;
	import org.flexunit.internals.runners.InitializationError;
	import org.flexunit.internals.runners.statements.IAsyncStatement;
	import org.flexunit.runner.IDescription;
	import org.flexunit.runner.IRunner;
	import org.flexunit.runner.external.IExternalDependencyRunner;
	import org.flexunit.runner.notification.IRunNotifier;
	import org.flexunit.runner.notification.StoppedByUserException;
	import org.flexunit.runners.model.FrameworkMethod;
	import org.flexunit.runners.model.IRunnerBuilder;
	import org.flexunit.token.AsyncTestToken;

	public class Parameterized extends ParentRunner implements IExternalDependencyRunner {
		private var runners:Array;
		private var klass:Class;
		private var dr:IExternalDependencyResolver;
		private var _dependencyWatcher:IExternalRunnerDependencyWatcher;
		private var dependencyDataWatchers:Array;
		private var _externalDependencyError:String;
		private var externalError:Boolean = false;

		public function set dependencyWatcher( value:IExternalRunnerDependencyWatcher ):void {
			_dependencyWatcher = value;

			if ( value && dr ) {
				value.watchDependencyResolver( dr );
			}
		}

		public function set externalDependencyError( value:String ):void {
			externalError = true;
			_externalDependencyError = value;
		}

		//Blank constructor means the old 0/1 error
		public function Parameterized(klass:Class) {
			super(klass);
			this.klass = klass;

			dr = new ExternalDependencyResolver( klass, this );
			dr.resolveDependencies();
		}

		private function buildErrorRunner( message:String ):Array {
			return [new ErrorReportingRunner( klass, new Error("There was an error retrieving the parameters for the testcase: cause " + message ) ) ];
		}

		private function buildRunners():Array {
			var runners:Array = new Array();

			try {
				var parametersList:Array = getParametersList(klass);
				if ( parametersList.length == 0 ) {
					runners.push(new TestClassRunnerForParameters(klass));
				} else {
					for (var i:int= 0; i < parametersList.length; i++) {
						runners.push(new TestClassRunnerForParameters(klass,parametersList, i));
					}
				}
			}

			catch ( error:Error ) {
				runners = buildErrorRunner( error.message );
			}

			return runners;
		}

		private function getParametersList(klass:Class):Array {
			var allParams:Array = new Array();
			var frameworkMethod:FrameworkMethod;
			var field:Field;
			var methods:Array = getParametersMethods(klass);
			var fields:Array = getParametersFields(klass);
			var data:Array;

			for ( var i:int=0; i<methods.length; i++ ) {
				frameworkMethod = methods[ i ];

				data = frameworkMethod.invokeExplosively(klass) as Array;
				allParams = allParams.concat( data );
			}

			for ( var j:int=0; j<fields.length; j++ ) {
				field = fields[ j ];

				data = field.getObj( null ) as Array;
				allParams = allParams.concat( data );
			}

			return allParams;
		}

		private function getParametersMethods(klass:Class):Array {
			var methods:Array = testClass.getMetaDataMethods( AnnotationConstants.PARAMETERS );
			return methods;
		}

		private function getParametersFields(klass:Class):Array {
			var fields:Array = testClass.getMetaDataFields( AnnotationConstants.PARAMETERS, true );
			return fields;
		}

		// begin Items copied from Suite
		override protected function get children():Array {
			if ( !runners ) {
				if ( !externalError ) {
					runners = buildRunners();
				} else {
					runners = buildErrorRunner( _externalDependencyError );
				}
			}

			return runners;
		}

		override protected function describeChild( child:* ):IDescription {
			return IRunner( child ).description;
		}

		override public function pleaseStop():void {
			super.pleaseStop();

			if ( runners ) {
				for ( var i:int=0; i<runners.length; i++ ) {
					( runners[ i ] as IRunner ).pleaseStop();
				}
			}
		}

		override protected function runChild( child:*, notifier:IRunNotifier, childRunnerToken:AsyncTestToken ):void {
			if ( stopRequested ) {
				childRunnerToken.sendResult( new StoppedByUserException() );
				return;
			}

			IRunner( child ).run( notifier, childRunnerToken );
		}
		// end Items copied from Suite
	}
}

import flex.lang.reflect.Field;
import flex.lang.reflect.Klass;
import flex.lang.reflect.Method;
import flex.lang.reflect.metadata.MetaDataAnnotation;
import flex.lang.reflect.metadata.MetaDataArgument;

import org.flexunit.constants.AnnotationArgumentConstants;
import org.flexunit.constants.AnnotationConstants;
import org.flexunit.internals.runners.InitializationError;
import org.flexunit.internals.runners.statements.IAsyncStatement;
import org.flexunit.runner.Description;
import org.flexunit.runner.IDescription;
import org.flexunit.runner.notification.IRunNotifier;
import org.flexunit.runners.BlockFlexUnit4ClassRunner;
import org.flexunit.runners.model.FrameworkMethod;
import org.flexunit.runners.model.ParameterizedMethod;
import org.flexunit.token.AsyncTestToken;

class TestClassRunnerForParameters extends BlockFlexUnit4ClassRunner {
	private var klassInfo:Klass;
	private var expandedTestList:Array;
	private var parameterSetNumber:int;
	private var parameterList:Array;
	private var constructorParameterized:Boolean = false;

	private function buildExpandedTestList():Array {
		var testMethods:Array = testClass.getMetaDataMethods( AnnotationConstants.TEST );
		var finalArray:Array = new Array();

		for ( var i:int=0; i<testMethods.length; i++ ) {
			var fwMethod:FrameworkMethod = testMethods[ i ];
			var argument:MetaDataArgument = fwMethod.method.getMetaData( AnnotationConstants.TEST ).getArgument( AnnotationArgumentConstants.DATAPROVIDER );
			var classMethod:Method;
			var field:Field;
			var results:Array;
			var paramMethod:ParameterizedMethod;

			if ( argument ) {
				classMethod = klassInfo.getMethod( argument.value );

				if ( classMethod ) {
					results = classMethod.invoke( testClass ) as Array;
				} else {
					field = klassInfo.getField( argument.value );

					if ( field ) {
						var ar:Array = field.getObj(null) as Array;
						results = new Array();
						results = results.concat( ar );
					}
				}

				for ( var j:int=0; j<results.length; j++ ) {
					var method:Method = applyOrderToParameterizedTestMethod( fwMethod.method, j, results.length );
					paramMethod = new ParameterizedMethod( method, results[ j ] );
					finalArray.push( paramMethod );
				}
			} else {
				finalArray.push( fwMethod );
			}
		}

		return finalArray;
	}

	protected function applyOrderToParameterizedTestMethod( method : Method, dataSetIndex : int, totalMethods : int ) : Method
	{
		var xmlCopy:XML = method.methodXML.copy();

		var a:MetaDataAnnotation = method.getMetaData( AnnotationConstants.TEST );
		var arg:MetaDataArgument;

		if ( a )
			arg = a.getArgument( AnnotationArgumentConstants.ORDER );
		else	// CJP: If the method doesn't contain a "TEST" metadata tag, we probably shouldn't be in  here anyway... throw Error?
			return method;

		if ( !arg )
			xmlCopy.metadata.(@name=="Test").appendChild( <arg key="order" value="0"/> );

		var orderValueDec : Number = (dataSetIndex + 1) / ( Math.pow( 10, totalMethods ) );
		var newOrderValue : Number = xmlCopy.metadata.(@name=="Test").arg.( @key == "order" ).attribute( "value" ) + orderValueDec;

		xmlCopy.metadata.(@name=="Test").arg.( @key == "order" ).( @value = newOrderValue );
		var newMethod:Method = new Method( xmlCopy );
		return newMethod;
	}

	override protected function computeTestMethods():Array {
		//OPTIMIZATION POINT
		if ( !expandedTestList ) {
			expandedTestList = buildExpandedTestList();
		}

		return expandedTestList;
	}

	override protected function validatePublicVoidNoArgMethods( metaDataTag:String, isStatic:Boolean, errors:Array ):void {

		//Only validate the ones that do not have a dataProvider attribute for these rules
		var methods:Array = testClass.getMetaDataMethods( metaDataTag  );
		var annotation:MetaDataAnnotation;
		var argument:MetaDataArgument;

		var eachTestMethod:FrameworkMethod;
		for ( var i:int=0; i<methods.length; i++ ) {
			eachTestMethod = methods[ i ] as FrameworkMethod;

			annotation = eachTestMethod.method.getMetaData( AnnotationConstants.TEST );

			if ( annotation ) {
				//Does it have a dataProvider?
				argument = annotation.getArgument( AnnotationArgumentConstants.DATAPROVIDER );
			}

			//If there is an argument, we need to punt on verification of arguments until later when we know how many there actually are
			if ( !argument ) {
				eachTestMethod.validatePublicVoidNoArg( isStatic, errors );
			}
		}
	}

	override protected function describeChild( child:* ):IDescription {
		if ( !constructorParameterized ) {
			return super.describeChild( child );
		}

		var params:Array = computeParams();

/*		if ( !params ) {
			throw new InitializationError( "Parameterized runner has not been provided data" );
		}*/

		var paramName:String = params?params.join ( "_" ):"Missing Params";
		var method:FrameworkMethod = FrameworkMethod( child );
		return Description.createTestDescription( testClass.asClass, method.name + '_' + paramName, method.metadata );
	}

	private function computeParams():Array {
		return parameterList?parameterList[parameterSetNumber]:null;
	}

	override protected function createTest():Object {
		var args:Array = computeParams();

		if ( args && args.length > 0 ) {
			return testClass.klassInfo.constructor.newInstanceApply( args );
		} else {
			return testClass.klassInfo.constructor.newInstance();
		}
	}

	//we don't want the BeforeClass and AfterClass on this run to execute, this will be handled by Parameterized
	override protected function classBlock( notifier:IRunNotifier ):IAsyncStatement {
		return childrenInvoker( notifier );
	}

	public function TestClassRunnerForParameters(klass:Class, parameterList:Array=null, i:int=0) {
		klassInfo = new Klass( klass );
		super(klass);

		this.parameterList = parameterList;
		this.parameterSetNumber = i;

		if ( parameterList && parameterList.length > 0 ) {
			constructorParameterized = true;
		}
	}
}

/**
 * Copyright (c) 2009 Digital Primates IT Consulting Group
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * @author     Alan Stearns - astearns@adobe.com
 * 			   Michael Labriola - labriola@digitalprimates.net
 * 			   David Wolever - david@wolever.net
 * @version
 *
 **/

package org.flexunit.runners
{
	import flex.lang.reflect.Field;

	import org.flexunit.constants.AnnotationConstants;
	import org.flexunit.internals.dependency.ExternalDependencyResolver;
	import org.flexunit.internals.dependency.IExternalDependencyResolver;
	import org.flexunit.internals.dependency.IExternalRunnerDependencyWatcher;
	import org.flexunit.internals.runners.ErrorReportingRunner;
	import org.flexunit.internals.runners.InitializationError;
	import org.flexunit.internals.runners.statements.IAsyncStatement;
	import org.flexunit.runner.IDescription;
	import org.flexunit.runner.IRunner;
	import org.flexunit.runner.external.IExternalDependencyRunner;
	import org.flexunit.runner.notification.IRunNotifier;
	import org.flexunit.runner.notification.StoppedByUserException;
	import org.flexunit.runners.model.FrameworkMethod;
	import org.flexunit.runners.model.IRunnerBuilder;
	import org.flexunit.token.AsyncTestToken;

	public class Parameterized extends ParentRunner implements IExternalDependencyRunner {
		private var runners:Array;
		private var klass:Class;
		private var dr:IExternalDependencyResolver;
		private var _dependencyWatcher:IExternalRunnerDependencyWatcher;
		private var dependencyDataWatchers:Array;
		private var _externalDependencyError:String;
		private var externalError:Boolean = false;

		public function set dependencyWatcher( value:IExternalRunnerDependencyWatcher ):void {
			_dependencyWatcher = value;

			if ( value && dr ) {
				value.watchDependencyResolver( dr );
			}
		}

		public function set externalDependencyError( value:String ):void {
			externalError = true;
			_externalDependencyError = value;
		}

		//Blank constructor means the old 0/1 error
		public function Parameterized(klass:Class) {
			super(klass);
			this.klass = klass;

			dr = new ExternalDependencyResolver( klass, this );
			dr.resolveDependencies();
		}

		private function buildErrorRunner( message:String ):Array {
			return [new ErrorReportingRunner( klass, new Error("There was an error retrieving the parameters for the testcase: cause " + message ) ) ];
		}

		private function buildRunners():Array {
			var runners:Array = new Array();

			try {
				var parametersList:Array = getParametersList(klass);
				if ( parametersList.length == 0 ) {
					runners.push(new TestClassRunnerForParameters(klass));
				} else {
					for (var i:int= 0; i < parametersList.length; i++) {
						runners.push(new TestClassRunnerForParameters(klass,parametersList, i));
					}
				}
			}

			catch ( error:Error ) {
				runners = buildErrorRunner( error.message );
			}

			return runners;
		}

		private function getParametersList(klass:Class):Array {
			var allParams:Array = new Array();
			var frameworkMethod:FrameworkMethod;
			var field:Field;
			var methods:Array = getParametersMethods(klass);
			var fields:Array = getParametersFields(klass);
			var data:Array;

			for ( var i:int=0; i<methods.length; i++ ) {
				frameworkMethod = methods[ i ];

				data = frameworkMethod.invokeExplosively(klass) as Array;
				allParams = allParams.concat( data );
			}

			for ( var j:int=0; j<fields.length; j++ ) {
				field = fields[ j ];

				data = field.getObj( null ) as Array;
				allParams = allParams.concat( data );
			}

			return allParams;
		}

		private function getParametersMethods(klass:Class):Array {
			var methods:Array = testClass.getMetaDataMethods( AnnotationConstants.PARAMETERS );
			return methods;
		}

		private function getParametersFields(klass:Class):Array {
			var fields:Array = testClass.getMetaDataFields( AnnotationConstants.PARAMETERS, true );
			return fields;
		}

		// begin Items copied from Suite
		override protected function get children():Array {
			if ( !runners ) {
				if ( !externalError ) {
					runners = buildRunners();
				} else {
					runners = buildErrorRunner( _externalDependencyError );
				}
			}

			return runners;
		}

		override protected function describeChild( child:* ):IDescription {
			return IRunner( child ).description;
		}

		override public function pleaseStop():void {
			super.pleaseStop();

			if ( runners ) {
				for ( var i:int=0; i<runners.length; i++ ) {
					( runners[ i ] as IRunner ).pleaseStop();
				}
			}
		}

		override protected function runChild( child:*, notifier:IRunNotifier, childRunnerToken:AsyncTestToken ):void {
			if ( stopRequested ) {
				childRunnerToken.sendResult( new StoppedByUserException() );
				return;
			}

			IRunner( child ).run( notifier, childRunnerToken );
		}
		// end Items copied from Suite
	}
}

import flex.lang.reflect.Field;
import flex.lang.reflect.Klass;
import flex.lang.reflect.Method;
import flex.lang.reflect.metadata.MetaDataAnnotation;
import flex.lang.reflect.metadata.MetaDataArgument;

import org.flexunit.constants.AnnotationArgumentConstants;
import org.flexunit.constants.AnnotationConstants;
import org.flexunit.internals.runners.InitializationError;
import org.flexunit.internals.runners.statements.IAsyncStatement;
import org.flexunit.runner.Description;
import org.flexunit.runner.IDescription;
import org.flexunit.runner.notification.IRunNotifier;
import org.flexunit.runners.BlockFlexUnit4ClassRunner;
import org.flexunit.runners.model.FrameworkMethod;
import org.flexunit.runners.model.ParameterizedMethod;
import org.flexunit.token.AsyncTestToken;

class TestClassRunnerForParameters extends BlockFlexUnit4ClassRunner {
	private var klassInfo:Klass;
	private var expandedTestList:Array;
	private var parameterSetNumber:int;
	private var parameterList:Array;
	private var constructorParameterized:Boolean = false;

	private function buildExpandedTestList():Array {
		var testMethods:Array = testClass.getMetaDataMethods( AnnotationConstants.TEST );
		var finalArray:Array = new Array();

		for ( var i:int=0; i<testMethods.length; i++ ) {
			var fwMethod:FrameworkMethod = testMethods[ i ];
			var argument:MetaDataArgument = fwMethod.method.getMetaData( AnnotationConstants.TEST ).getArgument( AnnotationArgumentConstants.DATAPROVIDER );
			var classMethod:Method;
			var field:Field;
			var results:Array;
			var paramMethod:ParameterizedMethod;

			if ( argument ) {
				classMethod = klassInfo.getMethod( argument.value );

				if ( classMethod ) {
					results = classMethod.invoke( testClass ) as Array;
				} else {
					field = klassInfo.getField( argument.value );

					if ( field ) {
						var ar:Array = field.getObj(null) as Array;
						results = new Array();
						results = results.concat( ar );
					}
				}

				var methodXML : XML = insertOrderMetadataIfNecessary( fwMethod.method );

				for ( var j:int=0; j<results.length; j++ ) {
					var method:Method = applyOrderToParameterizedTestMethod( methodXML, j, results.length );
					paramMethod = new ParameterizedMethod( method, results[ j ] );
					finalArray.push( paramMethod );
				}
			} else {
				finalArray.push( fwMethod );
			}
		}

		return finalArray;
	}

	protected function insertOrderMetadataIfNecessary( method : Method ) : XML
	{
		var xmlCopy:XML = method.methodXML.copy();

		var a:MetaDataAnnotation = method.getMetaData( AnnotationConstants.TEST );
		var arg:MetaDataArgument;

		if ( a )
			arg = a.getArgument( AnnotationArgumentConstants.ORDER );
		else	// CJP: If the method doesn't contain a "TEST" metadata tag, we probably shouldn't be in  here anyway... throw Error?
			return xmlCopy;

		if ( !arg )
			xmlCopy.metadata.(@name=="Test").appendChild( <arg key="order" value="0"/> );

		return xmlCopy;
	}

	protected function applyOrderToParameterizedTestMethod( methodXML : XML, dataSetIndex : int, totalMethods : int ) : Method
	{
		var xmlCopy:XML = methodXML.copy();

		var orderValueDec : Number = (dataSetIndex + 1) / ( Math.pow( 10, totalMethods ) );
		var newOrderValue : Number = xmlCopy.metadata.(@name=="Test").arg.( @key == "order" ).attribute( "value" ) + orderValueDec;

		xmlCopy.metadata.(@name=="Test").arg.( @key == "order" ).( @value = newOrderValue );
		var newMethod:Method = new Method( xmlCopy );
		return newMethod;
	}

	override protected function computeTestMethods():Array {
		//OPTIMIZATION POINT
		if ( !expandedTestList ) {
			expandedTestList = buildExpandedTestList();
		}

		return expandedTestList;
	}

	override protected function validatePublicVoidNoArgMethods( metaDataTag:String, isStatic:Boolean, errors:Array ):void {

		//Only validate the ones that do not have a dataProvider attribute for these rules
		var methods:Array = testClass.getMetaDataMethods( metaDataTag  );
		var annotation:MetaDataAnnotation;
		var argument:MetaDataArgument;

		var eachTestMethod:FrameworkMethod;
		for ( var i:int=0; i<methods.length; i++ ) {
			eachTestMethod = methods[ i ] as FrameworkMethod;

			annotation = eachTestMethod.method.getMetaData( AnnotationConstants.TEST );

			if ( annotation ) {
				//Does it have a dataProvider?
				argument = annotation.getArgument( AnnotationArgumentConstants.DATAPROVIDER );
			}

			//If there is an argument, we need to punt on verification of arguments until later when we know how many there actually are
			if ( !argument ) {
				eachTestMethod.validatePublicVoidNoArg( isStatic, errors );
			}
		}
	}

	override protected function describeChild( child:* ):IDescription {
		if ( !constructorParameterized ) {
			return super.describeChild( child );
		}

		var params:Array = computeParams();

/*		if ( !params ) {
			throw new InitializationError( "Parameterized runner has not been provided data" );
		}*/

		var paramName:String = params?params.join ( "_" ):"Missing Params";
		var method:FrameworkMethod = FrameworkMethod( child );
		return Description.createTestDescription( testClass.asClass, method.name + '_' + paramName, method.metadata );
	}

	private function computeParams():Array {
		return parameterList?parameterList[parameterSetNumber]:null;
	}

	override protected function createTest():Object {
		var args:Array = computeParams();

		if ( args && args.length > 0 ) {
			return testClass.klassInfo.constructor.newInstanceApply( args );
		} else {
			return testClass.klassInfo.constructor.newInstance();
		}
	}

	//we don't want the BeforeClass and AfterClass on this run to execute, this will be handled by Parameterized
	override protected function classBlock( notifier:IRunNotifier ):IAsyncStatement {
		return childrenInvoker( notifier );
	}

	public function TestClassRunnerForParameters(klass:Class, parameterList:Array=null, i:int=0) {
		klassInfo = new Klass( klass );
		super(klass);

		this.parameterList = parameterList;
		this.parameterSetNumber = i;

		if ( parameterList && parameterList.length > 0 ) {
			constructorParameterized = true;
		}
	}
}

Refactor for performance improvement in order injection of parameterized tests.


package org.postgresql.codec {

    import org.postgresql.Oid;
    import flash.utils.Dictionary;

    import org.postgresql.CodecError;

    /**
     * The CodecFactory manages mappings between ActionScript Objects (of certain
     * Classes) and PostgreSQL column values (of certain oids). A Class can be mapped
     * to an oid registering an encoder, and an oid to a Class through a decoder.
     * Only a single mapping can exist for a given oid (or Class) at any given time.
     *
     * @see org.postgresql.Oid
     * @see Class
     */
    public class CodecFactory {

        private var _decoders:Dictionary;
        private var _encoders:Dictionary;

        /**
         * Constructor. No encoders or decoders are registered by default.
         */
        public function CodecFactory() {
            _decoders = new Dictionary();
            _encoders = new Dictionary();
        }

        /**
         * Register the given encoder to map values of the inType to the inOid. If
         * an encoder was previously registered for the same inType, it is silently
         * replaced.
         *
         * @param inType
         * @param inOid
         * @param encoder
         */
        public function registerEncoder(inType:Class, encoder:IPGTypeEncoder):void {
            _encoders[inType] = encoder;
        }

        /**
         * Register the given decoder to map values of the given outOid to the outType. If
         * a decoder was previously registered for the same outOid, it is silently replaced.
         *
         * @param outOid
         * @param outType
         * @param decoder
         */
        public function registerDecoder(outOid:int, decoder:IPGTypeDecoder):void {
            _decoders[outOid] = decoder;
        }

        /**
         * Return the decoder for the given oid
         * @param oid oid for which to find decoder
         * @return registered decoder
         * @throws org.postgresql.CodecError if no decoder has been registered for the given oid
         */
        public function getDecoder(oid:int):IPGTypeDecoder {
            if (oid in _decoders) {
                return _decoders[oid];
            } else {
                throw new CodecError("Could not find suitable decoder", CodecError.DECODE, null, oid);
            }
        }

        /**
         * Return the encoder for the given Class
         * @param value for which to find encoder
         * @return registered encoder
         * @throws org.postgresql.CodecError if no encoder is registered for the given Class
         */
        public function getEncoder(clazz:Class):IPGTypeEncoder {
            if (clazz in _encoders) {
                return _encoders[clazz];
            } else {
                throw new CodecError("Could not find suitable encoder", CodecError.ENCODE, null, Oid.UNSPECIFIED, clazz);
            }
        }

    }
}

package org.postgresql.codec {

    import org.postgresql.Oid;
    import flash.utils.Dictionary;

    import org.postgresql.CodecError;

    /**
     * The CodecFactory manages mappings between ActionScript Objects (of certain
     * Classes) and PostgreSQL column values (of certain oids). A Class can be mapped
     * to an oid by registering an encoder, and an oid to a Class through a decoder.
     * Only a single mapping can exist for a given oid (or Class) at any given time.
     *

     * Default encoders and decoders can also be registered.
     *

     * No encoders or decoders are registered by default.
     *
     * @see org.postgresql.Oid
     * @see Class
     */
    public class CodecFactory {

        private var _decoders:Dictionary;
        private var _encoders:Dictionary;

        private var _defaultDecoder:IPGTypeDecoder;
        private var _defaultEncoder:IPGTypeEncoder;

        /**
         * @private
         */
        public function CodecFactory() {
            _decoders = new Dictionary();
            _encoders = new Dictionary();
        }

        /**
         * Register the given encoder to map values of the inType to an oid. If
         * an encoder was previously registered for the same inType, it is silently
         * replaced.
         *
         * @param inType Class for which to register mapping
         * @param encoder encoder instance to use for given class
         */
        public function registerEncoder(inType:Class, encoder:IPGTypeEncoder):void {
            if (!encoder) {
                throw new ArgumentError("Encoder must not be null");
            }
            if (!inType) {
                throw new ArgumentError("Class to be mapped must not be null");
            }
            _encoders[inType] = encoder;
        }

        /**
         * Register a encoder to map values when no other encoder is suitable. If
         * a previous default encoder was specified, it is silently replaced.
         *
         * @param encoder encoder instance for default encoding
         */
        public function registerDefaultEncoder(encoder:IPGTypeEncoder):void {
            if (!encoder) {
                throw new ArgumentError("Encoder must not be null");
            }
            _defaultEncoder = encoder;
        }

        /**
         * Register the given decoder to map values of the given outOid to an ActionScript type. If
         * a decoder was previously registered for the same outOid, it is silently replaced.
         *
         * @param outOid oid for which to register mapping
         * @param decoder decoder instance to use for given oid
         */
        public function registerDecoder(outOid:int, decoder:IPGTypeDecoder):void {
            if (!decoder) {
                throw new ArgumentError("Decoder must not be null");
            }
            _decoders[outOid] = decoder;
        }

        /**
         * Register a decoder to map values when no other decoder is suitable. If
         * a previous default decoder was specified, it is silently replaced.
         *
         * @param decoder decoder instance to use for default decoding
         */
        public function registerDefaultDecoder(decoder:IPGTypeDecoder):void {
            if (!decoder) {
                throw new ArgumentError("Decoder must not be null");
            }
            _defaultDecoder = decoder;
        }

        /**
         * Return the decoder for the given oid
         *
         * @param oid oid for which to find decoder
         * @return registered decoder
         * @throws org.postgresql.CodecError if no decoder has been registered for the given oid
         */
        public function getDecoder(oid:int):IPGTypeDecoder {
            if (oid in _decoders) {
                return _decoders[oid];
            } else if (_defaultDecoder) {
                return _defaultDecoder;
            } else {
                throw new CodecError("Could not find suitable decoder", CodecError.DECODE, null, oid);
            }
        }

        /**
         * Return the encoder for the given Class
         *
         * @param value for which to find encoder
         * @return registered encoder
         * @throws org.postgresql.CodecError if no encoder is registered for the given Class
         */
        public function getEncoder(clazz:Class):IPGTypeEncoder {
            if (clazz in _encoders) {
                return _encoders[clazz];
            } else if (_defaultEncoder) {
                return _defaultEncoder;
            } else {
                throw new CodecError("Could not find suitable encoder", CodecError.ENCODE, null, Oid.UNSPECIFIED, clazz);
            }
        }

    }
}

Support for default decoders and encoders; doc cleanup.


package aerys.minko.scene.node.camera
{
	import aerys.minko.scene.controller.camera.CameraController;
	import aerys.minko.scene.data.CameraDataProvider;
	import aerys.minko.scene.node.AbstractSceneNode;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.Signal;
	import aerys.minko.type.binding.DataBindings;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Ray;

	public class AbstractCamera extends AbstractSceneNode
	{
		public static const DEFAULT_ZNEAR	: Number	= .1;
		public static const DEFAULT_ZFAR	: Number	= 500.;

		protected var _cameraData	: CameraDataProvider	= null;

		protected var _enabled		: Boolean				= true;

		protected var _activated	: Signal				= new Signal('Camera.activated');
		protected var _deactivated	: Signal				= new Signal('Camera.deactivated');

		public function get cameraData() : CameraDataProvider
		{
			return _cameraData;
		}

		public function get zNear() : Number
		{
			return _cameraData.zNear;
		}
		public function set zNear(value : Number) : void
		{
			_cameraData.zNear = value;
		}

		public function get zFar() : Number
		{
			return _cameraData.zFar;
		}
		public function set zFar(value : Number) : void
		{
			_cameraData.zFar = value;
		}

		public function get enabled() : Boolean
		{
			return _enabled;
		}
		public function set enabled(value : Boolean) : void
		{
			if (value != _enabled)
			{
				_enabled = value;

				if (_enabled)
					_activated.execute(this);
				else
					_deactivated.execute(this);
			}
		}

		public function get activated() : Signal
		{
			return _activated;
		}
		public function get deactivated() : Signal
		{
			return _deactivated;
		}

		public function get worldToView() : Matrix4x4
		{
			return worldToLocal;
		}

		public function get viewToWorld() : Matrix4x4
		{
			return localToWorld;
		}

		public function get worldToScreen() : Matrix4x4
		{
			return _cameraData.worldToScreen;
		}

		public function get projection() : Matrix4x4
		{
			return _cameraData.projection;
		}

		public function AbstractCamera(zNear	: Number = DEFAULT_ZNEAR,
									   zFar		: Number = DEFAULT_ZFAR)
		{
			super();

			_cameraData = new CameraDataProvider(worldToView, viewToWorld);

			_cameraData.zNear 	= zNear;
			_cameraData.zFar 	= zFar;

			initialize();
		}

		protected function initialize() : void
		{
			throw new Error('Must be overriden.');
		}

		public function unproject(x : Number, v : Number, out : Ray = null) : Ray
		{
			throw new Error('Must be overriden.');
		}
	}
}

package aerys.minko.scene.node.camera
{
	import aerys.minko.scene.controller.camera.CameraController;
	import aerys.minko.scene.data.CameraDataProvider;
	import aerys.minko.scene.node.AbstractSceneNode;
	import aerys.minko.scene.node.Scene;
	import aerys.minko.type.Signal;
	import aerys.minko.type.binding.DataBindings;
	import aerys.minko.type.math.Matrix4x4;
	import aerys.minko.type.math.Ray;

	public class AbstractCamera extends AbstractSceneNode
	{
		public static const DEFAULT_ZNEAR	: Number	= .1;
		public static const DEFAULT_ZFAR	: Number	= 500.;

		protected var _cameraData	: CameraDataProvider	= null;

		protected var _enabled		: Boolean				= true;

		protected var _activated	: Signal				= new Signal('Camera.activated');
		protected var _deactivated	: Signal				= new Signal('Camera.deactivated');

		public function get cameraData() : CameraDataProvider
		{
			return _cameraData;
		}

		public function get zNear() : Number
		{
			return _cameraData.zNear;
		}
		public function set zNear(value : Number) : void
		{
			_cameraData.zNear = value;
		}

		public function get zFar() : Number
		{
			return _cameraData.zFar;
		}
		public function set zFar(value : Number) : void
		{
			_cameraData.zFar = value;
		}

		public function get enabled() : Boolean
		{
			return _enabled;
		}
		public function set enabled(value : Boolean) : void
		{
			if (value != _enabled)
			{
				_enabled = value;

				if (_enabled)
					_activated.execute(this);
				else
					_deactivated.execute(this);
			}
		}

		public function get activated() : Signal
		{
			return _activated;
		}
		public function get deactivated() : Signal
		{
			return _deactivated;
		}

		public function get worldToView() : Matrix4x4
		{
			return worldToLocal;
		}

		public function get viewToWorld() : Matrix4x4
		{
			return localToWorld;
		}

		public function get worldToScreen() : Matrix4x4
		{
			return _cameraData.worldToScreen;
		}

		public function get projection() : Matrix4x4
		{
			return _cameraData.projection;
		}

		public function AbstractCamera(zNear	: Number = DEFAULT_ZNEAR,
									   zFar		: Number = DEFAULT_ZFAR)
		{
			super();

			_cameraData = new CameraDataProvider(worldToView, viewToWorld);

			_cameraData.zNear 	= zNear;
			_cameraData.zFar 	= zFar;

			initialize();
		}

		protected function initialize() : void
		{
			throw new Error('Must be overriden.');
		}

		public function unproject(x : Number, y : Number, out : Ray = null) : Ray
		{
			throw new Error('Must be overriden.');
		}
	}
}

fix typo

fix typo