Posts Tagged “flash”

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:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <loader connection="1">
  3.     <asset id="image0" src="assets/img/image0.jpg" smoothing="true" transparent="true"/>
  4.     <asset id="image1" src="assets/img/image1.jpg" smoothing="true" transparent="true"/>
  5.     <group id="group0">
  6.         <group id="group00">
  7.             <asset id="image2" src="assets/img/image2.jpg" smoothing="true" transparent="true"/>
  8.             <asset id="image3" src="assets/img/image3.jpg" smoothing="true" transparent="true"/>
  9.         </group>
  10.         <group id="group01">
  11.             <asset id="css" src="assets/css/stylesheet.css" preventCache="true" weight="352"/>
  12.             <asset id="json" src="assets/json/data.json" preventCache="true" weight="582"/>
  13.             <asset id="sound" src="assets/sounds/sample.mp3" preventCache="true" weight="16718"/>
  14.             <asset id="text" src="assets/text/text.txt" preventCache="true" weight="574"/>
  15.             <asset id="xml" src="assets/xml/sample.xml" preventCache="true" weight="79"/>
  16.             <asset id="video" src="assets/video/sample.flv" weight="1550580"/>
  17.             <asset id="zip" src="assets/zip/file.zip" weight="3493"/>
  18.         </group>
  19.     </group>
  20. </loader>

First step, I create a SomaCore application.

Actionscript:
  1. public function Main() {
  2.     _app = new SomaApplication(this);
  3. }

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).

Actionscript:
  1. package com.soma.plugins.assets.demo {
  2.  
  3.     import com.soma.plugins.assets.demo.commands.ExampleAssetCommand;
  4.     import com.soma.plugins.assets.events.SomaAssetsEvent;
  5.     import com.soma.core.Soma;
  6.     import com.soma.core.di.SomaInjector;
  7.     import com.soma.core.interfaces.ISoma;
  8.     import com.soma.plugins.assets.SomaAssets;
  9.     import com.soma.plugins.assets.demo.views.ImageGroup;
  10.     import com.soma.plugins.assets.demo.views.ImageGroupMediator;
  11.     import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
  12.     import com.soma.plugins.assets.demo.views.ImageWhenAllLoadedMediator;
  13.     import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
  14.     import com.soma.plugins.assets.demo.views.ImageWhenNotLoadedMediator;
  15.     import com.soma.plugins.assets.demo.wires.InitializeWire;
  16.     import com.soma.plugins.assets.vo.SomaAssetsVO;
  17.  
  18.     /**
  19.      * @author Romuald Quantin
  20.      */
  21.     public class SomaApplication extends Soma implements ISoma {
  22.  
  23.         private var _container:Main;
  24.  
  25.         public function SomaApplication(container:Main) {
  26.             _container = container;
  27.             super(_container.stage, SomaInjector);
  28.         }
  29.        
  30.         // create a command for a demo purpose to monitor the assets that are loaded
  31.         override protected function registerCommands():void {
  32.             addCommand(SomaAssetsEvent.ASSET_LOADED, ExampleAssetCommand);
  33.         }
  34.        
  35.         // register mediators to views
  36.         // the views won't be created at the same moment to show how you can handle your loading
  37.         override protected function registerViews():void {
  38.             mediators.mapView(ImageWhenAllLoaded, ImageWhenAllLoadedMediator);
  39.             mediators.mapView(ImageWhenNotLoaded, ImageWhenNotLoadedMediator);
  40.             mediators.mapView(ImageGroup, ImageGroupMediator);
  41.         }
  42.        
  43.         // create the plugin and register an external assets configuration to load
  44.         override protected function registerPlugins():void {
  45.             createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets.xml"));
  46.         }
  47.        
  48.         // create an wire where you could handle the "global" loading process
  49.         override protected function start():void {
  50.             injector.createInstance(InitializeWire);
  51.         }
  52.        
  53.         // just the document class to add some views to
  54.         public function get container():Main {
  55.             return _container;
  56.         }
  57.        
  58.     }
  59. }

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.

Actionscript:
  1. package com.soma.plugins.assets.demo.wires {
  2.  
  3.     import com.soma.plugins.assets.demo.views.ImageGroup;
  4.     import com.soma.core.interfaces.IWire;
  5.     import com.soma.core.wire.Wire;
  6.     import com.soma.plugins.assets.demo.SomaApplication;
  7.     import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
  8.     import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
  9.     import com.soma.plugins.assets.events.SomaAssetsEvent;
  10.     import flash.display.DisplayObjectContainer;
  11.     import org.assetloader.core.IAssetLoader;
  12.  
  13.     /**
  14.      * @author Romuald Quantin
  15.      */
  16.     public class InitializeWire extends Wire implements IWire {
  17.        
  18.         [Inject(name="assets")]
  19.         public var loader:IAssetLoader;
  20.        
  21.         // register some SomaAssets events for monitoring
  22.         override public function initialize():void {
  23.             addEventListener(SomaAssetsEvent.CONFIG_LOADED, configLoaded);
  24.             addEventListener(SomaAssetsEvent.LOADER_COMPLETE, assetsComplete);
  25.             addEventListener(SomaAssetsEvent.ERROR, assetsErrorHandler);
  26.         }
  27.        
  28.         // shortcut to get the document class
  29.         private function get container() :D isplayObjectContainer {
  30.             return SomaApplication(instance).container;
  31.         }
  32.  
  33.         // in case there's an error for both the assets config or the assets
  34.         private function assetsErrorHandler(event:SomaAssetsEvent):void {
  35.             trace("Asset Error:", event.errorMessage, event.errorType);
  36.         }
  37.        
  38.         // the external XML assets config has been loaded here
  39.         private function configLoaded(event:SomaAssetsEvent):void {
  40.             container.addChild(new ImageWhenNotLoaded());
  41.             container.addChild(new ImageGroup());
  42.             trace("config loaded");
  43.             loader.start();
  44.         }
  45.        
  46.         // all assets container in the config XML have been loaded here
  47.         private function assetsComplete(event:SomaAssetsEvent):void {
  48.             container.addChild(new ImageWhenAllLoaded());
  49.         }
  50.  
  51.     }
  52. }

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

Actionscript:
  1. package com.soma.plugins.assets.demo.views {
  2.  
  3.     import com.soma.core.interfaces.IMediator;
  4.     import com.soma.core.mediator.Mediator;
  5.  
  6.     import flash.display.Bitmap;
  7.  
  8.     /**
  9.      * @author Romuald Quantin
  10.      */
  11.     public class ImageWhenAllLoadedMediator extends Mediator implements IMediator {
  12.  
  13.         [Inject]
  14.         public var view:ImageWhenAllLoaded;
  15.        
  16.         // all the assets are loaded at this point
  17.         // we can inject the asset (or loaders)
  18.         [Inject(name="image0")]
  19.         public var image:Bitmap;
  20.        
  21.         override public function initialize():void {
  22.             image.scaleX = image.scaleY = 0.1;
  23.             image.x = 130;
  24.             view.addChild(image);
  25.         }
  26.        
  27.         override public function dispose():void {
  28.             while (view.numChildren> 0) view.removeChildAt(0);
  29.             view = null;
  30.             image = null;
  31.         }
  32.        
  33.     }
  34. }

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.

Actionscript:
  1. package com.soma.plugins.assets.demo.views {
  2.  
  3.     import flash.display.Bitmap;
  4.     import com.soma.core.interfaces.IMediator;
  5.     import com.soma.core.mediator.Mediator;
  6.  
  7.     import org.assetloader.core.ILoader;
  8.     import org.assetloader.events.AssetLoaderErrorEvent;
  9.     import org.assetloader.events.AssetLoaderEvent;
  10.     import org.assetloader.events.AssetLoaderProgressEvent;
  11.  
  12.     /**
  13.      * @author Romuald Quantin
  14.      */
  15.     public class ImageWhenNotLoadedMediator extends Mediator implements IMediator {
  16.  
  17.         [Inject]
  18.         public var view:ImageWhenNotLoaded;
  19.        
  20.         // here we get the loader of an asset for monitoring purpose
  21.         // this one is an ImageLoader but we keep the interface as a type
  22.         [Inject(name="image1")]
  23.         public var imageLoader:ILoader;
  24.        
  25.         // add some listeners to monitor the loading of a single loader
  26.         override public function initialize():void {
  27.             imageLoader.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
  28.             imageLoader.addEventListener(AssetLoaderEvent.START, startHandler);
  29.             imageLoader.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
  30.             imageLoader.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
  31.         }
  32.  
  33.         private function errorHandler(event:AssetLoaderErrorEvent):void {
  34.             trace("Error", event.errorType, event.message);
  35.         }
  36.  
  37.         private function startHandler(event:AssetLoaderEvent):void {
  38.             trace("Loading started (" + ILoader(event.currentTarget).id + ")");
  39.         }
  40.  
  41.         private function progressHandler(event:AssetLoaderProgressEvent):void {
  42.             trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
  43.         }
  44.        
  45.         // the loader is complete, the asset is ready
  46.         private function completeHandler(event:AssetLoaderEvent):void {
  47.             trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
  48.             var image:Bitmap = event.data;
  49.             image.scaleX = image.scaleY = 0.1;
  50.             view.addChild(image);
  51.         }
  52.        
  53.         override public function dispose():void {
  54.             while (view.numChildren> 0) view.removeChildAt(0);
  55.             view = null;
  56.             imageLoader = null;
  57.         }
  58.        
  59.     }
  60. }

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.

Actionscript:
  1. package com.soma.plugins.assets.demo.views {
  2.  
  3.     import flash.display.Bitmap;
  4.     import com.soma.plugins.assets.SomaAssets;
  5.     import com.soma.core.interfaces.IMediator;
  6.     import com.soma.core.mediator.Mediator;
  7.     import org.assetloader.core.IAssetLoader;
  8.     import org.assetloader.core.ILoader;
  9.     import org.assetloader.events.AssetLoaderErrorEvent;
  10.     import org.assetloader.events.AssetLoaderEvent;
  11.     import org.assetloader.events.AssetLoaderProgressEvent;
  12.     import flash.utils.Dictionary;
  13.  
  14.     /**
  15.      * @author Romuald Quantin
  16.      */
  17.     public class ImageGroupMediator extends Mediator implements IMediator {
  18.  
  19.         [Inject]
  20.         public var view:ImageGroup;
  21.        
  22.         // here we get the plugin
  23.         [Inject(name="assets")]
  24.         public var assets:SomaAssets;
  25.  
  26.         // here we get a group using a path (ids + delimiter)
  27.         [Inject(name="group0/group00")]
  28.         public var imageGroup:IAssetLoader;
  29.        
  30.         // add some listeners to monitor the loading of a single group
  31.         override public function initialize():void {
  32.             imageGroup.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
  33.             imageGroup.addEventListener(AssetLoaderEvent.START, startHandler);
  34.             imageGroup.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
  35.             imageGroup.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
  36.         }
  37.  
  38.         private function errorHandler(event:AssetLoaderErrorEvent):void {
  39.             trace("Error", event.errorType, event.message);
  40.         }
  41.  
  42.         private function startHandler(event:AssetLoaderEvent):void {
  43.             trace("Loading started (" + ILoader(event.currentTarget).id + ")");
  44.         }
  45.  
  46.         private function progressHandler(event:AssetLoaderProgressEvent):void {
  47.             trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
  48.         }
  49.  
  50.         // now the group is loaded, get the 2 images from the group
  51.         private function completeHandler(event:AssetLoaderEvent):void {
  52.             trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
  53.             var images:Dictionary = event.data;
  54.             trace("asset from dictionary", images["image3"]);
  55.             trace("asset from loader:", imageGroup.getAsset("image3"));
  56.             trace("asset from plugin:", assets.getAssets("group0/group00/image3"));
  57.             var image2:Bitmap = images["image2"];
  58.             var image3:Bitmap = images["image3"];
  59.             image2.x = 290;
  60.             image2.scaleX = image2.scaleY = 0.1;
  61.             image3.x = 340;
  62.             image3.scaleX = image3.scaleY = 0.1;
  63.             view.addChild(image2);
  64.             view.addChild(image3);
  65.         }
  66.        
  67.         override public function dispose():void {
  68.             while (view.numChildren> 0) view.removeChildAt(0);
  69.             view = null;
  70.             imageGroup = null;
  71.         }
  72.        
  73.     }
  74. }

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.

Actionscript:
  1. package com.soma.plugins.assets.demo.commands {
  2.  
  3.     import com.soma.core.controller.Command;
  4.     import com.soma.core.interfaces.ICommand;
  5.     import com.soma.plugins.assets.SomaAssets;
  6.     import com.soma.plugins.assets.demo.SomaApplication;
  7.     import com.soma.plugins.assets.events.SomaAssetsEvent;
  8.  
  9.     import flash.display.DisplayObjectContainer;
  10.     import flash.events.Event;
  11.     import flash.media.Sound;
  12.     import flash.media.Video;
  13.     import flash.net.NetStream;
  14.     import flash.text.TextField;
  15.     import flash.utils.getQualifiedClassName;
  16.  
  17.     /**
  18.      * @author Romuald Quantin
  19.      */
  20.     public class ExampleAssetCommand extends Command implements ICommand {
  21.        
  22.         [Inject]
  23.         public var evt:SomaAssetsEvent;
  24.        
  25.         [Inject(name="assets")]
  26.         public var assets:SomaAssets;
  27.        
  28.         // just some examples
  29.         public function execute(event:Event):void {
  30.             var container:DisplayObjectContainer = SomaApplication(instance).container;
  31.             trace("Command Example (" + evt.path + ")> " + assets.getLoader(evt.path).type + " Loaded: " +  getQualifiedClassName(evt.asset));
  32.             // you can use a switch to find the assets:
  33.             switch (evt.path) {
  34.                 case "group0/group01/css":
  35.                     break;
  36.                 case "group0/group01/json":
  37.                     break;
  38.                 case "group0/group01/sound":
  39.                     var sound:Sound = evt.asset;
  40.                     sound.play(0);
  41.                     break;
  42.                 case "group0/group01/text":
  43.                     var textfield:TextField = new TextField();
  44.                     textfield.multiline = textfield.wordWrap = true;
  45.                     textfield.text = evt.asset;
  46.                     container.addChild(textfield);
  47.                     break;
  48.                 case "group0/group01/xml":
  49.                     break;
  50.                 case "group0/group01/video":
  51.                     var video:Video = new Video();
  52.                     var stream:NetStream = evt.asset;
  53.                     container.addChild(video);
  54.                     video.y = 80;
  55.                     video.smoothing = true;
  56.                     video.attachNetStream(stream);
  57.                     stream.resume();
  58.                     break;
  59.                 case "group0/group01/zip":
  60.                     break;
  61.             }
  62.         }
  63.        
  64.     }
  65. }

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

Vote in HexoSearch

Comments No Comments »

Two new releases today, an asset loader and the SomaCore plugin: SomaAssets.

The AssetLoader library is a port from Matan's AssetLoader library to be event-based, it makes you able to load and manage multiple assets (image, video, xml, sound, etc) in your application.

SomaAssets is a plugin based on the AssetLoader library to easily access to your assets and effectively integrate them in your SomaCore application with paths and automatic mapping name generation for injection.

Special thanks to Matan for his help with the AssetLoader and his joy in general, a pleasure to "meet" him.

You can read the SomaAssets wiki section to get started with it, but I'll post below a few hints of what you can easily do with it within a SomaCore application.

AssetLoader source
AssetLoader wiki
SomaAssets source
SomaAssets wiki

Easily create the plugin and add a XML config file for the assets.

Actionscript:
  1. createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets_config.xml"))

Easily retrieve the assets with paths through the XML config.

Actionscript:
  1. var image:Bitmap = assets.getAssets("group0/group00/img0");

Easily retrieve the plugin, main loader, config and assets with injection in a SomaCore application. The following mapping names have been automatically generated from the XML config.

Actionscript:
  1. [Inject(name="assets")]
  2. public var plugin:SomaAssets;
  3.  
  4. [Inject(name="assets")]
  5. public var loader:IAssetLoader;
  6.  
  7. [Inject(name="group0/group00/img0")]
  8. public var loaderType1:ImageLoader;
  9.  
  10. [Inject(name="group0/group00/img0")]
  11. public var assetType1:Bitmap;

Vote in HexoSearch

Comments 3 Comments »

BinderUI is a debugging tools to help you create interfaces and debug values.

Very often I’m sure you spend time building visual interfaces to set, to see and to debug some values.
This can be useful for example to show to the creative (or even the client?) and extract the right values instead of tweaking thing for ages, I’m sure you know what I mean.

That can be time consuming and is often very annoying so I wanted to ease the process (1 line of code and a metadata tag).

BinderUI is a simple static class and the idea is to “bind” a value to visual components such as slider, knob, meter, text input, and so on. For the components I used the library minimalComps.

That means that the bound values will update the components in real-time and the components will update the values (two-ways). I used the BindingUtils and ChangeWatcher classes from the mx package but as it will be for debugging, you can use it on project that will be pure AS3 as well.



Click here to see the demo.

As a quick example, imagine you have a custom darkness property on your custom class, you can bind the value this way:

Actionscript:
  1. BinderUI.displaySliderHorizontal(this, _mySprite, "darkness", "darkness", null, 0.1, 1, -255, 255);

This will create a slider that will update (and be updated) for your darkness property.

You’ll also need to add a Bindable metadata in your class:

Actionscript:
  1. [Bindable]
  2. public class MySprite extends Sprite {

Note: in case you want to debug built-in flash properties (such as x and y), you’ll need to override the properties in your custom class even if it does nothing.

Actionscript:
  1. override public function get x():Number {
  2.     return super.x;
  3. }
  4. override public function set x(value:Number):void {
  5.     super.x = value;
  6. }

For now you can debug only properties (getters and setters), and types that are String, Number, Boolean (and color).

Here is a list of component that can be used.

Actionscript:
  1. BinderUI.displayLabel(this, s, "x")
  2. BinderUI.displayColorChooser(this, sprite, "color", 0xFFFF00);
  3. BinderUI.displayCheckBox(this, sprite, "halfTransparent", "half transparent");
  4. BinderUI.displayIndicatorLight(this, sprite, "halfTransparent", "half transparent");
  5. BinderUII.displayNumericStepper(this, sprite, "x", 5, null, 0, 900, 1);
  6. BinderUI.displayInput(this, sprite, "x");
  7. BinderUI.displaySliderHorizontal(this, sprite, "x", "x", null, 0.1, 1, 0, 900);
  8. BinderUI.displaySliderVertical(this, sprite, "x", "x", null, 0.1, 1, 0, 900);
  9. BinderUI.displayTextarea(this, sprite, "x");
  10. BinderUI.displayKnob(this, sprite, "x", "x", null, Knob.VERTICAL, 20, 0, 900);
  11. BinderUI.displayMeter(this, sprite, "x", "x", null, 0, 900);

In some case, it is harder to bind values, such as when you want to update a component from what you type in a textfield. You’ll need to dispatch an event yourself (usually these events are added by the compiler with the Bindable metadata tag).

Actionscript:
  1. dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, false, false, PropertyChangeEventKind.UPDATE, 'text', oldValue, newValue, this));

About colors, you can use the displayColorChooser method. The easiest is using a “color” property for example.

Actionscript:
  1. BinderUI.displayColorChooser(this, mySprite, "color");

You can also use the colorTransform property but this property is not bindable, so it will work only in one way (component —> target):

Actionscript:
  1. BinderUI.displayColorChooser(this, mySprite.transform, "color");

You can also use the MinimalConfigurator to create your interface from an XML file.

Three methods are available to dispose (remove and destroy) components. You can dispose by target, by component or dispose everything.

Actionscript:
  1. BinderUI.disposeByTarget(mySprite);
  2. BinderUI.disposeByComponent(myComponent)
  3. BinderUI.dispose();

Download source and demos.
Source on github.

Vote in HexoSearch

Comments No Comments »

I've added some more information on the SomaCore wiki.

You can find some code and explanation how to use, create and remove Wires within the framework, using injection or not. I also explained how to monitor and control the application flow with methods you are used to, such as dispatchEvent, addEventListener, preventDefault and so on.

You can also find explanation to handle the views in the framework.

Last addition is a diagram showing the commands flow from other framework elements, I've added it to the previous SomaCore diagram.

SomaCore Diagram


Next step in the wiki are about commands and 2 others diagrams related to them.

Hope that will help to get you started.

Vote in HexoSearch

Comments No Comments »

I'll be writing in the next days a series of wiki, manual, best practices with tons of code example. It should help you to get started. I will be explaining in-depth how SomaCore works and what you can do with it.

The first one is about the Framework Instance. The different ways to create a SomaCore application, what is required, how to enable dependency injection and how to access to this instance.

Vote in HexoSearch

Comments 2 Comments »