Tumetsu
Tumetsu

Reputation: 1721

Create instances with string of class' name in As3

I have xml-structure where I load most of the data of my program. In this case I want to instantiate a class which is specified in xml. I figured that I could write class' name in xml, and then instantiate it and pass parameters to it. Turned out it wasn't that easy!

I tried code like this:

            //special objects
        for each (o in xml.Objects[0].special) 
        { 
            p.x = o.@x;
            p.y = o.@y;
            s.x = o.@width;
            s.y = o.@height;
            trace(o.@classname);
            //var type:Class = o.@classname as Class;
            var type:Class = getDefinitionByName(String(o.@classname)) as Class;

            trace(type);
            objectArray.push(new type(p, s)); 
            trace("special");
        }

As you can see I have the name of my class in classname attribute in xml-file. I managed to get the definition with getDefinitionByName (at least next trace shows correct class name) but when I try to instantiate it and push it into array I get pile of errors which begin

Error #2136: The SWF file file:///Users/tuomas/Dropbox/Flash/ScorpionBox/bin-debug/ScorpionBox.swf contains invalid data.

Any idea how I should go with this?

Upvotes: 1

Views: 6299

Answers (1)

Jason Sturges
Jason Sturges

Reputation: 15955

Presuming your XML type definitions consisted of qualified names as obtained by getQualifiedClassName(), instantiate the type and apply properties as needed.

Example instantiation of display objects defined by xml:

package
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.utils.getDefinitionByName;

    public class XmlParser extends Sprite
    {
        public var xml:XML = <objects>
                                <object type="flash.display::Sprite" x="0" y="0" width="100" height="100" />
                                <object type="flash.display::MovieClip" x="0" y="0" width="100" height="100" />
                             </objects>;

        public function XmlParser()
        {
            for each (var object:XML in xml.children())
            {
                var type:Class = getDefinitionByName(object.@type) as Class;
                var instance:DisplayObject = new type();
                instance.x = object.@x;
                instance.y = object.@y;
                instance.width = object.@width;
                instance.height = object.@height;

                addChild(instance);
            }
        }
    }
}

You could also describeType objects when serialized to XML, then apply properties back to the object instance by iterating attributes of the XML, such as:

package
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.utils.getDefinitionByName;

    public class XmlParser extends Sprite
    {
        public var xml:XML = <objects>
                                <object type="flash.display::Sprite" x="0" y="0" width="100" height="100" />
                                <object type="flash.display::MovieClip" x="0" y="0" width="100" height="100" />
                             </objects>;

        public function XmlParser()
        {
            for each (var object:XML in xml.children())
            {
                var type:Class = getDefinitionByName(object.@type) as Class;
                var instance:DisplayObject = new type();
                addChild(instance);

                for each (var attribute:XML in object.@*)
                {
                    if(attribute.name() == "type") { continue; }

                    trace("setting: " + attribute.name() + " = " + attribute.toXMLString());
                    instance[attribute.name().toString()] = attribute.toXMLString();
                }
            }
        }
    }
}

Upvotes: 4

Related Questions