Some favorite site feeds aggregated locally: iPhone Development RSS   Adobe Labs RSS   Macrumors RSS

Tuesday, September 11, 2007

as3: a *generic* COMPLETE listener for Loader

Tuesday, September 11, 2007   

Today I was banging my head up against the notion of loading multiple things and using a single COMPLETE event to serve them all. My head was banging against getting the actual instance of who was being loaded into for the event. I didn't see this covered anywhere online or in the documentation, but I imagine that TONS of AS3 developers would prefer this approach (opposed to setting up multiple COMPLETE events for different loaders).

I was checking event.target (which gives you the LoaderInfo object, but I wanted to get the actual Loader object & the .name I assigned it). In this way I could assign variables to the content of the clips I was loading into easily. It took a while and another pair of eyes (thanks Andrew O.), and we imported the LoaderInfo object, did a little casting, and using the .name property, are able to easily reference loaded stuff (say code/elements in SWFs) in a document class. This is the basic code showing whats going on.


In two different SWFs that get loaded into the AS3 document class are simple variables (just to test that the document class can get in there): var iam:String = "viewX.swf";. Each SWF has their own file name populating the variable. Now for the important bits in the document class (typing this by hand as an example... the indention is probably off):
package net.ericd.base
{
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.*
import flash.display.Stage;
import flash.net.URLLoader;
import flash.net.URLRequest;

import flash.display.Loader;
import flash.display.LoaderInfo;

public class Application extends Sprite
{
private var FOO:Object;
private var BAR:Object;

private function loadViewElements():void
{
var loader1:Loader = new Loader();
var loader2:Loader = new Loader();

loader1.name = "foo";
loader2.name = "bar";

var mc1_URL:URLRequest = new URLRequest( "views/view.swf" );
var mc2_URL:URLRequest = new URLRequest( "views/view2.swf" );

loader1.load( mc1_URL );
loader2.load( mc2_URL );

loader1.contentLoaderInfo.addEventListener(
Event.COMPLETE, onClipLoaded );
loader2.contentLoaderInfo.addEventListener(
Event.COMPLETE, onClipLoaded );

var foo_holder:MovieClip = new MovieClip();
foo_holder.addChild( loader1 );
addChild( foo_holder );

var bar_holder:MovieClip = new MovieClip();
bar_holder.addChild( loader2 );
addChild( bar_holder );
}

private function onClipLoaded( event:Event ):void
{
// Need to get Loader from LoaderInfo!!
trace( event.target ); //[object LoaderInfo]
var loaderInfo:LoaderInfo = event.target as LoaderInfo;

// Important code below:
trace( loaderInfo.loader ); // [object Loader]
var myName:String = loaderInfo.loader.name;

// Now we can do this:
if( myName == "foo" )
{
// We can reference the cont
FOO = event.target.content;
trace( FOO.iam ); // view.swf

} else if( myName == "bar" )
{
BAR = event.target.content;
trace( BAR.iam ); // view2.swf
}
}
}
}
For me, this is going to save me TONS of time and coding to have a single COMPLETE function work for me in this kind of context. I was looking for something a little more like MovieClipLoader but we don't have that in AS3 which is perfectly fine with me. Just a different hurdles to navigate here.

I thought some might benefit from seeing this because I didn't see an example of it online. Perhaps this is super-common knowledge for those already traversing the waters of AS3, but it wasn't for me. It was time well spent though. Hope someone can learn from this to make their lives easier too.
 
 Return to the main page
Comments:

There are currently 8 Comments:

Blogger Leif said...
“Eric,

Sorry to bug you in the comments. Did you create the MAX badge that you have in the right column (the one that counts down for Chicago)?

If so, may I have a copy of the swf for my user group sites?

If not, where did you get it?

leif [dot] wells [at] augatlanta [dot] org”
 
Blogger e.dolecki said...
September 11, 2007 4:49 PM
“I did indeed make the badge. Go ahead and grab the SWF if you want:

http://www.ericd.net/swf/maxBadge.swf
120x60

If you want the source, let me know.”
 
Anonymous Mike J said...
September 12, 2007 10:11 AM
“Not sure if it will work or not, but why not look at trying to compare against the loaders themselves, so you don't have random string references in the code ( ala magic numbers ).

You'd need to make them module level declarations for the loaders, but if you were going to try and remove the strings out you'd need to declare constants to compare against anyway, and using the actual loader instance is more generic for expanding and changing things in the future.

if ( loaderInfo.loader == loader1 ) {
FOO = event.target.content;
}”
 
Blogger e.dolecki said...
September 12, 2007 10:36 AM
“trace( loaderInfo.loader );
= [object Loader]

(for each loader). I can't see how to get the instance of the loader itself.


trace( event.target.loader.name );
= the .name (works)”
 
Anonymous Mike J said...
September 12, 2007 3:17 PM
“I know the formatting won't work well, but I was able to get this to work, which takes magic strings out of the equation:

protected var fooLoader:Loader;
protected var barLoader:Loader;

protected function createChildren():void {
var url:String = "autofill.png";

fooLoader = new Loader();
fooLoader.name = "foo";
fooLoader.contentLoaderInfo.addEventListener(
Event.COMPLETE, onItemLoaded, false, 0, true );
fooLoader.load( new URLRequest( url ) );
addChild( fooLoader );

barLoader = new Loader();
barLoader.name = "bar";
barLoader.contentLoaderInfo.addEventListener(
Event.COMPLETE, onItemLoaded, false, 0, true );
barLoader.load( new URLRequest( url ) );
barLoader.x = 30;
addChild( barLoader );
}

protected function onItemLoaded( e:Event ):void {
var myinfo:LoaderInfo = e.target as LoaderInfo;
var myloader:Loader = myinfo.loader;
trace( "IS FOO : " + [ ( myloader == fooLoader ), myloader.name ] );
trace( "IS BAR : " + [ ( myloader == barLoader ), myloader.name ] );
}”
 
Blogger e.dolecki said...
September 12, 2007 3:44 PM
“Well, I'll be darned. That indeed works. One has to define the loaders ahead of time which is acceptable, and one does get the loaders in the event. Nice find there!”
 
Anonymous Greg North said...
October 22, 2008 12:07 AM
“I'm glad I came across this page while googling. It saved me a whole night of work-around code.

Thanks!”
 
Blogger girobai said...
July 31, 2009 5:08 AM
“thanks e.dolecki !! very useful”
 
 Leave a comment