Posts Tagged “soma”

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 »

Hi everyone,

In case you didn't notice that I released an new minimal AS3 MVC Framework some time ago, SomaCore is available on this page.

I call it minimal because it is very lightweight, yet powerful and non-intrusive. You don't have much to learn if you're used to MVC framework of any sort.

I made an update today, the second one in months because it won't change a lot, the structure is there. All the sources and demo have been updated.

You can also replace any kind of previous use of the framework, the only feature added is a dispose method that will remove everything that has been created in the framework. Mostly useful in case you're creating several instance of the framework, it will now be correctly garbage collected.

Once you've created a instance of the framework:

Actionscript:
  1. var app:ISoma = new Application(stage);

The only things you need to do is

Actionscript:
  1. app.dispose();
  2. app = null;

Here is what it is doing to the components that have been added to the frameworks:

- all wires will be removed. On each wire, the dispose method will be called. You can overwrite this dispose method in your wires subclasses.

- all models will be removed. On each model, the dispose method will be called. You can overwrite this dispose method in your models subclasses.

- all commands will be removed

- all views will be removed but not removed from the display list, that's your job. On each view, a dispose method will be called if it exists. You can create this dispose method in your views:

Actionscript:
  1. public function dispose():void {
  2.     // dispose objects, graphics and events listeners
  3. }

It important to say that all the components will be removed from the framework, but that's your matter to properly destroyed what you're creating in order to be garbage collected.

A quick info for my plans because I've silent lately (busy).

I'll make a BaseUI release in the next weeks, a completely rebuilt and optimized version 4. It is ready but I need to finish the documentation.

After that I plan to make more examples and screen cast about the SomaCore Framework.

I just wanted to say that I'm rarely happy about what I'm producing, because I like things to be... perfect. Of course, perfection can't be reached, but that is pushing me to create the better code I can, at my level.

I'm now using SomaCore in some projects. One is a relatively complicated AIR Modular Application for children. And for once, I'm very happy with what I've done with SomaCore. It has been a great help really, I should say that it saves me a lot of troubles when changes happened because I built the application how I wanted it, without "framework-fight" and as much flexible as I could. It just made me more responsive to any kind of changes in the project.

For this reason, I'll try to push SomaCore further by making more demos, videos, examples, documentation, wires concept and so on.

I still have plans to create a new version of the first automated framework Soma MVC, and its source generator, based on SomaCore.

Happy development!

Vote in HexoSearch

Comments 3 Comments »

I've updated the debugger used in SomaCore. You can know click on everything to parse the objects and I've added a FPS + Memory meter. I'll continue to improve the debugger with my needs, next step might be a Garbage Collection monitor.

Click here to see the debugger in action.

Tips: if you close the debugger, type "debug" to get it back.

Here is a little bit of code in case you want to want to use the debugger without using the SomaCore Framework.

Actionscript:
  1. package {
  2.    
  3.     import flash.display.Sprite;
  4.     import com.soma.core.Soma;
  5.     import com.soma.core.interfaces.ISoma;
  6.     import com.soma.debugger.SomaDebugger;
  7.     import com.soma.debugger.vo.SomaDebuggerVO;
  8.     import com.soma.debugger.events.SomaDebuggerEvent;
  9.    
  10.     public class Main extends Sprite {
  11.        
  12.         function Main() {
  13.             // create soma application
  14.             var app:ISoma = new Soma(stage);
  15.             // create debugger options
  16.             var vo:SomaDebuggerVO = new SomaDebuggerVO(app, SomaDebugger.NAME_DEFAULT, [], true, false);
  17.             // create debugger
  18.             var debugger:SomaDebugger = app.createPlugin(SomaDebugger, vo) as SomaDebugger;
  19.             // use debugger
  20.             debug("Hello Debugger");
  21.             debug(this);
  22.             debug(app);
  23.         }
  24.        
  25.         private function debug(obj:Object):void {
  26.             // use app.dispatchEvent() from a class that is not in the display list
  27.             dispatchEvent(new SomaDebuggerEvent(SomaDebuggerEvent.PRINT, obj));
  28.             // events available:
  29.             // SomaDebuggerEvent.SHOW_DEBUGGER;
  30.             // SomaDebuggerEvent.CLEAR;
  31.             // SomaDebuggerEvent.PRINT;
  32.             // SomaDebuggerEvent.HIDE_DEBUGGER;
  33.             // SomaDebuggerEvent.MOVE_TO_TOP;
  34.         }
  35.        
  36.     }
  37.    
  38. }

Vote in HexoSearch

Comments No Comments »

A minor update for Soma and SomaUI, mostly bug fixes. The source are available available on the SomaUI page.

SomaUI v2.0.2

-bug fixed: page selection in the page tab wasn't working properly
-bug fixed: layout tab and layout properties wasn't correctly updating the XML
-bug fixed: Flash Player wasn't correctly updated in Page Settings tab when opening a project
-update: new page auto-name renamed to Page1, Page2, etc
-update: Soma v2.0.2

Soma v2.0.2

-bug fixed: layout with a background alpha 0 wasn't displayed

Note: to update sources already exported with a version 2.0.x, just grab the com.soma package (or SWC) and replace, or in SomaUI, in the export tab and under Soma Framework, select "overwrite all".

Vote in HexoSearch

Comments 3 Comments »

Here is a new Video Tutorial about the MovieClip Page Mode in Soma, it might remind you the Flash Catalyst workflow. This mode is only for Flash IDE user. I'm creating a designed site in few minutes by importing Photohop Files in MovieClip that wll be managed by Soma.

The PageManager will instantiate MovieClip instead or pure actionscript class. It is a very useful mode if you want to build your site with the Flash IDE with a minimum of code, and very quickly.

SomaUI MovieClip Page Mode Video Tutorial


Vote in HexoSearch

Comments No Comments »