Ted Patrick > { Events & Community } > Adobe Systems


_level0 as a Class Instance

There is an interesting bit of code for making the root of your movie a class instance. This eliminates an extra nested movieclip and makes things much cleaner. Plus it works with AS2.&

This essentially makes the movie a class instance and all objects/properties/movieclips are within the class instance. Notice the lack of an import statement and that there are zero clips in the library.

Source Example

//modify the inheiritance chain to point to a Class
this.__proto__ = Application['prototype']

//call the Class constuctor targeting the root or this
_global.Application.apply( this , [] )


Anytime you want to call a method you can go any of the following:

this.myMethod()
_level0.myMethod()
_root.myMethod()


Now if we could only find a way to create forms and views at runtime without predefined library movieClips. Looks like a job for FLOW!

Cheers,

Ted ;)

9 Responses to “ _level0 as a Class Instance ”

  1. # Anonymous al

    hey,

    for me it's look more than an ugly hack than a helpfull. which sense should it make and where is the problem storing a reference of the _root timeline in my App class?

    For me there is no advantage, because i only have 2 lines in an AS2 project in my Main.fla/swf.

    import Application;
    Application.main( this );

    the rest will all be done in classes, no more timeline script for now, it's so cool.

    yours
    al  

  2. # Blogger Ted Patrick

    Al,

    The problem with your solution is that you are treating Application as a static class with a main method and passing a reference to the main timeline.

    1. No use of constructor
    2. No use of super
    3. 'this' is distorted in Application
    4. All methods must hard code a reference to _root

    The example I posted used 'this' within the constructor and within the myMethod and everything works perfectly.

    I feel pretty strongly that Application should be a class instance rather than a static class.

    Even though I use AS1, it doesn't mean that the solution is incorrect or invalid. You cannot correctly make _level0 a class instance without using this methodology in AS1. Just keep in mind that prior to compilation AS2 is converted to AS1.

    My 2 cents.

    Ted ;)  

  3. # Anonymous Al

    hey,

    i think you misunderstood me.
    When I'm makin a new AS2 Project,
    my Application Class is for shure a Singleton not a static. That means

    function main(timeline) {

    Application._instance = new Application(timeline);

    }

    I store timeline in a private member and get access all the way by

    Application.getInstance().getTimeline();

    so I have a central Point. I rather don't use any timelinescript anymore in a AS2 project. This is the cleanest way for me and make me no Problem at all.

    Inheritance in AS2 is in my opinion a diffrent thing than in AS2.

    But I zhink diffrent people make diffrent code ;) so long

    yours
    al  

  4. # Blogger Ted Patrick

    Al,

    Your Application class has 1 static property _instance and a static 'main' function. Things are getting worse as we peel this onion.

    To provide your 'Singleton' design you have embedded an application instance into the Class itself as a static property.

    'this' is completely distorted and you are abstracted from the base timeline. Considering that if anyone else wanted to call a method, they would have to say:

    _global.Application._instance.method()

    It seems like a wasted effort to me. I would rather have 2 confusing lines in my app, than have every Application methods work in a convoluted manner. Not to mention every other method must call your Application in a convoluted way.

    Do what you want but it seems much more complex and confusing than what I posted originally. Plus working in your model make composition very difficult if not impossible to implement.

    Not to mention that should anyone call Application.main() again, your applicaiton and its state is as good as toast.

    Plus using my model, you already have a global reference to the singleton Applicaiton instance, _level0! Can't get easier than that.

    Sorry to be so harsh but I just do not understand why you are making things so hard on yourself.

    Cheers,

    Ted ;)  

  5. # Blogger Ted Patrick

    Just to add a bit to the original post, if your Applciation class supports constructor arguments, just pass those into the apply call as follows:

    _global.Application.apply( this , [Arg1,Arg2,Arg3] )  

  6. # Anonymous Collin Peters

    Any reason of using "_global.Application.apply( this , [] )" instead of just "Application.apply( this , [] )"?

    Reason being is that if your class is not in the same dir as the fla (i.e. you need an import), then it doesn't work.

    import com.domain.Application;

    //bind class to root movie
    this.__proto__ = Application['prototype']
    Application.apply( this , [] )

    //call method
    this.myMethod()  

  7. # Blogger Ted Patrick

    I always use _global to prevent the lookup within the inheiritance chain. The only reason _global works is it is the last lookup before a lookup returns undefined.

    If it works for you without _global, do that instead. The first line of code should take care of class importing automatically but this case seems to break that theory.

    Good catch.

    Ted ;)  

  8. # Anonymous Anonymous

    FYI found this on the mtasc mailing list

    -------------------------
    http://www.powersdk.com/ted/2005/02/level0-as-class-instance.php

    Is there any way to accomplish this mtasc? I get an error saying the
    function 'apply' doesn't exist which is true on the class level... but
    shouldn't we be able to call the constructor via apply?
    --------------------------
    Yes.
    Simply replace "this" with "_root".

    Nicolas
    --
    MTASC : no more coffee break while compiling
    ---------------------------




    -Will  

  9. # Anonymous Joan Ganet

    Is never too late :)
    If you want to use packages anyway:

    import com.domain.Application;
    this.__proto__ = Application['prototype'];
    var app = Application;//no type checking here, that's the price..
    app.apply (this, []);

    Very helpful Ted :)
    Cheers!  

Post a Comment



© 2008 Ted On Flex