Posts Tagged “as3”

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 »

Another SomaCore demo is available on Githug or on the SomaCore page.

This demo is relatively simple. Keywords are sent to the Twitter API using a command that is dispatched straight from the view as it is something possible with SomaCore. A command is nothing more than a flash built-in event. The views are able to dispatch commands without accessing to a mediator first and stay completely free of framework code.

A TwitterService dispatch a search result event after getting the data. The wire responsible of the main view is listening to the search result event and update the view.

The SearchWire class demonstrates that both commands and events can be listened to from any wire.

The control of the flow of the application is also very flexible, the SearchWire class could have stopped the search command for any reason using event.preventDefault() as the class is listening to the command (if the event is sent with a cancelable property set to true).

Any commands in SomaCore can be listened to in any wires, and can also be "default prevented".

Twitter Search

SomaCore Twitter Search

View Demo
View Source
Download Source

Credits: Inspired by a great Flex Robotlegs demo by John Lindquist, using the AS3 API library Tweetr.

Vote in HexoSearch

Comments 1 Comment »

I've added a very simple SomaCore Hello World demo.

The application creates a wire, a view and a model. The view dispatch a command to request a message, the command ask the data to the model, the model gets the data and dispatch an event to notify the framework, the wire catch the event and update the view with the message.

That's all!

The demo is also available from the demo repository on Github:
http://github.com/soundstep/somacore_demos

Hello World

SomaCore Hello World

View Demo
View Source
Download Source

Vote in HexoSearch

Comments 1 Comment »

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 updated SomaUI, the AIR tool that generates the draft of a Flash website build with SomaMVC. Sorry for the late update but you can now use the generator with Flex 4 and target the Flash Player 10.1.

To avoid a confusion, SomaUI is an AIR tool that generates AS3 sources build with the AS3 MVC Framework SomaMVC.

SomaMVC has nothing to do with SomaCore, they are 2 different frameworks and don't share the same goal.

While SomaMVC (which would entered in the same category as the Gaia Framework) is meant to be generated and rely on an XML File to describe and build its content, SomaCore is a lightweight MVC framework that doesn't build anything for you and would entered in the same category as PureMVC.

I intend at some point to rebuild SomaMVC using SomaCore and unify these 2 projects.

You can find the new SomaUI version on this page or on the Google code project.

Vote in HexoSearch

Comments 17 Comments »