As requested, I Just made a quick demo how to implement the SomaAssets plugin in your application.

See the demo.
Download the demo.
View source.
Demo on github.

I’ll make a quick descrition here. I’ll be using the following XML config:

<?xml version="1.0" encoding="UTF-8"?>
<loader connection="1">
	<asset id="image0" src="assets/img/image0.jpg" smoothing="true" transparent="true"/>
	<asset id="image1" src="assets/img/image1.jpg" smoothing="true" transparent="true"/>
	<group id="group0">
		<group id="group00">
			<asset id="image2" src="assets/img/image2.jpg" smoothing="true" transparent="true"/>
			<asset id="image3" src="assets/img/image3.jpg" smoothing="true" transparent="true"/>
		</group>
		<group id="group01">
			<asset id="css" src="assets/css/stylesheet.css" preventCache="true" weight="352"/>
			<asset id="json" src="assets/json/data.json" preventCache="true" weight="582"/>
			<asset id="sound" src="assets/sounds/sample.mp3" preventCache="true" weight="16718"/>
			<asset id="text" src="assets/text/text.txt" preventCache="true" weight="574"/>
			<asset id="xml" src="assets/xml/sample.xml" preventCache="true" weight="79"/>
			<asset id="video" src="assets/video/sample.flv" weight="1550580"/>
			<asset id="zip" src="assets/zip/file.zip" weight="3493"/>
		</group>
	</group>
</loader>

First step, I create a SomaCore application.

public function Main() {
	_app = new SomaApplication(this);
}

In the application facade, I create a command from a SomaAssets just to demo how to monitor the assets loading at a framework level. I also register 3 views and 3 mediators to show how to get the assets at different moments. I create the plugin SomaAssets and I finally create a simple wire class “InitializeWire” to handle some global events (config loaded, assets loaded, etc).

package com.soma.plugins.assets.demo {

	import com.soma.plugins.assets.demo.commands.ExampleAssetCommand;
	import com.soma.plugins.assets.events.SomaAssetsEvent;
	import com.soma.core.Soma;
	import com.soma.core.di.SomaInjector;
	import com.soma.core.interfaces.ISoma;
	import com.soma.plugins.assets.SomaAssets;
	import com.soma.plugins.assets.demo.views.ImageGroup;
	import com.soma.plugins.assets.demo.views.ImageGroupMediator;
	import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
	import com.soma.plugins.assets.demo.views.ImageWhenAllLoadedMediator;
	import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
	import com.soma.plugins.assets.demo.views.ImageWhenNotLoadedMediator;
	import com.soma.plugins.assets.demo.wires.InitializeWire;
	import com.soma.plugins.assets.vo.SomaAssetsVO;

	/**
	 * @author Romuald Quantin
	 */
	public class SomaApplication extends Soma implements ISoma {

		private var _container:Main;

		public function SomaApplication(container:Main) {
			_container = container;
			super(_container.stage, SomaInjector);
		}
		
		// create a command for a demo purpose to monitor the assets that are loaded
		override protected function registerCommands():void {
			addCommand(SomaAssetsEvent.ASSET_LOADED, ExampleAssetCommand);
		}
		
		// register mediators to views
		// the views won't be created at the same moment to show how you can handle your loading 
		override protected function registerViews():void {
			mediators.mapView(ImageWhenAllLoaded, ImageWhenAllLoadedMediator);
			mediators.mapView(ImageWhenNotLoaded, ImageWhenNotLoadedMediator);
			mediators.mapView(ImageGroup, ImageGroupMediator);
		}
		
		// create the plugin and register an external assets configuration to load
		override protected function registerPlugins():void {
			createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets.xml"));
		}
		
		// create an wire where you could handle the "global" loading process
		override protected function start():void {
			injector.createInstance(InitializeWire);
		}
		
		// just the document class to add some views to
		public function get container():Main {
			return _container;
		}
		
	}
}

In the InitializeWire class, I add some event listeners to handle errors, when the XML config is loaded and when the assets are all loaded. I used it mostly to create views and mediators at different moments of the loading process to show you how to handle you loaders, events and assets.

package com.soma.plugins.assets.demo.wires {

	import com.soma.plugins.assets.demo.views.ImageGroup;
	import com.soma.core.interfaces.IWire;
	import com.soma.core.wire.Wire;
	import com.soma.plugins.assets.demo.SomaApplication;
	import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
	import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
	import com.soma.plugins.assets.events.SomaAssetsEvent;
	import flash.display.DisplayObjectContainer;
	import org.assetloader.core.IAssetLoader;

	/**
	 * @author Romuald Quantin
	 */
	public class InitializeWire extends Wire implements IWire {
		
		[Inject(name="assets")]
		public var loader:IAssetLoader;
		
		// register some SomaAssets events for monitoring
		override public function initialize():void {
			addEventListener(SomaAssetsEvent.CONFIG_LOADED, configLoaded);
			addEventListener(SomaAssetsEvent.LOADER_COMPLETE, assetsComplete);
			addEventListener(SomaAssetsEvent.ERROR, assetsErrorHandler);
		}
		
		// shortcut to get the document class
		private function get container():DisplayObjectContainer {
			return SomaApplication(instance).container;
		}

		// in case there's an error for both the assets config or the assets
		private function assetsErrorHandler(event:SomaAssetsEvent):void {
			trace("Asset Error:", event.errorMessage, event.errorType);
		}
		
		// the external XML assets config has been loaded here 
		private function configLoaded(event:SomaAssetsEvent):void {
			container.addChild(new ImageWhenNotLoaded());
			container.addChild(new ImageGroup());
			trace("config loaded");
			loader.start();
		}
		
		// all assets container in the config XML have been loaded here 
		private function assetsComplete(event:SomaAssetsEvent):void {
			container.addChild(new ImageWhenAllLoaded());
		}

	}
}

In the ImageWhenAllLoadedMediator mediator, I inject directly an asset (Bitmap) as everything is loaded when the mediator gets created.

package com.soma.plugins.assets.demo.views {

	import com.soma.core.interfaces.IMediator;
	import com.soma.core.mediator.Mediator;

	import flash.display.Bitmap;

	/**
	 * @author Romuald Quantin
	 */
	public class ImageWhenAllLoadedMediator extends Mediator implements IMediator {

		[Inject]
		public var view:ImageWhenAllLoaded;
		
		// all the assets are loaded at this point
		// we can inject the asset (or loaders)
		[Inject(name="image0")]
		public var image:Bitmap;
		
		override public function initialize():void {
			image.scaleX = image.scaleY = 0.1;
			image.x = 130;
			view.addChild(image);
		}
		
		override public function dispose():void {
			while (view.numChildren > 0) view.removeChildAt(0);
			view = null;
			image = null;
		}
		
	}
}

The ImageWhenNotLoadedMediator mediator gets created when the XML config has been loaded. The assets are not loaded yet and I show how to retrieve the loader of a specific asset to monitor when it starts, the loading progress and when it has been completed.

package com.soma.plugins.assets.demo.views {

	import flash.display.Bitmap;
	import com.soma.core.interfaces.IMediator;
	import com.soma.core.mediator.Mediator;

	import org.assetloader.core.ILoader;
	import org.assetloader.events.AssetLoaderErrorEvent;
	import org.assetloader.events.AssetLoaderEvent;
	import org.assetloader.events.AssetLoaderProgressEvent;

	/**
	 * @author Romuald Quantin
	 */
	public class ImageWhenNotLoadedMediator extends Mediator implements IMediator {

		[Inject]
		public var view:ImageWhenNotLoaded;
		
		// here we get the loader of an asset for monitoring purpose
		// this one is an ImageLoader but we keep the interface as a type
		[Inject(name="image1")]
		public var imageLoader:ILoader;
		
		// add some listeners to monitor the loading of a single loader 
		override public function initialize():void {
			imageLoader.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
			imageLoader.addEventListener(AssetLoaderEvent.START, startHandler);
			imageLoader.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
			imageLoader.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
		}

		private function errorHandler(event:AssetLoaderErrorEvent):void {
			trace("Error", event.errorType, event.message);
		}

		private function startHandler(event:AssetLoaderEvent):void {
			trace("Loading started (" + ILoader(event.currentTarget).id + ")");
		}

		private function progressHandler(event:AssetLoaderProgressEvent):void {
			trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
		}
		
		// the loader is complete, the asset is ready
		private function completeHandler(event:AssetLoaderEvent):void {
			trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
			var image:Bitmap = event.data;
			image.scaleX = image.scaleY = 0.1;
			view.addChild(image);
		}
		
		override public function dispose():void {
			while (view.numChildren > 0) view.removeChildAt(0);
			view = null;
			imageLoader = null;
		}
		
	}
}

The ImageGroupMediator mediator does the same job as the mediator above but applied to an IAssetLoader (loader containing others loaders). The way to monitor the loading process is exactly the same. I also show different ways to retrieve the assets of this group, once the groupe has been loaded. You will notice the special injection name of the loader, it is a path generated from the XML config using the group and assets ids and a delimiter.

package com.soma.plugins.assets.demo.views {

	import flash.display.Bitmap;
	import com.soma.plugins.assets.SomaAssets;
	import com.soma.core.interfaces.IMediator;
	import com.soma.core.mediator.Mediator;
	import org.assetloader.core.IAssetLoader;
	import org.assetloader.core.ILoader;
	import org.assetloader.events.AssetLoaderErrorEvent;
	import org.assetloader.events.AssetLoaderEvent;
	import org.assetloader.events.AssetLoaderProgressEvent;
	import flash.utils.Dictionary;

	/**
	 * @author Romuald Quantin
	 */
	public class ImageGroupMediator extends Mediator implements IMediator {

		[Inject]
		public var view:ImageGroup;
		
		// here we get the plugin
		[Inject(name="assets")]
		public var assets:SomaAssets;

		// here we get a group using a path (ids + delimiter)
		[Inject(name="group0/group00")]
		public var imageGroup:IAssetLoader;
		
		// add some listeners to monitor the loading of a single group 
		override public function initialize():void {
			imageGroup.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
			imageGroup.addEventListener(AssetLoaderEvent.START, startHandler);
			imageGroup.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
			imageGroup.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
		}

		private function errorHandler(event:AssetLoaderErrorEvent):void {
			trace("Error", event.errorType, event.message);
		}

		private function startHandler(event:AssetLoaderEvent):void {
			trace("Loading started (" + ILoader(event.currentTarget).id + ")");
		}

		private function progressHandler(event:AssetLoaderProgressEvent):void {
			trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
		}

		// now the group is loaded, get the 2 images from the group 
		private function completeHandler(event:AssetLoaderEvent):void {
			trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
			var images:Dictionary = event.data;
			trace("asset from dictionary", images["image3"]);
			trace("asset from loader:", imageGroup.getAsset("image3"));
			trace("asset from plugin:", assets.getAssets("group0/group00/image3"));
			var image2:Bitmap = images["image2"];
			var image3:Bitmap = images["image3"];
			image2.x = 290;
			image2.scaleX = image2.scaleY = 0.1;
			image3.x = 340;
			image3.scaleX = image3.scaleY = 0.1;
			view.addChild(image2);
			view.addChild(image3);
		}
		
		override public function dispose():void {
			while (view.numChildren > 0) view.removeChildAt(0);
			view = null;
			imageGroup = null;
		}
		
	}
}

The ExampleAssetCommand command is just a demo to show that you can use the SomaAssetsEvent class to directly create commands from it. In this example I used the type SomaAssetsEvent.ASSET_LOADED. The command will get created every time an asset is loaded.

package com.soma.plugins.assets.demo.commands {

	import com.soma.core.controller.Command;
	import com.soma.core.interfaces.ICommand;
	import com.soma.plugins.assets.SomaAssets;
	import com.soma.plugins.assets.demo.SomaApplication;
	import com.soma.plugins.assets.events.SomaAssetsEvent;

	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.media.Sound;
	import flash.media.Video;
	import flash.net.NetStream;
	import flash.text.TextField;
	import flash.utils.getQualifiedClassName;

	/**
	 * @author Romuald Quantin
	 */
	public class ExampleAssetCommand extends Command implements ICommand {
		
		[Inject]
		public var evt:SomaAssetsEvent;
		
		[Inject(name="assets")]
		public var assets:SomaAssets;
		
		// just some examples
		public function execute(event:Event):void {
			var container:DisplayObjectContainer = SomaApplication(instance).container;
			trace("Command Example (" + evt.path + ") > " + assets.getLoader(evt.path).type + " Loaded: " +  getQualifiedClassName(evt.asset));
			// you can use a switch to find the assets:
			switch (evt.path) {
				case "group0/group01/css":
					break;
				case "group0/group01/json":
					break;
				case "group0/group01/sound":
					var sound:Sound = evt.asset;
					sound.play(0);
					break;
				case "group0/group01/text":
					var textfield:TextField = new TextField();
					textfield.multiline = textfield.wordWrap = true;
					textfield.text = evt.asset;
					container.addChild(textfield);
					break;
				case "group0/group01/xml":
					break;
				case "group0/group01/video":
					var video:Video = new Video();
					var stream:NetStream = evt.asset;
					container.addChild(video);
					video.y = 80;
					video.smoothing = true;
					video.attachNetStream(stream);
					stream.resume();
					break;
				case "group0/group01/zip":
					break;
			}
		}
		
	}
}

This implementation is just an example as it could be handled in very different ways, but that should get you started.

Share and Enjoy!