Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with SWCs - getDefinitionByName issue

I have a bunch of graphics assets in a fla, the MovieClips are linked to some classes. I export the fla as a swc , which I add to my library with the option "Merged into Code".

All works great, I can create instances of my MovieClips , just by calling their classes like this.

     //example 1
     var newMc:BaseClass = new GraphicAsset();

Now if I want do the following , Flash throws an error , GraphicsAssetClass is null!

    //example 2
    var GraphicsAssetClass:Class = getDefinitionByName("GraphicAsset") as Class;

The only way I can get the above line to work is to do this

    //example 3
    var newMc:GraphicAsset;
    var GraphicsAssetClass:Class = getDefinitionByName("GraphicAsset") as Class;

    //then I'm able to do this 
    var newMc:BaseClass = new GraphicsAssetClass();

Can you think of a solution where I could simply get the class by calling getDefinitionByName() like I do on example 2 , without having to resort to example 3 solution.

like image 607
PatrickS Avatar asked Nov 05 '10 04:11

PatrickS


2 Answers

The problem is that the compiler will exclude any class that is not referenced directly somewhere in your code. This is an optimization that the compiler applies by design.

The normal way around this is exactly as you have shown in your "example 3". But it's important to note that the two lines don't have to be together in the same place. As long as

var newMc:GraphicAsset;

is somewhere in your SWF that is being referenced from the main path of execution, then the class definition for GraphicAsset will be included in the final swf. Then you can call...

var GraphicsAssetClass:Class = getDefinitionByName("GraphicAsset") as Class;

from somewhere else entirely, and it'll work as you expect.

It's even possible (and quite common) to find the two lines in seaprate SWFs. In this case, one swf would load the other swf at runtime. Typically, the loader swf would be the one using getDefinitionByName("SomeClass), and the loaded swf would be the one that defines class SomeClass, and uses var a:SomeClass;, to ensure that the class gets built into the swf.

For this reason, you often find a class called something like "MyLibraryManifest" defined in a "library swf", and then referenced from that swf's main movie clip. The "manifest" class then would simply look like this:

class MyLibraryManifest {

   private var a:GraphicAsset;
   private var b:SomeClass;
   private var c:SomeOtherClass;

   //... and so on...

}

[edit] You can use the -includes or -include-libraries options to the mxmlc compiler, to force the linker to include one or more individual classes (or an entire swc), without applying the "pruning optimization" I described above.

see adobe's site for explanation of the mxmlc command line options.

The options can also be specified in a config file, allowing you to control how flex and/or the Flash IDE will invoke the compiler behind the scenes.

good luck!

like image 73
Lee Avatar answered Nov 02 '22 01:11

Lee


Using FlashDevelop this is pretty simple to fix.

Right click your included swc from the Project list. Choose options then "include library (complete library)".

..you can now use getDefinitionByName to get a unreferenced class from your swc file.

like image 20
Daniel Avatar answered Nov 02 '22 00:11

Daniel