AS3 Настройка изменения типа класса во время выполнения - PullRequest
1 голос
/ 14 марта 2011

У меня есть класс и отслеживание его типа с помощью flash.utils.describeType (this)

class Data extends EventDispatcher
        {
        public function Data()
            {
            //constructor
            }

        public override function toString():String
            {
            return describeType(this);
            }
        }


<type name="Data" base="flash.events::EventDispatcher" isDynamic="false" isFinal="false" isStatic="false">
    <extendsClass type="flash.events::EventDispatcher"/>
    <extendsClass type="Object"/>
    <implementsInterface type="flash.events::IEventDispatcher"/>
    </type>

Можно ли переопределить эту информацию, например type. @ IsDynamic, а также extendsClass. @ Type, во время выполнения? без байт-кода?

Ответы [ 5 ]

3 голосов
/ 14 марта 2011

Лучшая альтернатива для этого - использовать композицию и просто инкапсулировать нужный вам класс. Таким образом, вы можете избежать динамического ключевого слова и необходимости менять значение расширения.

public class Data extends TheClassYouNeedToExtend
{
    private var encapsulated : TheRealData;

    private var value : int;

    public function Data()
    {
        encapsulated = new TheRealData;
    }

    public function get dynamicValue() : int
    {
        return value;
    }

    public function get dataValue() : int
    {
        return encapsulated.value;
    }
}
0 голосов
/ 15 марта 2011

сейчас работает. Последний пост был чем-то постыдным для какой-то части бананов. вот почему я бросил еще одно письмо. для аксессуаров мне пришлось пройти долгий путь. oldschool javascript ...

пакет { import flash.display.DisplayObject; импорт flash.display.Sprite; импорт flash.events.Event; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; import flash.utils.describeType;

public class Main extends Sprite 
    {

    public function Main():void 
        {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
        }

    private function init(e:Event = null):void 
        {
        removeEventListener(Event.ADDED_TO_STAGE, init);

        var C:Class = Class(extend(D, Sprite));
        var O:Object = _new(C);

        var s:Sprite = new Sprite();
        O.addEventListener('asddas',event);
        O.dispatchEvent(new Event('asddas'));
        O.addChild(s);

        O.graphics.clear();
        O.graphics.beginFill(0x000000,1);
        O.graphics.lineStyle(1, 0x000000, 1, true, "none"); 
        O.graphics.drawRect(0, 0, 100, 100);
        O.graphics.endFill();       

        trace(O.getChildAt(0), O.numChildren, O.width, O.prototype.extend.width, O.hasEventListener('asddas'), O.willTrigger('asddas'), O.mouseY, O.mouseEnabled);

        addChild(O.prototype.extend);
        }   


    private function event(e:Object):void
        {
        trace(e.type);
        }

    private function _new(A:Class):Object
        {
        if (A.prototype.extend)
            {
            var O:Object = new A();
            var E:Object = new A.prototype.extend(); 
            var xml:XML = describeType(E);          
            trace(xml);

            O = copy(O, E, xml.method);
            O = copy(O, E, xml.variable);
            O = copy(O, E, xml.constant);
            O = copy(O, E, xml.accessor);

            O.prototype = { }; O.prototype.extend = E;
            return O;
            }
        else return new A(); //->
        }

    private function extend(A:Object, B:Object, b:Boolean = false):Object
        {
        var xml:XML = describeType(B);

        A.prototype.extend = B;
        A = copy(A, B, xml.constant);
        A = copy(A, B, xml.variable);
        A = copy(A, B, xml.method);
        A = copy(A, B, xml.accessor);

        return A;
        }

    private function copy(A:Object, B:Object, xml:XMLList):Object   
        {
        var node:XML

        for each(node in xml)
            {
            try { A[node.@name] = B[node.@name] } catch (e:Error) { trace('fail: '+node.@name) };
            }

        return A;
        }


    }

}

пакет
{

public dynamic class D
    {
    public static var abc:String = 'adsda';
    public const abd:String = '23223';
    private var width:Number;

    public function D() 
        {

        }

    public function toString():String 
        {
        return 'object';
        }   


    }

}
0 голосов
/ 15 марта 2011

Это не проблема, чтобы расширить два класса во время выполнения. Я работаю с примером прошлым вечером, но он не безглючный, потому что он мне сейчас не понадобится.

это очень просто с описанием типа. я не могу избавиться от динамики, но это не проблема. У меня нет моего примера на этом компьютере, вот что я могу придумать:

//D == public dynamic class;
var C:Class = extend(D,EventDispatcher);


function _new(A)
{
if(A.prototype.extend)
  {
  //hehe
  for(var i in A.prototype.extend)
    {
    //BANG!
    //copy proterties
    }
  return new A();
  }
else return new A();
}


function extend(A,B,b=false)
{
var C = A;

if(!b)
 {
 C = xtend(C,B,xml.extendClass);
 C = xtend(C,A,xml.extendClass);
 }

C = copy(C,B,xml.constant);
C = copy(C,A,xml.constant);
C = copy(C,B,xml.variable);
C = copy(C,A,xml.variable);

return C;
}


function xtend(A,B,xml)
{
for(var i in xml)
    {
    var C:Class = Class(getDefinitionByName(xml[xml.length()-Number(i)-1]));
    A = extend(A,C,true);

    if(!A.prototype.extend) A.prototype.extend = [];
    A.prototype.extend.push(C);
    }

A.prototype.extend = A.prototype.extend.unique();
return A;
}


function copy(A,B,xml)
{
for each(var node in xml)
    A[node.@name] = B[node.@name];

return A;
}

это будет 200-300 линейное решение.

0 голосов
/ 15 марта 2011

Нет, xml основан на признаках в байт-коде, когда класс загружается.Вы не можете переопределить классы, загружая новые, поэтому вы застряли с первым определением класса.

0 голосов
/ 14 марта 2011

Есть способ сделать то, что вы хотите сделать, но прежде чем я объясню это, я хотел бы сказать несколько вещей:

1) Это НЕ лучшая практика - есть причина, по которойкод работает так, как работает, и каждый раз, когда вам кажется, что вам нужно полностью изменить работу AS3 (например, путем изменения класса на динамический во время выполнения), тогда очень полезно сесть и выяснить,действительно лучшее, что можно сделать.Скорее всего, существует существующий шаблон проектирования, который поможет вам решить конкретную проблему, которую вы пытаетесь решить.

2) Если вы используете секреты, которыми я собираюсь поделиться с вами, то он станет рядом сдругие пользователи не могут понять ваш код.Может быть, вы работаете соло над хобби-проектом, и это хорошо - но если вы в команде, или если вы один из множества людей, делающих обновления для очень сложного проекта, будьте готовы ко всем, кто прикасаетсяэтот код после того, как вы прокляли свое имя.:)

Что сказал, готов?

Вы можете изменить поведение класса, изменив его свойство .prototype.Например, допустим, у меня есть класс MyClass, который имеет только один метод, «myMethod ()».Но по какой-то причине во время выполнения мне нужно добавить новый метод ("myNewMethod ()") в класс.

Я делаю это, создавая функцию с именем "myNewMethod ()" в любом классе, где яработая в. Затем я передаю ссылку на эту функцию в прототип MyClass.Обратите внимание, что, поскольку вы изменяете правила здесь, вам придется использовать строковые литералы в качестве имен функций, чтобы избежать ошибок компилятора.

Вот пример кода:

var test1:MyClass = new MyClass();
test1.myMethod() // works just fine
test1.anotherMethod() // compiler error - this method does not exist in MyClass! Can't compile.

MyClass.prototype["anotherMethod"] = function ():void { trace("anotherMethod!"); }

test1.anotherMethod(); // error - as far as the compiler knows, anotherMethod doesn't exist. Still can't compile.

test1["anotherMethod"]() // this works!

Довольнокруто, да?

Тем не менее, НЕ ДЕЛАЙТЕ ЭТОГО В ПРОИЗВОДСТВЕННОМ КОДЕКСЕ, ЕСЛИ ВЫ НЕ ЗНАЕТЕ, ЧТО ВЫ ДЕЛАЕТЕ!Есть лучшие способы достижения подобных результатов, и ваши товарищи по команде, вероятно, будут вам благодарны.

...