More on preloaders: passing the loaderInfo

I previously made 2 posts on the topic of preloaders (The right way to do a preloader in AS3, External Preloader; more complex cases), well this post will be a continuation of those. And one that I believe not everyone will agree with me. I know that because I didn’t agree with it at first but the more I thought about it the more it felt right.

When it comes to code I’m a bit of a fascist, I have trouble accepting habits of other coders if they are not the same as mine. So when I see something different my first reaction is to frown upon it (I am talking just about code; I am a very open minded person). When I first saw this mean of passing variables from the preloader to the main application that a coworker was doing I didn’t quite like it.

In the post about the more complex preloaders, I showed how to use an interface to pass data from the preloader to the loaded (main) movie. Now this part of the code is still the same. What changes is that instead of passing the flashVars (variables that are passed to the flash from the html embed code or javascript) individually inside fo the init method of the Main class (also in the interface), we pass them all together by giving the root.loaderInfo instead.

I already know what you are going to say: this is not strictly typed so it is bad. I know, I know, but if you think about it a bit you see that at some point the flashVars are not typed anyway; when they transition from html to flash. So what is the harm of perpetuating this just one level more? In the init method inside the Main class, the first thing I do is that I type the parameters passed, so I do end up typing my variables.

Now, you’re going to ask what do you gain from this? Well, since the preloader is an external file, every time you are going to pass more variables to the Flash from the HTML, you will have to modify 3 files : the preloader.fla, the IMain.as and the Main.as. Now if you pass the loaderInfo instead of the individual flashVars, you will only need to modify the Main.as since it is there that you type the variables. You completely bypass the preloader, which in a way make sense since your preloader doesn’t need to know about your application, all it does is to load it. once your preloader is completed you don’t ever have to touch it again.

Here is some code to illustrate this. In the preloader :

var mainContent:IMain;
function onLoadComplete(event:Event):void{ // this would be the function that the loader would call when the loading is completed
  mainContent = IMain(loader.content);
  addChild(Sprite(mainContent) );
  mainContent.init( root.loaderInfo);
}

And in the Main class :

package{
  import com.zedia.interfaces.IMain;
  import com.display.Sprite;
  import com.display.LoaderInfo;
 
  public class Main extends Sprite implements IMain{
    public function init(loaderInfo:LoaderInfo):void{      
      var flashVar1:String = String(loaderInfo.parameters.flashVar1);
      var flashVar2:Number = Number(loaderInfo.parameters.flashVar2);
      //do something with the FlashVars
    }
  }
}

, , ,

  1. #1 by Steve Kudirka - January 20th, 2010 at 18:43

    Hmmm. Does look a little awkward at first, and felt the same way you did. I usually pass the FlashVars via an interface as well. But this seems to make things easier and less of a hassle when adding or removing a FlashVar without having to update the interface. May have to implement this on the next project. Thanks for sharing.

  2. #2 by sharedtut - January 21st, 2010 at 15:12

    thank you for showing the source code

  3. #3 by b. - February 12th, 2010 at 07:21

    Great approach: One thing bugs me though, hopefully you have an insight:

    During development, every time you test your movie, the Main class will ‘hang’ since the init-method isn’t called (gets only called by the preloader).
    Ofcourse, you can bypass this (during development) by calling init() in the constructor of Main, but that means code-changing every time you want to make a release version (with preloader) and a development version (without preloader)

    I’ve been checking, but haven’t found an elegant solution: It would be great if in Mains constructor, you could write something like:

    public function Main()
    {
    if (!loadedByPreloader) { init(); }
    }

    Question is, how can the ‘loadedByPreloader’ variable be defined?

    thanks for any insights.

  4. #4 by zedia.net - February 12th, 2010 at 11:17

    It’s funny because I stumbled on the solution for this just yesterday. If you check for Capabilities.playerType == “StandAlone” you will know that you are testing locally so you can call the init function. That way you don’t have to change code to release.

  5. #5 by b. - February 12th, 2010 at 16:30

    That’s interesting: should get the job done!
    Of course, dragging the main.swf file to your standalone Flash Player would still hang the app.

    I just found this to be working too:

    public function Main()
    {
    if (this.parent) { init(); }
    }

    if loaded directly, this.parent returns the Stage object,
    if loaded from the loader, this.parent returns null.

  6. #6 by Øyvind Nordhagen - May 5th, 2010 at 22:57

    What I do is I’ll use a singleton FlashVars class that defines all the vars I’m expecting with their types. When root.loaderinfo completes in the preloader, I populate this FlashVars instance. (I actually use a generic FlashVarsImporter class that types the vars for me).

    Then I load the main movie, which upon initialization references the same FlashVars instance. The instance raised by the preloader will always shadow the instance created in the loaded movie, so I know I’m using updated values. In the case of using the movie without the preloader, I can always have that run on the dummy/default values assigned to the properties in FlashVars.

(will not be published)
Subscribe to comments feed