Flex AS3/Air projects swcs

July 31st, 2008

check out this very useful article:
Turning a Flex Actionscript project into a Flex AIR project
as far as I can make out, the only swcs you need for a flex as3/air project (no flex-framework) are:

playerglobal.swc
flex.swc
utilities.swc
airglobal.swc
airframework.swc
servicemonitor.swc

pureMVC assetLoader utility (3)

July 27th, 2008

the main actors

the Loader Class:
this delegates loading tasks to its clients, and stores (if asked) the results.

the IAssetInfo Interface:
this is basically a value object that is requested from the Loader, on which properties or listeners may be set, and then passed back to the Loader to initiate loading.

the Clients:
these actually do the job of wrapping the different types of loading Objects (URLLoader, Loader, ModuleManager, Sound, NetStream... etc).

(if you are familiar with the Flex ModuleManager, the above implimentation is very similar).

the code
the refactored code can be downloaded from the googlecode svn here, or viewed by clicking the souce button on the demo below.

The loader is no means completed, but I feel that this is a good backbone to build on. It also needs some good thorough testing, but I'm confident that its basic functionality is sound.

To create and register the AssetLoaderProxy:

// create the LoaderProxy instance
var loaderProxy:LoaderProxy;
loaderProxy= new LoaderProxy();
// register the client that wraps
// the flash.net.URLLoader Class
loaderProxy.registerClient(ClientTypes.URLLOADER_CLIENT,
                           URLLoaderClient);
// register the client that wraps
//the flash.display.Loader Class
loaderProxy.registerClient(ClientTypes.LOADER_CLIENT,
                           LoaderClient);
// register proxy with the pureMVC framework
facade.registerProxy(assetLoader);

To retrieve an asset:

// create assetInfo
var assetInfo:IAssetInfo;
assetInfo= assetLoader.getAsset("filePath/myImage.jpg");
// test to see if it has already been loaded and stored
if(assetInfo.hasLoaded)
{
    trace("this asset has already been loaded");
    // retrieve and type asset;
    var myBMP:Bitmap = Bitmap( assetInfo.getAsset() );
}
else
{
    // add the id of the client that should
    // handle the loading of the asset
    assetInfo.clientType = ClientTypes.LOADER_CLIENT;
    // add a LoaderContext or SoundLoaderContext if needed
    assetInfo.context = new LoaderContext();
    // add any listeners required
    assetInfo.addEventListener(Event.COMPLETE,
                               completeHandler);
    // add the assetInfo to the load que
    assetLoader.addToQue(assetInfo);
}

The LoaderProxy that wraps the Loader class traps the Loader's events and relays them as notifications to the pureMVC framework (see the enumerated type class LoaderNotificationNames).

refactoring

July 24th, 2008

Spent last night refactoring the AssetLoader. It looks a lot better stripped down. I have also removed the typed getter methods from the IAssetContainer. You know the fileType, you know the clientLoaderType, so it can be typed after a call to the getAsset():* method. The only asset type this really affects is XML. Basically, you can't store XML in the AssetLoader, it can only be stored in its serialised state (ie a String). This means that once it is loaded it must be retrieved, parsed, and injected into its very own model for storage and access. But that's only good practise - no??

The reason I'm not parsing XML within the AssetLoader is because you might want to set some of the static XML parsing properties first. This is one of the main reasons that I stopped using BulkLoader.

I have added a few smaller interfaces:

ICreate
which is basically a factory method that wraps a Module or SWF asset. The create(id:String="") method can be called on them, allowing access to classes embedded in the assets.

IDeconstruct
this enforces the good practice of disposing of assets properly. An IDeconstructor that knows how to handle a specific asset's deconstruction wraps the asset and is passed into the ILoadInfo at the completion of a successful load. So a NetStream or a Bitmap can be handled in their own unique ways.

thoughts of complexity

July 23rd, 2008

After the weekly FlashBrighton geekmeet about OOP and the reduction of complexity (taken by Flexible Factory) I'm undergoing a garbage collection phase with my thoughts. I've decided that the automatic assignment of the correct loader client from the fileType is adding too much complexity, and I promised my self I wasn't going to do this.

Also, I was implementing a test for my Flex Module loader client, when I realised that it was a specialised swf. The automatic assignment just wouldn't work in this case, so I had to create a property on the IAssetContainer that explicity set the clientLoaderType.

If its annoying once and results in code fiddling, it'll be even more annoying the next time etc... Any logic that assigns the correct clientLoaderType from the fileType can be implemented for a specific project.

Also for the Notifications, I'm sending the AssetLoaderProxy itself, which is resulting in lots of getters and setters that don't need to be there. Create a custom event object and send that as the body. This will work well with some good advice from Pedr Browne, and that is to remove my AssetLoader from the Proxy, and have a Proxy wrap it. This means that it can work in isolation from the pureMVC framework, and dispatch errors that the Proxy can handle and pass on as Notifications.

pureMVC assetLoader utility (2)

July 22nd, 2008

Been thinking a lot about the architecture of this. Currently the AssetLoaderProxy's clients (ie the classes that actually do the loading of the different types of data) are Commands that are triggered by Notifications given by the AssetLoaderProxy. But I think this is a case "its pureMVC, let's use Notifications". The same effect could be achieved by an abstract client class and a client factory, without the overhead of sending a Notification, and it would make adding new clients far easier.

I've also created a client for loading Flex Modules, and added functionality to extract class instances from loaded SWFs.

I'm aiming for the end of July for my first alpha release of the AssetLoaderProxy and the LogProxy :-/ Hopefully I will have time, as it can be combined with my next job, which is a multimedia presentation tool to be implemented in pureMVC Flex and Air - YEY!

mmm... I guess I need to look at a FileStream client too. Best put that on the list.

Update
Thinking some more, lets do away with a factory altogether. We can register the clients directly, they can be added and removed at run time.

fzip fun

July 19th, 2008

For anybody who hasn't heard of fzip yet, this is a great little package of classes that enable the manipulation of zip files in AS3, and when combined with Air its awesome. Its written by Claus Wahlers, and you can get it from here

poxy proxy

June 24th, 2008

Ok, I like using pureMVC, but I'm just going to have a rant about its naming conventions.

I just think that its rather unimaginative to give them names of design patterns, but what really gets me is the Proxy. Which isn't actually a proxy pattern, its just a data holder. A Proxy must implement the interface of the object it wraps, and the pureMVC Proxy class doesn't - well, not yet - it may do once extended, but that can't be enforced.

The real reason for my bugbear is because if I have a real proxy that's not a pureMVC Proxy class, I can't name it so, as this will lead to confusion to future developers. :~/

multicore pureMVC out of beta

June 24th, 2008

Thats nice, been using it for a while now.
http://puremvc.org/content/view/75/181/

google code page

June 23rd, 2008

have just created a google code page specifically for pureMVC utilities. Not much there yet, but here it is anyway:

http://code.google.com/p/puremvc-utilities/

pureMVC assetLoader utility (1)

June 15th, 2008

Yes, another asset loader utility, they seem to be the in thing at the moment, but none of the ones I've used are me. They are far too feature rich for my needs, clutter up the global namespace, and since I use pureMVC a lot, I may as have an asset loader utility that actualy is implimented in it.

This is the first version... a very early one, so much that I haven't even writen any documentation for it. I just need to get it out there, and if not now, when?

At the moment it only loads non-streaming assets (ie those that are only available after Event.COMPLETE), and my aim, apart from those listed below, is to add features only when neccessary.

TODO:
1) write some documentation
2) impliment streaming file types (flvs, mpgs and zips)
3) refactor for use without pureMVC (maybe)

To create and register the AssetLoaderProxy:

var assetLoader:AssetLoaderProxy;
assetLoader = new AssetLoaderProxy();
facade.registerProxy(assetLoader);

To retrieve an asset:

var asset:IAssetContainer;
asset = assetLoader.getAsset("filePath/myFile.jpg")

The AssetLoaderProxy will return an IAssetContainer which either contains the asset (if it has been previously loaded and stored) or the information that will enable the loading of the asset. So the first thing to do is to check to see its loaded state:

if(asset.hasLoaded)
{
    trace("this asset has already been loaded")
}
else
{
    trace("this asset has not been loaded yet")
}

If the asset has already been loaded, it can be accessed either via the getAsset():Object method, or using any of the pre-typed getters.

To load an asset:
If the asset has not already been loaded, listeners, loader contexts and other properties can be added to the IAssetContainer, before it is passed back to the AssetLoaderProxy load que.

asset.addEventListener(Event.COMPLETE, completeHandler);
asset.addEventListener(ProgressEvent.PROGRESS, progressHandler);
asset.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
assetLoader.addToQue(asset);

Note on Typing:
The loaded assets will be typed as its loader types it. For example, an XML file is loaded with a URLLoader and is therefore a String. At no point will this String be parsed as an XML within the AssetLoader utility until you call the getAsXML() method from the IAssetsContainer. The string will then be parsed and stored as an XML. If you want to keep it as a String, always call the getAsset() and type it, or call getAsString(). This is a good thing, as it gives you more control over it (ie changing whitespace settings before parsing).
The type of asset can be ascertained through its fileType property, which is basically just the file extension.

Notifications:
The AssetLoaderProxy also sends pureMVC Notifications. You can use its enumerated static constants to register commands that will respond to these.

facade.registerCommand(
                        AssetLoaderProxy.LOAD_QUE_PROGRESS,
                        WriteToProgressBar
                       );

The AssetLoaderProxy instance will be passed as the body of the Notification, so any information required can be taken from its public properties.

And finally:
So, that gives a very quick over view. The next thing I've got to do is commenting documentation, and perhaps some UML diagrams.

Update:
I Have created a google code account, for this and other pureMVC utilities. I intend to get a fully featued download out at the end of July.