Posts Tagged “air”

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 »

SomaCore is a lightweight AS3 MVC event-based framework that provides a very flexible structure for your Flash, Flex and AIR projects.

The main addition in this version 2 is Dependency Injection, but it is up to you how you want to use SomaCore because injection is optional.

Information

SomaCore Main Page (tutorials, demos, source)
Repository SomaCore (github)
Repository Demos (github)
Repository Plugins (github)
Documentation

Don't want to read, just show me some code!

SomaCore Hello World
SomaCore CafeTownSend (Flex)
Twitter Search demo (pure as3)

SomaCore is both a registry and dependency injection framework

As a base, SomaCore is a registry framework, much like PureMVC. The framework makes you able to add and remove elements to the framework instance to be able to access them from anywhere (such as addView, getView, addWire, getWire, addModel, getModel, addCommand, and so on).

Enable injection

You are now able to use dependency injection. It can be enabled by sending an ISomaInjector class to the constructor of the Soma class:

Actionscript:
  1. public class SomaApplication extends Soma implements ISoma {
  2.     public function SomaApplication(stage:Stage) {
  3.         super(stage, SomaInjector);
  4.     }
  5. }

The injector is accessible from framework instances, wires and commands using the property injector.

Here is a quick example:

Actionscript:
  1. injector.mapToInstance(MyModel, new MyModel());
  2. injector.mapSingleton(MyWire);
  3. injector.getInstance(MyWire);

Actionscript:
  1. package  {
  2.     import com.soma.core.wire.Wire;
  3.     import com.soma.core.interfaces.IWire;
  4.    
  5.     public class MyWire extends Wire implements IWire {
  6.  
  7.         [Inject]
  8.         public var model:MyModel;
  9.        
  10.         override public function initialize():void {
  11.             // called when the wire has been registered to the framework
  12.             trace(model, " is injected");
  13.         }
  14.        
  15.         override public function dispose():void {
  16.             // called when the wire has been removed from the framework
  17.         }
  18.        
  19.     }
  20. }

Inspirations

Before going further, I have to give some credits.

When I first tried Robotlegs, one part strikes me as it was solving a problem I had for a while: The mediator system: being able to build your application and add mediators regardless of any kind of structure and very easily. This workflow was so nice that it made me rethink a lot of things.

SomaCore has some capabilities that made me build the framework and I wasn't ready to give them up. But I felt that this mediator workflow in SomaCore would just be amazing and a great addition.

I built these tools and frameworks to make my developer life easier, I then share them to other developers. If my work makes them enjoy their coding, that's good enough for me.

So before asking myself too many questions, I reproduced the mediator system in SomaCore. It is now very similar to Robotlegs but it can also be used without enabling injection. That is the first part of the credits: a big one to Robotlegs that has been an amazing inspiration to SomaCore, as big as PureMVC has been for the version 1.

The second credit would go to the library SwiftSuspenders, the same one that Robolegs is using to handle its dependency injection. It is very lightweight and has good performance.

Mediators

Here is how it works, you can map a view to another class (the mediator), and every time this "mapped view" will be added to a display list, the mediator class will be instantiated with a reference to this view. The mediator class will also be destroyed when the view is removed from the display list. Everything is automatic and handled by the framework.

In SomaCore the Mediator class is extending the Wire class which gives access to everything in the framework.

Mapping a view (example in a wire):

Actionscript:
  1. mediator.mapView(MySprite, MySpriteMediator);

The mediator get instantiated when the view is added to the display list

Actionscript:
  1. addChild(new MySprite());

Mediator example:

Actionscript:
  1. package {
  2.     import com.soma.core.interfaces.IMediator;
  3.     import com.soma.core.mediator.Mediator;
  4.     public class MySpriteMediator extends Mediator implements IMediator {
  5.        
  6.         [Inject]
  7.         public var view:MySprite;
  8.        
  9.         override public function initialize():void {
  10.             // called when the mediator has been created and registered to the framework
  11.             trace(view == viewComponent);
  12.         }
  13.        
  14.         override public function dispose():void {
  15.             // called when the mediator has been destroyed by the framework
  16.         }
  17.        
  18.     }
  19. }

From version 1 to version 2

Only minor changes:

1. initialize and dispose methods in wires and models are now public.

Actionscript:
  1. package  {
  2.     import com.soma.core.interfaces.IModel;
  3.     import com.soma.core.model.Model;
  4.     public class ModelExample extends Model implements IModel {
  5.         override public function initialize():void {
  6.             // called when the model has been registered to the framework
  7.         }
  8.         override public function dispose():void {
  9.             // called when the model has been removed from the framework
  10.         }
  11.     }
  12. }

2. the framework instance property has changed from soma to instance.

Actionscript:
  1. package  {
  2.     import com.soma.core.wire.Wire;
  3.     import com.soma.core.interfaces.IWire;
  4.     public class WireExample extends Wire implements IWire {
  5.         override protected function initialize():void {
  6.             // called when the wire has been registered to the framework
  7.             trace("my framework instance:", instance)
  8.         }
  9.         override protected function dispose():void {
  10.             // called when the wire has been removed from the framework
  11.         }
  12.     }
  13. }

3. a public setup method is available in your framework instance.

Actionscript:
  1. var app:ISoma = new Soma();
  2. app.setup(stage, SomaInjector);

4. an initialize and start protected methods have been added in the Soma instance.

Actionscript:
  1. package  {
  2.     import com.soma.core.Soma;
  3.     import com.soma.core.interfaces.ISoma;
  4.     import com.soma.core.di.SomaInjector;
  5.     import flash.display.Stage;
  6.     public class SomaApplication extends Soma implements ISoma {
  7.         public function SomaApplication(stage:Stage) {
  8.             super(stage, SomaInjector);
  9.         }
  10.         override protected function initialize():void {
  11.            
  12.         }
  13.         override protected function registerCommands():void {
  14.            
  15.         }
  16.         override protected function registerModels():void {
  17.            
  18.         }
  19.         override protected function registerViews():void {
  20.            
  21.         }
  22.         override protected function registerWires():void {
  23.            
  24.         }
  25.         override protected function registerPlugins():void {
  26.            
  27.         }
  28.         override protected function start():void {
  29.            
  30.         }
  31.     }
  32. }

SomaCore features

Here are some features that might makes you enjoy the framework.

Stage as single event dispatcher

SomaCore is using a single event dispatcher: the stage, and a system of event interception to handles its commands system. As the commands in SomaCore are normal built-in events with the property bubbles set to true, this makes you able to dispatch commands straight from a view removing potential layers (like mediators) to handles communications from the views to the framework.

This also makes you able to communicate between different modules (or swf files) as they all share the same stage.

Seamless commands and events integration

The commands in SomaCore are normal built-in events and the framework has a seamless integration with the flash event system. Seamless meaning that the built-in syntax is in use: dispatchEvent, addEventListener, and so on.

Register a command:

Actionscript:
  1. addCommand(MyEvent.DO_SOMETHING, MyCommand);

Dispatch a command from a framework elements (wires, commands, models, etc) or views:

Actionscript:
  1. dispatchEvent(new MyEvent(MyEvent.DO_SOMETHING));

Monitoring commands from wires, mediators, or models:

Actionscript:
  1. addEventListener(MyEvent.DO_SOMETHING, myEventHandler);

Commands monitoring

This capability is probably one of the most important to me. SomaCore makes you able to listen to commands from any wires and mediators, but also makes you able to stop the execution of any command (if the event is set as cancelable) using event.preventDefault().

Actionscript:
  1. package  {
  2.     import com.soma.core.wire.Wire;
  3.     import com.soma.core.interfaces.IWire;
  4.     public class WireExample extends Wire implements IWire {
  5.         override public function initialize():void {
  6.             // called when the wire has been registered to the framework
  7.             addEventListener(MyEvent.DO_SOMETHING, myEventHandler);
  8.         }
  9.         private function myEventHandler(event:MyEvent):void {
  10.             // the command MyEvent.DO_SOMETHING has been dispatched
  11.             // I can monitor it here (possible from any wires and mediators)
  12.             // for some reasons, I decide to stop the execution of this command:
  13.             event.preventDefault();
  14.         }
  15.         override public function dispose():void {
  16.             // called when the wire has been removed from the framework
  17.             removeEventListener(MyEvent.DO_SOMETHING, myEventHandler);
  18.         }
  19.     }
  20. }

Easy way to map a mediator to a view

This is the workflow I reproduced from Robotlegs. It allows you to build you application, let's say... complicated layouts, structure, tons of views, and so on. But at any point, if the framework needs to talk to a specific view, you can easily map a mediator to this view:

Actionscript:
  1. mediator.mapView(MyView, MyViewMediator);

For the other way around: a view needs to talk to the framework, mediators are not necessarily needed as you can dispatch commands straight from views in SomaCore. The commands are just normal events. The only requirement is that the view needs to be on the stage (added to a display list, after a ADDED_TO_STAGE event) in order for the stage to get the command.

Flexibility (injection, not injection, or both)

As the injection is optional in the framework, you are free to code the way you like, in the registry way like PureMVC way or in the injection way like Robotlegs, or even using both ways in the same time.

For some reasons, you might want to avoid injection, describeType, getElementByName, not comfortable yet with the concept, portability, optimal performance for games, etc. This is still possible with SomaCore.

Here are the built-in registry methods without injection:

Actionscript:
  1. addWire(MyWire.NAME, new MyWire());
  2. getWire(MyWire.NAME);
  3. addModel(MyModel.NAME, new MyModel());
  4. getModel(MyModel.NAME);
  5. addView(MY_SPRITE_NAME, new Sprite());
  6. getView(MY_SPRITE_NAME);

With injection, you might do something like:

Actionscript:
  1. injector.mapSingleton(MyModel);
  2. injector.createInstance(MyWire);

Actionscript:
  1. // MyWire injectee class
  2. [Inject]
  3. public var model:MyModel;

You can also use both:

Actionscript:
  1. var wire:MyWire = new MyWire();
  2. injector.mapToInstance(MyWire, wire);
  3. addWire(MyWire.NAME, wire);

Making you able to get the wire back this 2 ways:

Actionscript:
  1. [Inject]
  2. public var wire:MyWire;

Actionscript:
  1. getWire(MyWire.NAME)

Plugins system

An easy way to add plugins to the framework, the SomaDebugger is the first one but I have plans to write others.

Debugger

The SomaDebugger especially built to work with SomaCore (even if it can be used without).

Actionscript:
  1. protected function registerPlugins():void {
  2.     createPlugin(SomaDebugger, new SomaDebuggerVO(this, SomaDebugger.NAME_DEFAULT, getCommands(), true, false));
  3. }

Lightweight

SomaCore is lightweight, here are the size compiled of the framework:

9.46 KB (9 693 bytes) - injector not enabled
14.83 KB (15 185 bytes) - injector enabled

Next steps

I'll make new documents for code examples, best practices, and so on to help you get started.
Maybe a javascript version as a developer has made an amazing port of SomaCore.

If you're looking for more information about the dependency injection part before I write documents, check the README file from the injection library: SwiftSuspenders.

Try SomaCore out, it is really easy to get started with. You'll feel at home very quickly with its flexibility and well integrated command system with built-in events.

Vote in HexoSearch

Comments 4 Comments »

I've decided to put my framework SomaCore on Github.

SomaCore is a lightweight event-based MVC framework written in AS3 that provides a structure, models, views management and commands. Somacore can be used for Flash, Flex and AIR projects.

SomaCore does not use any external library and does not use dependency injection.

SomaCore is completely event-based and use a concept of wires to code in an efficient decoupled way.

Framework
http://github.com/soundstep/somacore_framework
Demos
http://github.com/soundstep/somacore_demos
Plugins
http://github.com/soundstep/somacore_plugins
Blog Page (with demos)
http://www.soundstep.com/blog/downloads/somacore/
Video tutorial
http://www.soundstep.com/blog/source/somacore/tutorials/getting-started/
Documentation
http://www.soundstep.com/blog/source/somacore/docs/

A very handy capability of the framework among others is the way you can monitor the flow of your application. SomaCore is using the the flash model to monitor commands and even intercept them in a way so that any actionscript developer will feel at home. Example in a wire class to listen and intercept a command:

Actionscript:
  1. // listen to a command
  2. addEventListener(MyEvent.DO_SOMETHING, commandHandler);
  3. // remove a listener
  4. removeEventListener(MyEvent.DO_SOMETHING, commandHandler);
  5.  
  6. private function commandHandler(event:MyEvent):void {
  7.     // intercept (if the event is cancelable)
  8.     e.preventDefault();
  9. }

Click here to see one of the demo code to get started.

Some other things to know about the framework

  • Commands are normal built-in Flash events with the bubbles property set to true.
  • Commands can be used in the views as they are not really framework code.
  • Parallel and sequence commands are built-in.
  • Wires are the glue of the frameworks elements (models, commands, views, wires) and can be used the way you wish, as proxy/mediators or managers.
  • Wires can manage one class or multiple classes.
  • Wires and commands access to all the framework elements (stage, framework instance, wires, models, views and commands).
  • Plugins can be created for the framework (such as the SomaDebugger plugin).
  • Powerful flow control using the built-in flash event model.

Here is how to get started with github:
http://help.github.com/



Vote in HexoSearch

Comments 1 Comment »

I've just uploaded a new video tutorial (48 min) for my lightweight AS3 MVC Framework SomaCore.

You can now get started with it. I explain how to create the framework instance, how to create a wire, create views, create commands and how to intercept them.

SomaCore Getting Started Video Tutorial

I hope you like it!

Vote in HexoSearch

Comments 4 Comments »

Here is how to bring life to an image using the filter DisplacementMapFilter.

Click here to see the demo.

I got the idea from a video made by Chad Perkins (thanks Chad, you're giving me a lot of inspiration!) where he is showing this effect in After Effects. My Flash nature pushed me to reproduced it with AS3. The result is great even if the After Effects version is slightly better, maybe the Flash version can be tweaked a bit more.

Here is how it works. I used this wonderful picture from my friend Ziemowit Maj :)

You also need a second picture that will describe the map of the filter using luminance. The foreground areas should be whiter than the background areas. I made this picture using Photoshop, the brush tools, and of course my proven drawing skills :D

I apply the DisplacementMapFilter on a BitmapData and I move the map position over time. It is not too complicated, but you can probably spend more time than me to draw the map correctly. Be careful not to make a distortion too big or it will look weird! Here is the code:

Actionscript:
  1. package {
  2.     import caurina.transitions.Tweener;
  3.  
  4.     import flash.display.Bitmap;
  5.     import flash.display.BitmapData;
  6.     import flash.display.BitmapDataChannel;
  7.     import flash.display.PixelSnapping;
  8.     import flash.display.Sprite;
  9.     import flash.display.StageAlign;
  10.     import flash.display.StageScaleMode;
  11.     import flash.events.Event;
  12.     import flash.filters.DisplacementMapFilter;
  13.     import flash.filters.DisplacementMapFilterMode;
  14.     import flash.geom.Point;
  15.     import flash.geom.Rectangle;
  16.  
  17.     /**
  18.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  19.      * <b>Company:</b> Less Rain - <a href="http://www.lessrain.com/" target="_blank">www.lessrain.com</a><br />
  20.      * <b>Class version:</b> 1.0<br />
  21.      * <b>Actionscript version:</b> 3.0<br />
  22.      * <b>Copyright:</b>
  23.      * <br />
  24.      * <b>Date:</b> Aug 16, 2010<br />
  25.      * <b>Usage:</b>
  26.      * @example
  27.      * <listing version="3.0"></listing>
  28.      */
  29.    
  30.     public class Main extends Sprite {
  31.        
  32.         [Embed(source="../assets/photo.jpg")]
  33.         private var Photo:Class;
  34.         [Embed(source="../assets/map.jpg")]
  35.         private var Map:Class;
  36.        
  37.         private var _photo:Bitmap;
  38.         private var _map:Bitmap;
  39.         private var _point:Point;
  40.         private var _photoDisplaced:Bitmap;
  41.         private var _photoDisplacedData:BitmapData;
  42.         private var _filter:DisplacementMapFilter;
  43.        
  44.         private var _range:Number = 17;
  45.  
  46.         //------------------------------------
  47.         // private, protected properties
  48.         //------------------------------------
  49.        
  50.        
  51.  
  52.         //------------------------------------
  53.         // public properties
  54.         //------------------------------------
  55.        
  56.        
  57.        
  58.         //------------------------------------
  59.         // constructor
  60.         //------------------------------------
  61.        
  62.         public function Main() {
  63.             initialize();
  64.         }
  65.  
  66.         //
  67.         // PRIVATE, PROTECTED
  68.         //________________________________________________________________________________________________
  69.        
  70.         private function initialize():void {
  71.             // stage
  72.             stage.frameRate = 41;
  73.             stage.align = StageAlign.TOP_LEFT;
  74.             stage.scaleMode = StageScaleMode.NO_SCALE;
  75.             // photo
  76.             _photo = new Photo();
  77.             // photoDisplaced
  78.             _photoDisplacedData = new BitmapData(_photo.width, _photo.height);
  79.             _photoDisplaced = new Bitmap(_photoDisplacedData, PixelSnapping.AUTO, true);
  80.             _photoDisplaced.scaleX = 1.05;
  81.             _photoDisplaced.scaleY = 1.05;
  82.             _photoDisplaced.x = (stage.stageWidth - _photo.width)>> 1;
  83.             _photoDisplaced.y = (stage.stageHeight - _photo.height)>> 1;
  84.             addChild(_photoDisplaced);
  85.             // map
  86.             _map = new Map();
  87.             // point
  88.             _point = new Point(-(_range), 0);
  89.             // enterframe
  90.             addEventListener(Event.ENTER_FRAME, loop);
  91.             // scroll motion
  92.             move(_range);
  93.         }
  94.  
  95.         private function move(target:Number):void {
  96.             Tweener.addTween(_point, {time:2, x:target, transition:"linear", onComplete:move, onCompleteParams:[target*-1]});
  97.         }
  98.  
  99.         private function loop(event:Event):void {
  100.             _filter = new DisplacementMapFilter(
  101.                 _map.bitmapData,
  102.                 _point,
  103.                 BitmapDataChannel.RED,
  104.                 BitmapDataChannel.RED,
  105.                 _point.x,
  106.                 _point.y,
  107.                 DisplacementMapFilterMode.WRAP);
  108.             _photoDisplacedData.applyFilter(_photo.bitmapData, _photoDisplacedData.rect, new Point(0,0), _filter);
  109.             _photoDisplaced.bitmapData.draw(_photoDisplacedData, null, null, null, new Rectangle( _point.x, _point.y, _photo.width, _photo.height), true);
  110.         }
  111.        
  112.         // PUBLIC
  113.         //________________________________________________________________________________________________
  114.        
  115.        
  116.        
  117.     }
  118. }

Vote in HexoSearch

Comments 4 Comments »