LazyXMLLoader: loading MovieClips or SWF files

The above example loads several .swf files into another swf file using BulkLoader’s LazyXMLLoader. You can download the example files here.

This example uses the BulkLoader LazyXMLLoader class, which is convenient as most of the time, you load multiple photos or swf files or videos from an XML file. Press the start button to see it in action.

The Basic Code

// import the bulkloader classes
	import br.com.stimuli.loading.BulkLoader;
import br.com.stimuli.loading.lazyloaders.*;
import br.com.stimuli.loading.loadingtypes.*;

public class Main extends MovieClip {           

public var _bulkLoader:LazyXMLLoader; 

public function Main():void {

_bulkLoader = new LazyXMLLoader("SWFs.xml", "loadSomeMovies",1);
_bulkLoader.addEventListener(LazyBulkLoader.LAZY_COMPLETE,
onLazyComplete);
_bulkLoader.addEventListener("complete", completeHandler);
_bulkLoader.addEventListener("progress", progressHandler);}

LazyBulkLoader.LAZY_COMPLETE is a special event that lets you know that the XML file has been downloaded and parsed. You can then attach event listeners for each individual load:

public function onLazyComplete(evt : Event):void {
for each (var item:LoadingItem in _bulkLoader.items) {
item.addEventListener("complete", onMovieLoaded);
item.addEventListener("progress", onMovieProgress);   }
}

Using currentTarget to retrieve the ID for BulkLoader

In my example, when an individual item (in this case, a swf file) loads, it calls the onMovieLoaded event, and the currentTarget of that event has an ID which is the same as the ID BulkLoader uses for that item.

private function onMovieLoaded(e:Event) {
var itemSWF:MovieClip =
_bulkLoader.getMovieClip(e.currentTarget.id); 

Unique IDs are really key to using BulkLoader – it allows you to control which element is being loaded (if, say, you want to pause other elements and force an item to load first) and also you need it to tell BulkLoader what to do with the item being loaded.

How to prepare your XML file for use with LazyXMLLoader

When you use the LazyXMLLoader class, you use special kind of xml file. See the example or check out the BulkLoader site. When you use this xml file, there is a tag that allows the LazyXMLLoader class to generate a unique id from each file name:

Telling LazyXMLLoader to create auto-ids

<allowsAutoIDFromFileName>true</allowsAutoIDFromFileName>

So, for my file, the filename was Movie_1.swf…which makes LazyXMLLoader create an id, “Movie_1″ (file extensions, such as .swf, and .jpg are removed). So, when the event fires…the currentTarget.id of the event is, “Movie_1″.

You can then use the loadNow() function to call an individual item (and pause everything else from loading):

_bulkLoader.loadNow(put-your-id-here);
trace(put-your-id-here);
// trace the id to make sure it's correct

So when you trace that item, it should be “Movie_1″.

Another example, when loading SWF files, treat it as a MovieClip:

var itemSWF:MovieClip =
_bulkLoader.getMovieClip(e.currentTarget.id);

Setting up the FLA file

There are a few things I do in my example:

1. Uncheck “Automatically Declare Stage Instances”:

This is something I like to do, mostly because I still use instances on the stage. But I also like to extend my symbols with their own classes (for example, if I want to reuse a “Button” movieclip over and over, I would write a class for it so I don’t have to write eventlisteners for MOUSE_OVER and MOUSE_OUT over and over). Extending symbols with instances on your stage causes headaches if you don’t uncheck this checkbox.

The only thing is, once you uncheck this box, you have to remember to declare all your instances on the stage as PUBLIC in your Document Class:

public var myInstance:MyLinkedMovieClip = new MyLinkedMovieClip

or

public var myInstance:MyLinkedMovieClip

Just remember that for “instances” on the stage, you have to use public or you will get a nasty error message.

2. MovieClip Linkages:

Right-click on your symbol in the Library and go to Properties. In the example, I named my MovieClip “GoWhere” (for whatever reason…I think because I’m telling my clip to “Go Where” I want it to…hmmm not very semantic) – so, in my Document Class I wrote:

public var go_1:GoWhere = new GoWhere();

And on the stage in my FLA I gave it an instance name of “go_1″:

Bulkloader example: loading photos with the LazyXMLLoader class

The above example works *after* the first image has loaded…a better version is coming soon, I swear.

Bulkloader has a LazyXMLLoader class that allows you to load photos without having to write repetitive Actionscript XML code over and over (a pain for every project you work on).

To use the LazyXMLLoader class, you write your xml file in a particular way. Below is an xml example that uses the LazyXMLLoader class to load photos (but the LazyXMLLoader class can load a bunch of other media types, such as FLV/F4V files, audio, text files and even other XML files)

Download the XML and .AS file



 lazyTest
 5
 10
 
 photos/
 photos/Eiseisugimoto.jpg
 
 true

 
 
 {base_path}400px-2008-08-22_Skateboarder_floating_in_the_air.jpg
 
 
 {base_path}800px-Canal_St._Skateboarders_2.jpg
 
 
 {base_path}Eiseisugimoto.jpg
 
 
 {base_path}Retrato-jura1.jpg
 
 
 {base_path}Skateboarder_grinding_public_bench_2005.jpg
 

 

NumConnections: In this example, the bulkloader instance has 5 connections (items loading) at any time.

Base Path: just set this to whatever the path is to the folder with your images. For me, since it’s a photo on my computer labelled “photos”, I just wrote “photos/”. You might write http://www.myWebsiteName.com/images/ or where you happen to have your photos.

Then any photo in the xml file is referenced by {base_path}Name-of-your-photo.jpg.

Bulkloader example: loading multiple Photos

Here is an example on how to use Bulkloader to upload multiple photos.

Thanks to wasted potential and the bulkloader AS3 classes for this example. I have a link to the complete code, minus the FLA, the photos, and the bulkloader classes, which you should download from the google code site to ensure that you have the latest version:

A step-by-step explanation

The example below puts all the photos into a folder called “photos” and stores this information in a Vector. A Vector is just a strictly-typed array (meaning, if you make a Vector that contains say, integers, that every item you put in the Vector should be an integer or you will get an annoying “out-of-range” error).

To create a new Vector, you can use the format:

private var photos:Vector. = new Vector.

To add items to a Vector, you can write vectorName.push:

photos.push("photos/400px-2008-08-22_Skateboarder_floating_in_the_air.jpg")

Or use the syntax below:

photos[0] = "photos/400px-2008-08-22_Skateboarder_floating_in_the_air.jpg";
photos[1] = "photos/800px-Canal_St._Skateboarders_2.jpg";
photos[2] = "photos/Eiseisugimoto.jpg";
photos[3] = "photos/Retrato-jura1.jpg";
photos[4] = "photos/Skateboarder_grinding_public_bench_2005.jpg";

Use your own photos. I just grabbed some images from the Wiki Commons.

To make this work, create a .fla file and name it Main.fla. Then give the Document Class a name of BulkLoaderMultiplePhoto.

In my constructor function, I tend to try to check to see if the stage is initialized before I go on to do anything else. It’s a bit of extra writing but it saves your weird headaches later (from loading, trying to access objects on the stage, all sorts of stuff.)

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

    private function init(e:Event = null):void
    {
     removeEventListener(Event.ADDED_TO_STAGE, init);
     // do your stuff here

I use a loop to loop through the “photos” Vector:

  for (var i:int = 0; i < photos.length; i++) {
	// use a loop to "add" each photo to the loader with a unique id
	bulkLoader.add(photos[i], { id:"photo-"+i, priority:10 - i} );
	bulkLoader.get("photo-"+i).addEventListener(BulkLoader.COMPLETE, onPhotoLoaded, false, 0, true);
	bulkLoader.get("photo-"+i).addEventListener(BulkLoader.ERROR, onPhotoError, false, 0, true);

The loop starts off at i=0

(var i:int = 0;

- and then increments

i++)

- each time until it reaches the maximum, which is set for the amount of photos (photos.length gives the "size" or the amount of the photos in the photos Vector)

Keep in mind that I started at photos[0] so I have to set the maximum to 1 just below the photos.length (i < photos.length). In this case, I have five (5) photos in the example, and the last photo is at photos[4], which, as you can see is less than (i <) photos.length (5, for 5 photos).

At any rate, that's a pretty quick explanation of what a loop does but onto the Bulkloader explanation.

Bulkloader: A simple Photo example

Here is a simple example of how to use Bulkloader to upload a single image. In the future, I’ll post a more useful example about how to load multiple images, both from inside the Document Class and an XML file.

The steps are pretty simple, but below is a full example to show how it all fits together.

Create a new bulkloader instance.

bulkLoader = new BulkLoader("main-site", BulkLoader.LOG_VERBOSE);.

In the above example, I set the logging to “VERBOSE” – this is helpful when you are debugging. Bulkloader will tell you then if you are trying to load something that doesn’t exist – for example, if you wrote the path to the image incorrectly.

Add the item to the “bulkloader”:

bulkLoader.add(photoURL, { id:results[0], priority:10 } );.

For convenience, I created a string called “photoURL” which is the path to the photo and I also use it as the “id” by removing the “.jpg”. Bulkloader lets you assign an id to each loading item, which is useful when you are loading multiple items.

You can also set the priority of loading. Here I set it to 10, which isn’t really necessary since I am only loading one photo, but if you wanted to have an item load before another, you just give it a higher priority (say, priority:11).

Then you can add event listeners (say, to check for errors, and also to tell flash what to do with the item once you have loaded it).

bulkLoader.get(results[0]).addEventListener(BulkLoader.COMPLETE, onPhotoLoaded, false, 0, true);

The above uses the array “results” to get the “id” of the item:

bulkLoader.get("the-id-you-created-goes-here").addEventListener(BulkLoader.COMPLETE, onPhotoLoaded, false, 0, true);

This is an example of why unique id’s for each loaded item are handy. In many cases you want to handle each loaded item differently (for example, to place each photo you load in a different place on the stage, or to queue up music to get ready to play from a list).

Anyhow, more on the full example below.

Create a .fla file. Name it main.fla.

Then create a .as file in the same folder, name it BulkLoaderPhoto. In the .as file, copy-and-paste the following code:

package
{
/**
* Simple photo example
*/
  import flash.display.MovieClip;
  import flash.events.Event;

  import flash.display.Bitmap;

  // import the bulkloader classes
  import br.com.stimuli.loading.*;

  public class BulkLoaderPhoto extends MovieClip
  {

	private var bulkLoader:BulkLoader;
	private var bulkLoaderName:String = "main";

	private var photoURL:String = "skateboarder.jpg"

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

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

	// start a new bulkloader
    bulkLoader = new BulkLoader("main-site", BulkLoader.LOG_VERBOSE);

	// for the id, just remove .jpg
	var results:Array = photoURL.split(".jpg");
	trace(results[0]); // outputs "skateboarder"
	bulkLoader.add(photoURL, { id:results[0], priority:10 } );
	bulkLoader.get(results[0]).addEventListener(BulkLoader.COMPLETE, onPhotoLoaded, false, 0, true);
	bulkLoader.get(results[0]).addEventListener(BulkLoader.ERROR, onPhotoError, false, 0, true);

	 // start the loading
	bulkLoader.start();
    }

	private function onPhotoError(e:Event) {
		trace("photo load error:" + e.target);
	}

	private function onPhotoLoaded(e:Event) {
		trace("loading...");
		var image : Bitmap = bulkLoader.getBitmap(e.currentTarget.id);

		//Add the image to the holder
		addChild(image);

		// remove the listener so it doesn't suck up memory
		e.target.removeEventListener(BulkLoader.COMPLETE, onPhotoLoaded);
	 }
  }
}

In the same folder with the .fla file and the .as file, download the bulkloader classes and unzip them.

So, in the folder, it should look like

-main.fla

-BulkLoaderPhoto.as

-skateboarder.jpg

--br

---com

----stimuli

-----loading

-------all the other Bulkloader files...