Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating multiple read-only properties dynamically in AS3

I have a class which at the moment is quite messy/repetitive:

public class AvFramework extends Object
{
    // vars
    private var _handler:AvHandler;
    private var _keyboard:AvKeyboard;
    private var _manager:AvManager;

    /**
     * Constructor
     */
    public function AvFramework()
    {
        _handler = new AvHandler();
        _keyboard = new AvKeyboard();
        _manager = new AvManager();

        // attach
        _handler.framework = this;
        _keyboard.framework = this;
        _manager.framework = this;
    }

    /**
     * Getters
     */
    public function get keyboard():AvKeyboard{ return _keyboard; }
    public function get manager():AvManager{ return _manager; }
}

This class is only going to need to make use of more and more classes, and I don't really want to have 3 huge lists for this like above.

Is there a way to do the above dynamically - maybe using getDefinitonByName() in a loop of strings to represent the classes I want to create.

I also want the properties to be read-only and to be accessed via framework.myDynamicVarHere.

I'm thinking something along these lines:

  1. I create a list of the classes I want to create instances of, paired with the variable name they should be accessed by.
  2. I will need to make the class dynamic so that I can set the vars via this["var"] = new Blah();

Quick snippet of where my thoughts are going:

var required:Object =
{
    keyboard: "avian.framework.background.AvKeyboard",
    manager: "avian.framework.background.AvManager",
    handler: "avian.framework.background.AvHandler"
};

var i:String;
for(i in required)
{
    var Req:Class = Class(getDefinitionByName(required[i]));

    this[i] = new Req();
    AvFrameworkObject(this[i]).framework = this;
}

Just not sure how I would be able to make these read-only.

like image 410
Marty Avatar asked Jun 03 '11 03:06

Marty


2 Answers

You can use Proxy class to control get/set call and complete Eugeny89 answer. Look at http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html or http://blog.joa-ebert.com/2007/05/25/as3-proxy-example/

var required:Object =
{
    keyboard: "avian.framework.background.AvKeyboard",
    manager: "avian.framework.background.AvManager",
    handler: "avian.framework.background.AvHandler"
};
...

import flash.utils.Proxy;
import flash.utils.flash_proxy;
public dynamic class AvFramework extends Proxy { 
    private var holder: Object = {};

    public function AvFramework() {
        var i:String;
        for(i in required)
        {
            var Req:Class = Class(getDefinitionByName(required[i]));
            var name = //get Class name from required[i] e.g. AvKeyboard from avian.framework.background.AvKeyboard
            holder[name] = new Req();
            holder[name].framework = this;
        }
    }

    flash_proxy override function getProperty( name: * ): *
    {
        return holder[name];
    }

    flash_proxy function setProperty(name:*, value:*):void
    {
        // Do nothing
    }
}

With this code, when you do myAvFrameworkObj.something, getProperty() is automaticaly call and you get property name from "name" variable.

like image 196
Simon Eyraud Avatar answered Sep 22 '22 14:09

Simon Eyraud


Maybe you'll try to wrap that long list of classws in object:

var required:Object =
{
    keyboard: "avian.framework.background.AvKeyboard",
    manager: "avian.framework.background.AvManager",
    handler: "avian.framework.background.AvHandler"
};
...

public class AvFramework extends Object { 
    private var holder: Object;

    public function AvFramework() {
        holder = new Object();

        var i:String;
        for(i in required)
        {
            var Req:Class = Class(getDefinitionByName(required[i]));
            var name = //get Class name from required[i] e.g. AvKeyboard from avian.framework.background.AvKeyboard
            holder[name] = new Req();
            holder[name].framework = this;
        }
    }

    public var getHolder() { return holder; }
}

You can refer to e.g. AvKeyboard by framework.getHolder()["AvKeyboard"] or even by framework.getHolder()[someVar]. So all this classes from required are read-only, as holder is read-only.

Hope that'll help you!

like image 43
Eugeny89 Avatar answered Sep 24 '22 14:09

Eugeny89