Archive for the ‘QueueLoader’ Category

QueueLoader AS3 rev 7 + Garbage Collection + SoundManager

Latest Version Info:
Click here for the current rev

Click here for the usage guide

Click here for the change log

Also click here for any posts related to the latest changes:
QueueLoader Updates

First things first. I’ve thrown in an additional utility that may or may not turn into it’s own project. Most likely it will as I hope to add gapless playback of loops, sound mixing, etc. But I’m already getting ahead of myself:) The reason I included my SoundManager utility is to illustrate how easy it is to use the new feature of accessing loaded swf library assets, as well as using it in a more advance management type setting. There’s a lot to cover, but first let me go over the updates I made to this revision.

  • Added a stop() method for stopping the queue. resume() is in the works.
  • Added LoaderContext for accessing the classes and references in QueueLoaded external swf.
  • Added an error dispatch for an undefined target/container.
  • Added a dispose() method for unloading loaded items from memory for Garbage Collection. More on this later.
  • More cleanup and optimization of code

The most significant changes I will go over is with the LoaderContext and dispose() method. The rest are pretty self explanatory.

dispose() + Garbage Collection
This download is a lot heavier in file size as I’ve included some large images to clearly indicate what’s happening with the Garbage Collector. I’m not going to go into too much detail on how Garbage Collection works. Essentially it is the process the Actionscript Virtual Machine uses to free up/dump unused memory. It does this intermittently and during times of low processing load, or when the memory has reached a certain level and needs to flush. To deal with this it is important to null out your variables and use removeChild to remove instances from a Display object. AS3 will retain the object in memory if there is a reference to it anywhere in the code. This can be a pain when trying to track data flow so it’s better to keep this in mind when planning your plan of attack. To learn more about Garbage Collection, check out Grant Skinner’s posts here.

I’ve included monitoring of garbage collection in the source example. System.totalMemory is the property for getting this info. But wait! There are some important things to be aware of.

  • Either there is a bug with System.totalMemory, or with the Loader.unload() method, so you will need to see changes to the GC in the browser.
  • Because of the above issue I have set the publish for local access only, so just make a note
  • System.totalMemory will give you what it says, total memory. So if you have other flash apps open in the browser you will see the memory used for those apps added to your QueueLoader Example. So be sure to close everything out.

When you dispose of a section that has used QueueLoader for loading of assets, you would use dispose() to remove the loaded assets and ready them for Garbage Collection. Lets assume we’ve set up a QueueLoader and it’s already loaded it’s assets, say for an image gallery. Here’s the block of code we would use to set up the QueueLoaded assets and the loader for GC:

_oLoader.dispose();
               
// Delete the QueueLoader containers
while(imageContainer.numChildren > 0){
        imageContainer.removeChildAt(0);
}

_oLoader = null;

You can clearly see this working in the example fla, but you get the idea. On to the next exciting feature…

Accessing externally loaded classes and library assets:
First caveat to this. Sandbox security issues come into play if you are loading things across domains. For this example we are assuming you are loading within the same domain. QueueLoader will do this, but you need to add some extra code. For more on cross scripting go here.

This feature allows you to add Library assets to an external swf, export them for actionscript as classes, and access those classes in your parent swf. This is great for loaded sounds, images, interface widgets, etc. Personally I use a separate swf for each library asset type. This also helps if you want to add a Manager class to one of your external swf files. In this example I added the SoundManager class.

You would do this by adding:

//Definition vars for accessing loaded swf libary classes in this scope
var addedDefinitions:LoaderContext = new LoaderContext();
addedDefinitions.applicationDomain = ApplicationDomain.currentDomain;

// Scope and Instantiate variables
var _oLoader:QueueLoader = new QueueLoader(false, addedDefinitions);

and then once your assets are loaded using QueueLoader you would access them using:

var Loop1Reference:Class = getDefinitionByName(“Loop1″) as Class;
var loop1:Sound = new Loop1Reference();
soundChannel = loop1.play();

I know I’m using code snippets so if it seems unclear, open up the queueloader.fla and you can see all of this in its entirety.

SoundManager
SoundManager is a class I added that may or may not be used in conjunction with QueueLoader. It’s in its infancy so this class is pretty straight forward. Basically what is happening is on the first frame of the externalsounds.swf there is code to add the library assets intro the SoundManager.

import com.hydrotik.utils.SoundManager;

SoundManager.getInstance().addItem(new Glitch1());
SoundManager.getInstance().addItem(new Glitch2());
SoundManager.getInstance().addItem(new Loop1());

Now anywhere in your application you can now play these sounds. Check out the source for more info.

My thanks to those who have commented and brought issues to my attention. Helps me to enhance this class and make it more powerful for simple as well as advanced usage. I always welcome your constructive criticism and suggestions for upcoming revisions. Please keep this in mind though. QueueLoader is a utility, and most of the control and administrative functions should be handled outside of the utility in its parent class.

If you’re using QueueLoader on a project or have used it, I’d love to hear about it!

Enjoy! :)
Donovan


A more recent version of this code has been posted! Go HERE

Monday, October 29th, 2007

QueueLoader AS3 rev 5

Latest Version Info:
Click here for the current rev

Click here for the usage guide

Click here for the change log

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.QueueLoader;
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:

// Queue item start event
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

Friday, September 14th, 2007

QueueLoader AS3 Update

Latest Version Info:
Click here for the current rev

Click here for the usage guide

Click here for the change log

Also click here for any posts related to the latest changes:
QueueLoader Updates

I made a significant and minor fix to the QueueLoader class.

There was a dupe event being dispatched for complete and init that was dispatching ITEM_INIT twice. My apologies for that.

I also changed the {name:”Image 1″} to reflect the custom event so it is now {title:”Image 1″}

Update
In response to Erik’s question; I’m assuming you are referring to swf files as an alternate file type? FLV files and Audio files would be a nice addition of functionality to the class for loading into your assets library. However in the meantime, you can load swf files using QueueLoader as it is. It’s a little convoluted but here’s how to do it:

Here’s a snippet of code to add the swf to the loading queue as well as it’s respective container, in this case using the MovieClip class.

var swf:MovieClip = new MovieClip();
swf.name = “swf”;
addChild(swf);
_oLoader.addItem(prefix(“”) + “flashassets/images/slideshow/WCS.swf”, swf, {title:“swf”});

In the listening functions we add some code to detect the MovieClip container and access the timeline in it’s target.

function onItemInit(event:QueueLoaderEvent):void {
        if(event.targ is MovieClip){
                var container:MovieClip = event.targ as MovieClip;
                var loader:Loader = container.getChildAt(0) as Loader;
                var clip:MovieClip = loader.content as MovieClip;
                clip.gotoAndPlay(2);
        }
}

The above snippet is from an example that loads images and then loads a swf. The external swf has a stop() command in its first frame. The above snippet is in the ITEM_INIT handler and plays the swf’s timeline once it’s loaded. Although from a practical standpoint you would assign the clip to a class variable and then do the gotoAndPlay command in the QUEUE_INIT handler once everything is done loading.

Something interesting I noted here as well. Might be worthy of a post on it’s own. If you simply “type” the above variables with their respective classes you will get a coercion error, whereas declaring them makes it work fine. I’m assuming this is because the event.targ variable returns a DisplayObject. I’ve already changed the DisplayObject to “*” in rev 3.0.6 but it still requires the “variable as Class”. I’ll post that code when I make some more progress.

So to sum it up: The above example is a bit of a hack for the time being. I will add a more direct method for accessing the timeline of a loaded swf as well as an event variable that specifies the content type in the not so distant future:) Beyond that I will look into the feasibility of loading external mp3 files, flv files, and zip files.


A more recent version of this code has been posted! Go HERE

Monday, September 10th, 2007

QueueLoader AS3

Latest Version Info:
Click here for the current rev

Click here for the usage guide

Click here for the change log

Also click here for any posts related to the latest changes:
QueueLoader Updates

A while back Felix Raab from betriebsraum did a cool QueueLoader class for AS2 that I used often. I decided to update it for AS3 as my first port of my day to day utilitarian classes. It’s still in it’s early and raw stages, but at this point I’ve already been using it regularly.

Shortly I’ll post an example of an image gallery using the QueueLoader classes.

Here’s a simple example of how to use the class:

import com.hydrotik.utils.QueueLoader;
import com.hydrotik.utils.QueueLoaderEvent;

//Instantiate the QueueLoader
var _oLoader:QueueLoader = new QueueLoader();

//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(“../flashassets/images/slideshow/”+i+“.jpg”, image, {title:“Image “+i});
        //Move the image over a bit
        startX = startX + 50;
}

//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]);
}

function onQueueProgress(event:QueueLoaderEvent):void {
        trace(\t>> “+event.type+“: “+[” queuepercentage: “+event.queuepercentage]);
}

function onItemInit(event:QueueLoaderEvent):void {
        trace(\t>> event:” + event.type+” - “+[“target: “+event.targ, “w: “+event.width, “h: “+event.height]+\n);
}

function onItemError(event:QueueLoaderEvent):void {
        trace(\n>>”+event.message+\n);
}

function onQueueInit(event:QueueLoaderEvent):void {
        trace(“** “+event.type);
}


A more recent version of this code has been posted! Go HERE

Wednesday, August 15th, 2007