Archive for October, 2007

AS3 + XMLLoader + CSSLoader

Someone suggested the great idea of adding CSS and XML loading to QueueLoader. I plan on doing this, but first I thought I’d share a method I use to load those two items.

I personally tend to load XML first (I put the path to the css in the XML file), then I load the CSS, and then I start my QueueLoader. The reason for this is that I almost always store the paths for QueueLoader in the XML. If that’s a method you tend to follow as well, then these utilities will help if you haven’t built them already.

In the spirit of sequential loading and monitoring, I totally plan on adding this to the next revision. However, I would not suggest setting up a separate QueueLoader just for XML and CSS. If you need to load them separately, here are a couple of utilities for doing that. They will save you a bit of overhead, and are cousins of QueueLoader so they should be brainless to implement.

XMLLoader

import com.hydrotik.utils.XMLLoader;
import com.hydrotik.utils.XMLLoaderEvent;

var xmlLoader:XMLLoader = new XMLLoader(_sAdminPath + xmlFilename);
xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, onXMLComplete);
xmlLoader.addEventListener(XMLLoaderEvent.ERROR, onXMLError);
xmlLoader.addEventListener(XMLLoaderEvent.PROGRESS, onXMLProgress);

function onXMLError(event:XMLLoaderEvent):void {
    trace(“XMLLoader error: “+event);
}

function onXMLProgress(event:XMLLoaderEvent):void {
    trace(“XMLLoader progress: “+event.percentage);
}

function onXMLComplete(event:XMLLoaderEvent):void {
    xml = event.xml;
}

CSSLoader

import com.hydrotik.utils.CSSLoader;
import com.hydrotik.utils.CSSLoaderEvent;

var cssLoader:CSSLoader = new CSSLoader(_sAdminPath + xmlFilename);
cssLoader.addEventListener(CSSLoaderEvent.COMPLETE, onXMLComplete);
cssLoader.addEventListener(CSSLoaderEvent.ERROR, onXMLError);
cssLoader.addEventListener(CSSLoaderEvent.PROGRESS, onXMLProgress);

function onXMLError(event:CSSLoaderEvent):void {
    trace(“CSSLoader error: “+event);
}

function onXMLProgress(event:CSSLoaderEvent):void {
    trace(“CSSLoader progress: “+event.percentage);
}

function onXMLComplete(event:CSSLoaderEvent):void {
    css = event.css;
}

I didn’t include any fla files in the download, just the packages, since this should be pretty easy to implement. But here’s an example of how I use these before running my main block of code:

private function loadConfigration():void{
    var xmlLoader:XMLLoader = new XMLLoader(_sAdminPath + xmlFilename);
    xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, onXMLComplete);
    xmlLoader.addEventListener(XMLLoaderEvent.ERROR, onXMLError);
    xmlLoader.addEventListener(XMLLoaderEvent.PROGRESS, onXMLProgress);
}

private function onXMLError(event:XMLLoaderEvent):void {
    trace(“XMLLoader error: “+event)
}

private function onXMLProgress(event:XMLLoaderEvent):void {
    trace(“XMLLoader progress: “+event.percentage)
}

private function onXMLComplete(event:XMLLoaderEvent):void {
    trace(“:: onXMLComplete:”);
    _xml = event.xml;

    var cssLoader:CSSLoader = new CSSLoader(CacheKiller.file(“includes/admin/” + _xml.attribute(“css”), “../”, “/”));
    cssLoader.addEventListener(CSSLoaderEvent.COMPLETE, onCSSComplete);
    cssLoader.addEventListener(CSSLoaderEvent.ERROR, onCSSError);
    cssLoader.addEventListener(CSSLoaderEvent.PROGRESS, onCSSProgress);
}

private function onCSSError(event:CSSLoaderEvent):void {
    trace(“CSSLoader error: “+event)
}

private function onCSSProgress(event:CSSLoaderEvent):void {
    trace(“CSSLoader progress: “+event.percentage)
}

private function onCSSComplete(event:CSSLoaderEvent):void {
    trace(“:: onCSSLoaded:”);
    _css = event.css;
    buildInterface();
}

Pretty simple:) Just runs one after the other then you can run a QueueLoader with loaded items pulled from the XML. Just one way of doing, but like I said I will add css and xml to the next revision.

Thanks to Jesse for the idea!


XMLLoader and CSSLoader Source Rev1

Tuesday, October 30th, 2007

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

AS3 + Useful Little Things…

Here is a little list of useful tidbits and pieces of information I have discovered or encountered. Some are simple and obvious, and some are just nice to have handy.

If you come across any more, let us all know!

How to determine the number of times a substring shows up in a string. In this example we want to know how many times “http://” exists in a string:

var s:String = “http:// hdfkajsdhfksdh kj akjdhf ksjdh http:// jsdf asdlkfj  http:// http://”;
var pattern:RegExp = /http:\/\/+/g;
var results:Array = s.match(pattern);
trace(results.length); // 4
 

How to address the main swf preloader issue in IE7:

this.addEventListener(“enterFrame”,onEnterFrame);

function onEnterFrame(e:Event) {
    loadbar.width = (this.loaderInfo.bytesLoaded/this.loaderInfo.bytesTotal)*200;
    if (this.loaderInfo.bytesLoaded == this.loaderInfo.bytesTotal) {
        gotoAndPlay(2);
        this.removeEventListener(“enterFrame”, onEnterFrame);
    }
}

External javascript call that doesn’t bother you:

var playerType:String = Capabilities.playerType;
if (playerType == “External” || playerType == “StandAlone”) {
    //
} else {
    navigateToURL(new URLRequest(“javascript:setHeight(200);”), ‘_self’);
}

Phone and Email validation using REGEX:

// REGEX for email validation
function validateEmail(email:String):Boolean {
        var emailExpression:RegExp = /^[a-z][\w.-]+@\w[\w.-]+\.[\w.-]*[a-z][a-z]$/i;
        return ! emailExpression.test(email);
}
// REGEX for phone validation
function validatePhone(phone:String):Boolean {
        var emailExpression:RegExp = /^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,3})|(\(?\d{2,3}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/i;
        return ! emailExpression.test(phone);
}

Calling another function with arguments using Tweener:

Tweener.addTween(
        item, {
                alpha: 0,
                time:.3,
                transition:“easeoutquad”,
                onComplete:anotherFunction, //Completed Event Callback
                onCompleteParams:[arg1, arg2, arg3] //anotherFunction(arg1:String, arg2:String, arg3:String)
        }
);

Simple button interaction:

submitBT.addEventListener(MouseEvent.MOUSE_OVER, submitInteraction);
submitBT.addEventListener(MouseEvent.MOUSE_OUT, submitInteraction);
submitBT.addEventListener(MouseEvent.CLICK, submitInteraction);

function submitInteraction(event:MouseEvent):void {
        switch (event.type) {
                case MouseEvent.MOUSE_OVER :
                        Tweener.addTween(event.currentTarget, {alpha: 1, time:.2, transition:“easeoutquad”});
                        return;
                case MouseEvent.MOUSE_OUT :
                        Tweener.addTween(event.currentTarget, {alpha: .7, time:.2, transition:“easeoutquad”});
                        return;
                case MouseEvent.CLICK :
                        submitForm();
                        return;
        }
}

ADDED_TO_STAGE

pv3dContainer.addEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);

function handleAddedToStage(event:Event):void {
        trace(event);
}

I would suggest avoiding this at all costs. use a setTimeout() function if you need a delay otherwise find another way to call the event. My nightmare with this was confirmed during the Papervision 2.0 seminar when we removed it.

Consistency is the key to effective troubleshooting. That being said here are a couple things that throw that off as well as useful tips:

  • Small images will still load across domains. When security should prevent cross domain loading. (I get the feeling the security is dependent on the file size?)
  • Assets will instantiate in some browsers and some won’t in IE7. (Make sure you hit the frame with assets when preloading. Obvious practice, but when you see thing instantiate when you don’t, makes it easy to overlook)
  • Remember that the edit multiple frames button in the timeline is your friend. (It’s next to the right of the new layer button under the keyframe area in the timeline)
  • Actionscript video cue points are not precise. Cuepoints embedded in the FLV are.
  • Check out the gradient transform tool. It’s a hidden gem.
  • Flash has an easier time rendering filters when the values are exponents of 2, so if you can do x/y blur value pairs using 2, 4, 8, 16, 32. you might see a performance increase with multiples of 2 as well.

Monday, October 1st, 2007