QueueLoader AS3 rev 5
Latest Version Info:
Click here for the current rev
Click here for the usage guide
Also click here for any posts related to the latest changes:
QueueLoader Updates
I’ve updated QueueLoader once again with some significant enhancements.
- MP3 loading (to a target Sound object)
- Added file access (for swf timeline access, and Bitmap access)
Example code:
import com.hydrotik.utils.QueueLoaderEvent;
//Instantiate the QueueLoader and init vars
var _oLoader:QueueLoader = new QueueLoader();
var startX:int = 0;
var swfClip:MovieClip;
//Draw some progress indicators
var itemprog:Shape = new Shape();
itemprog.graphics.beginFill(0×333333, 1);
itemprog.graphics.drawRect(0, 0, 1, 2);
itemprog.graphics.endFill();
addChild(itemprog);
itemprog.x = 10;
itemprog.y = 350;
var queueprog:Shape = new Shape();
queueprog.graphics.beginFill(0×333333, 1);
queueprog.graphics.drawRect(0, 0, 1, 2);
queueprog.graphics.endFill();
addChild(queueprog);
queueprog.x = 10;
queueprog.y = 400;
//Run a loop that loads 3 images from the flashassets/images/slideshow folder
for (var i:int = 1; i < 4; i++) {
//Set up the container
var image:Sprite = new Sprite();
image.name = “image_”+i;
image.x = startX;
addChild(image);
//Add a load item to the loader
_oLoader.addItem(prefix(“”) + “flashassets/images/slideshow/”+i+“.jpg”, image, {title:“Image “+i});
//Move the image over a bit
startX = startX + 50;
}
//Let’s add an external swf file!
var swf:MovieClip = new MovieClip();
swf.x = 353;
swf.y = 152;
swf.name = “swf”;
addChild(swf);
_oLoader.addItem(prefix(“”) + “flashassets/swf/externalswf.swf”, swf, {title:“swf”});
//Let’s add a sound!
var sound:Sound = new Sound();
//sound.play();
_oLoader.addItem(prefix(“”) + “flashassets/mp3/jens_buchert.mp3″, sound, {title:“mp3″});
//Add event listeners to the loader
_oLoader.addEventListener(QueueLoaderEvent.QUEUE_START, onQueueStart, false, 0, true);
_oLoader.addEventListener(QueueLoaderEvent.ITEM_START, onItemStart, false, 0, true);
_oLoader.addEventListener(QueueLoaderEvent.ITEM_PROGRESS, onItemProgress, false, 0, true);
_oLoader.addEventListener(QueueLoaderEvent.ITEM_INIT, onItemInit,false, 0, true);
_oLoader.addEventListener(QueueLoaderEvent.ITEM_ERROR, onItemError,false, 0, true);
_oLoader.addEventListener(QueueLoaderEvent.QUEUE_PROGRESS, onQueueProgress, false, 0, true);
_oLoader.addEventListener(QueueLoaderEvent.QUEUE_INIT, onQueueInit,false, 0, true);
//Run the loader
_oLoader.execute();
//Listener functions
function onQueueStart(event:QueueLoaderEvent):void {
trace(“>> “+event.type);
}
function onItemStart(event:QueueLoaderEvent):void {
trace(“\t>> “+event.type, “item title: “+event.title);
}
function onItemProgress(event:QueueLoaderEvent):void {
trace(“\t>> “+event.type+“: “+[” percentage: “+event.percentage]);
itemprog.width = 150 * event.percentage;
item.text = “Item Progress: “+Math.round(event.percentage * 100)+ “%”
}
function onQueueProgress(event:QueueLoaderEvent):void {
trace(“\t>> “+event.type+“: “+[” queuepercentage: “+event.queuepercentage]);
queueprog.width = 150 * event.queuepercentage;
queue.text = “Queue Progress: “+Math.round(event.queuepercentage * 100)+ “%”
}
function onItemInit(event:QueueLoaderEvent):void {
trace(“\t>> “+event.type, “item title: “+event.title);
//If the file is a swf lets store a reference to it.
if(event.filetype == QueueLoader.FILE_SWF){
trace(event.file);
swfClip = event.file;
}
}
function onItemError(event:QueueLoaderEvent):void {
trace(“\n>>”+event.message+“\n“);
}
function onQueueInit(event:QueueLoaderEvent):void {
trace(“** “+event.type);
// play the sound!
sound.play();
// play the swf!
event.file.gotoAndPlay(2);
}
//function for simply adds a filepath prefix
function prefix(serverPath:String):String {
var playerType:String = Capabilities.playerType;
if (playerType == “External” || playerType == “StandAlone”) {
return “../”;
} else {
return serverPath;
}
}
Here are the current QueueLoader event variables for retrieving data as well as filetype constants:
public static var ITEM_START:String = “itemStart”;
// Queue item start event
public static var ITEM_PROGRESS:String = “itemProgress”;
// Queue item init/complete event
public static var ITEM_INIT:String = “itemInit”;
// Queue item error event
public static var ITEM_ERROR:String = “itemError”;
// Queue start event
public static var QUEUE_START:String = “queueStart”;
// Queue progress event
public static var QUEUE_PROGRESS:String = “queueProgress”;
// Queue init/complete event
public static var QUEUE_INIT:String = “queueInit”;
// The queue item container
public var targ:*;
// The queue item title
public var title:String = “”;
// The queue item filetype (QueueLoader.FILE_IMAGE, QueueLoader.FILE_SWF, QueueLoader.FILE_AUDIO)
public var filetype:int;
// The queue item loaded file (ie if you load a swf, this would reference its Timeline)
public var file:*;
// The queue item url/path
public var path:String;
// The queue item bytes loaded
public var bytesLoaded:Number = -1;
// The queue item total file size
public var bytesTotal:Number = -1;
// The queue item percentage loaded
public var percentage:Number = 0;
// The total queue percentage loaded
public var queuepercentage:Number = 0;
// The current queue item index
public var count:int;
// The remaining queue length
public var length:int;
// The total queue length
public var max:int;
// The queue items width
public var width:Number;
// The queue item height
public var height:Number;
// unused
public var message:String = “”;
// unused
public var dataObj:Object = null;
A more recent version of this code has been posted! Go HERE
October 9th, 2007 at 10:07 am
Donovan,
I’ve been working on a project is AS3 and I found your class quite useful. However, I’ve got some questions:
1. Is that easy enough to extend the functionality of the class to handle loading more items at a time? Let’s say loading 3 images simultaneously?
2. I’m using the same instance of loading queue in different modules of the same application and I am getting weird queue progress values (like 300%). I think that public ‘reset queue’ method would be useful. Also, some methods for ‘pause’ and ‘resume’ could be helpful.
Please let me know what you think.
Cheers,
Tomek aka Og2t
October 9th, 2007 at 11:03 am
Hi Tomek! To answer your questions:
1.The class was designed to load items sequentially so that you can provide accurate monitoring of an entire set of assets. If you wish to load items in tandem then you could run multiple QueueLoaders at once. For example, if you wish to load a set of Bitmap assets separate from a set of mp3 assets. If you are worried about garbage collection or optimization, you could just null out the QueueLoader instance, however I will add that to the update list:)
2.In reference to number 1, the class wasn’t designed to be used as a singleton pattern or as a static method for centrally loading assets. You would be stuck with having to load QueueLoader sequences sequentially as well.
Pause and resume are great ideas, although I’m not a 100% sure it would work with URLStream without some additional binary data conversion utility. Stop would be an easy and very useful feature which I will add to my TODO list.
October 10th, 2007 at 6:49 am
Thanks Donovan!
But I don’t see why not to incorporate tandem option into the class. For example, if I want to queue loading 40 thumbnails I have to create 40 instances of QueueLoader and let every instance download a single thumbnail. Then I have to remove them manually and whether I need to load another 39 odd ones I have to instantiate them again. If I had a “TANDEM” value specifying the number of items being downloaded at a time it would have made it much nicer. If you needed accurate monitoring you would set TANDEM value to 1
It would work as most download managers (Firefox, Flashget etc.)
Moreover, every HTTP request takes couple of seconds before it starts loading an asset, firing them off one after another creates annoying gaps
I’d like to know if my idea would be hard to code in. If so, I’d need to look for another solution. Also, I’d need to cache thumbnails somehow, and I’ve just migrated to AS3.
Thanks for your time anyway!
Tomek
October 10th, 2007 at 10:36 am
I guess my point was that if you wanted to load up a bunch of items in tandem then the QueueLoader class wouldn’t be ideal. You would be better served to have a separate Class like TandemLoader
QueueLoader is based on sequenced loading.
TandemLoader is a great idea though. I can’t imagine why I wouldn’t want to load a group of initial assets together not in a sequence, but using a tandem loader would be great if you are loading items on the fly. I.E. you needed to add items to the loader as other items are downloading such as creating your own photo book from a selection of thumbs. Something like this would definitely lend itself to a singleton class for centralized control.
I’ll give it some more thought. More then likely you will see a Tandem Loader here at some point:) I’m so swamped right now, it might be a few weeks before I get something up. In the meantime I would suggest an array of Loaders and an array of Event Dispatchers, then loop through the arrays to monitor, using array functions to adjust to items being added.
Hope this helps, wish I could whip up something for you now as it sounds like a great and useful idea:)
As far as caching thumbnails I’m not sure what you mean. The browser will cache loaded data. If you are referring to reusing the loaded bitmaps you could dupe them using the BitmapData class, clone or copyPixels etc..
Hope that helps!
October 21st, 2007 at 10:03 am
Yo Donovan,
How do you handle unloading of stuff? I’ve looked at the QueueLoader but can’t figure it out. All resources I load are being kept in memory.
Are you leaving loaded assest on purpose for Flash Players garbage collector?
October 21st, 2007 at 12:18 pm
With the way QueueLoader is set up, it wouldn’t be the way to remove the loaded objects. Containers for objects are instantiated before a QueueLoader item is added to the queue. This becomes the items target container. QueueLoader itself doesn’t create the container. If you wanted to delete the loaded item then you could simply delete it’s container from outside the QueueLoader. For example under the example section of code at the top you could add:
If you are worried about the data storage and the references of loaded items, QueueLoader resets its data array whenever a Queue is completed/Inited
Hope this helps!
Donovan
October 21st, 2007 at 12:29 pm
it seems that part of your answer was cut.
anyways, I have situation where I preload lots of pics in galleries and I am having problems if I load gallery (set of images) that I already loaded once. Player memory usage increases again for the same amount of again loaded data. Browser serves it from the cache so it’s fast, but I really want to get rid of instances from flash memory. I even tried loader.unload() -ing QueueLoaders loaders for every singe loaded item on gallery.dispose(), but no luck. I suppose I am not referencing loaders the right way. I am banging my head over this one whole damn sunday. 
October 21st, 2007 at 12:44 pm
btw, I thought that unloading/loading will help me write gallery class faster, but now I think I will do it the right way - with own internal caching of loaded assets.
October 21st, 2007 at 2:26 pm
Yeah the code example got stripped. Basically what I was saying is QueueLoader wouldnt handle the functions for removing your loaded items. You would remove the containers that you create that the loaded items are assigned to. removeChild(swf) for example would remove the swf that wa created int he above example.
QueueLoader does however remove references to the loader data once a queue is completed.
Sounds like you have Gallery class within a parent application. QueueLoader would be the method for loading the images, but the method for adding and removing gallery containers would be taken care of in your Gallery class, not in QueueLoader itself.
QueueLoader simply places a loaded item in the specified target container/object. management of those containers would be handle in the parent class.
October 22nd, 2007 at 3:41 am
Hi Donovan!
I managed to get my caching to work by storing references to loaded images (Sprites) in namespace visible to whole application (I needed that, instead of BitmapData). But one thing I don’t get… AFAIK, Flash Player releases memory ONLY when loader.unload() is called. As you said, my applicaton logic is in parent class to QueueLoader. Since, you don’t unload() stuff explicitly anywhere in QueueLoader, but you do assign loader object to the target loading placeholder, explicitly gave name to your loader instance in QueueLoader class so I can do: container.getChildByName(’loader’) and tried calling unload but alas….
October 22nd, 2007 at 9:27 am
You can have direct access to the loaded file using event.file for removal.
I’m working on some updates to QueueLoader including LoaderContext for accessing loaded Class references in the parent application domain. I will also include a reference to the loader in the QueueLoaderEvent variables.
October 24th, 2007 at 12:58 am
I will be posting updates to QueueLoader in the next couple days. I’ve added a new method dispose() for Garbage Collection of loaded assets.
October 24th, 2007 at 11:35 am
Donovan,
This looks like a great class! I must not be comprehending something, though. I took the demo files, and had it load two items, like so:
qLoader.addItem(”/movies/main.swf”, holder_mc1, {name:”main”});
qLoader.addItem(”/movies/music.swf”, holder_mc2, {name:”music”});
It begins preloading boths swf files. But then, after it preloaded music.swf (the second file), the “main.swf” movie is starting half-way! Which is to say, it seems to have started right after it was loaded (but was kept invisible until music.swf was loaded, right?). Naturally, this defeats my purpose of using your class to preload both movies (main + background music), both of which need to be started at the same time!
I’ve been searching all land and sea to find a good preloader that can do that; and your class seemed perfectly suited for my needs. Please, don’t tell me my impression was wrong.
Obviously I must have misunderstood how things work exactly. Can you please tell me what I’m missing? (and yes, I’m kinda new to flash).
Thx!
October 24th, 2007 at 11:57 am
Keep in mind that QueueLoader will load your main.swf first before loading the music.swf. If you need these to load a the same time then QueueLoader would be overkill and you’d want to run two Loaders in tandem.
You can access the main.swf before the music.swf is done loading using the following listener:
_oLoader.addEventListener(QueueLoaderEvent.ITEM_INIT, onItemInit);
Everything loads in the respective order it’s added to QueueLoader.
Hope that helps!
October 25th, 2007 at 1:55 am
Hi Donovan,
Well, I already kinda did something like that.
I added something to the onItemStart event, like:
qListener.onItemStart = function(evObj:Object) {
….
evObj.target_mc.stop();
}
That prevents the movies from starting up. But on onQueueComplete, or onQueueInit, doing:
evObj.target_mc.play();
Only starts the last loaded movie. And it seems like the handle for the first loaded movie is destroyed.
And no, I don’t need to have the two movies load at the same time, but only have them START at the same time! So, your QueueLoader certainly isn’t overkill, as I need to have both preloaded before I can even start them simultaneously.
So, after the second movie has loaded, is there any way, from with QueueLoader, I can still I can start the first movie?
October 29th, 2007 at 8:19 pm
I have posted the rev 7 code here.
March 11th, 2008 at 8:56 pm
[...] been using Hyrdotik’s Queue Loader in RAMEN to manage the loading of “theme” files for the interface. I’m not taxing [...]
October 6th, 2008 at 3:31 pm
Donovan
I have a question. I’m building a full browser flash website. There are three elements to it. I have the Preloader MovieClip that has a Class with your QueueLoader Class, I want to add two external swf, one is the background, and the other is the interface. They both are empty MovieClips on the main timeline, and when I both finish loading the two swf files, I tell the Preloader to move out of the stage, and once that moves it tells the background to play, but nothing happens, and basically the assets inside the background movieclip comes as undefine, like the external swf file was never loaded there. How can I go around to fix this problem.
October 6th, 2008 at 5:07 pm
event.file is how you access the loaded item. You would use the application domain param to get access to class references in the library. Beyond that, I’m not sure what you have going on there. Posting a snippet would be helpful.