Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

2. Framework instance

soundstep edited this page · 2 revisions

Document class

The first step to start building an application using SomaCore is to create a instance of the framework.

The shortest way is the following:

var app:ISoma = new Soma(stage);

However, the best way to create this instance is to create a class that will be the Facade of the framework and the application. In this example, I will create a class named SomaApplication.

Here is an example in a Document Class:

package  {
	import com.soma.core.interfaces.ISoma;
	import flash.display.Sprite;
	
	public class Main extends Sprite {
		
		private var _app:ISoma;
		
		public function Main() {
			_app = new SomaApplication(stage);
		}
		
	}
}

SomaCore needs the stage to be instantiated and will throw an Error if you try to use a stage that is null. If your movie will be loaded, the stage in your Document Class will be null. Here is how to solve the problem:

package  {
	import com.soma.core.interfaces.ISoma;
	import flash.display.Sprite;
	import flash.events.Event;
	
	public class Main extends Sprite {
		
		private var _app:ISoma;
		
		public function Main() {
			addEventListener(Event.ADDED_TO_STAGE, addedToStage); 
		}

		private function addedToStage(event:Event):void {
			removeEventListener(Event.ADDED_TO_STAGE, addedToStage); 
			_app = new SomaApplication(stage);
		}
		
	}
}

Framework instance

The nest step is to create the framework instance. This class must extends the class Soma and implements the interface ISoma.

The stage must be passed to the super class Soma or you can use the public method setup. This action will trigger the initialization of the framework.

In the following example are some overridden methods in case you want to create some framework elements (wires, commands, models, views, mediator mapping, injector configuration, and so on). That’s it, you’re ready to start!

package  {
	import com.soma.core.Soma;
	import com.soma.core.interfaces.ISoma;
	import flash.display.Stage;
	
	public class SomaApplication extends Soma implements ISoma {

		public function SomaApplication(stage:Stage) {
			super(stage);
		}
		
		override protected function initialize():void {
			
		}

		override protected function registerModels():void {
			
		}

		override protected function registerViews():void {
			
		}

		override protected function registerCommands():void {
			
		}

		override protected function registerWires():void {
			
		}

		override protected function registerPlugins():void {
			
		}
		
		override protected function start():void {
			
		}
		
	}
}

These methods that you can override will be executed in this order:

  1. initialize
  2. registerModels
  3. registerViews
  4. registerCommands
  5. registerWires
  6. registerPlugins
  7. start

You are free to create framework elements where you want, but it is a good practice to create important elements and commands in the Facade. In this way, another developer would find very quickly what are the commands available and important elements.

You can create the framework instance in Flex in the same way (pure as3), but here is an example if you want to create the instance using an mxml tag:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:soma="com.soma.demos.*"
			   minWidth="955" minHeight="600">
	<fx:Declarations>
		<soma:SomaApplication container="{this}" />
	</fx:Declarations>
</s:Application>

package com.soma.demos {
	import com.soma.core.Soma;
	import com.soma.core.interfaces.ISoma;
	import flash.display.Stage;
	import flash.events.Event;
	
	public class SomaApplication extends Soma implements ISoma {
		
		private var _container:MyApplication;
		
		public function set container(value:MyApplication):void {
			// register container, listen to the added to stage event
			_container = value;
			_container.addEventListener(Event.ADDED_TO_STAGE, added);
		}

		private function added(event:Event):void {
			setup(_container.stage);
		}
		
	}
}

Enable injection

Dependency injection is optional in SomaCore because the framework can be use without it, and also to keep it as light as possible if you don’t want or need injection.

SomaCore is using an external library to handle its injection: SwiftSuspenders.

To enable the injection, the Soma Class can receive in its constructor or its setup method a Class that must extend the injector adapter ISomaInjector. The framework will take care of the instantiation of this adapter.

Here is an example to enable the injection in SomaCore:

package  {
	import com.soma.core.Soma;
	import com.soma.core.interfaces.ISoma;
	import com.soma.core.di.SomaInjector;
	import flash.display.Stage;
	
	public class SomaApplication extends Soma implements ISoma {

		public function SomaApplication(stage:Stage) {
			super(stage, SomaInjector);
		}
		
	}
}

Access to the framework instance from other elements

The framework instance you have created is easily accessible from wires, mediators and commands using the property instance. Here is an example in a wire:

package  {
    import com.soma.core.wire.Wire;
    import com.soma.core.interfaces.IWire;
    
    public class WireExample extends Wire implements IWire {
        
        override public function initialize():void {
            trace("My framework instance", instance);
        }
        
    }
}

It is a common practice to add getters in the framework instance in case you need to access variables from anywhere. For instance, very often you might need to access to your document class, here is an example:

package  {
	import com.soma.core.interfaces.ISoma;
	import flash.display.Sprite;
	public class Main extends Sprite {
		private var _app:ISoma;
		public function Main() {
			// create the framework instance passing the Document Class
			_app = new SomaApplication(this);
		}
	}
}

package  {
	import com.soma.core.Soma;
	import com.soma.core.interfaces.ISoma;
	import flash.display.Stage;

	public class SomaApplication extends Soma implements ISoma {
		
		private var _container:Main;
		
		public function SomaApplication(container:Main) {
			_container = container;
			super(_container.stage);
		}
		
		public function get container():Main {
			return _container;
		}
	}
}

package  {
    import com.soma.core.wire.Wire;
    import com.soma.core.interfaces.IWire;
    
    public class WireExample extends Wire implements IWire {
        
        override public function initialize():void {
            var container:Main = SomaApplication(instance).container;
            trace("My Document Class", container);
        }
        
    }
}

Code Examples

Here are some more “real world” framework instance examples from SomaCore demos.

package com.soma.core.demo.helloworld {
    import com.soma.core.Soma;
    import com.soma.core.demo.helloworld.controller.commands.MessageCommand;
    import com.soma.core.demo.helloworld.controller.events.MessageEvent;
    import com.soma.core.demo.helloworld.mediators.MessageViewMediator;
    import com.soma.core.demo.helloworld.models.MessageModel;
    import com.soma.core.demo.helloworld.views.MessageView;
    import com.soma.core.di.SomaInjector;
    import com.soma.core.interfaces.ISoma;

    import flash.display.StageAlign;
    import flash.display.StageScaleMode;

    public class SomaApplication extends Soma implements ISoma {
        
        private var _container:Main;

        public function SomaApplication(container:Main) {
            _container = container;
            super(_container.stage, SomaInjector);
        }

        override protected function initialize():void {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
        }

        override protected function registerCommands():void {
            addCommand(MessageEvent.REQUEST, MessageCommand);
        }
        
        override protected function registerModels():void {
            injector.mapSingleton(MessageModel);
        }
        
        override protected function registerViews():void {
            mediators.mapView(MessageView, MessageViewMediator);
            _container.addChild(new MessageView());
        }
        
        public function get container():Main {
            return _container;
        }
        
    }
}
package com.soundstep.somacolor {
    import com.greensock.plugins.TintPlugin;
    import com.greensock.plugins.TweenPlugin;
    import com.soma.core.Soma;
    import com.soma.core.di.SomaInjector;
    import com.soma.core.interfaces.ISoma;
    import com.soma.debugger.SomaDebugger;
    import com.soma.debugger.events.SomaDebuggerEvent;
    import com.soma.debugger.vo.SomaDebuggerVO;
    import com.soundstep.somacolor.controllers.commands.ASyncCommand;
    import com.soundstep.somacolor.controllers.commands.ColorCommand;
    import com.soundstep.somacolor.controllers.commands.MoveViewCommand;
    import com.soundstep.somacolor.controllers.commands.ParallelTestCommand;
    import com.soundstep.somacolor.controllers.commands.SequenceStopCommand;
    import com.soundstep.somacolor.controllers.commands.SequenceTestCommand;
    import com.soundstep.somacolor.controllers.commands.TweenCommand;
    import com.soundstep.somacolor.controllers.commands.TweenSequenceCommand;
    import com.soundstep.somacolor.controllers.events.ASyncEvent;
    import com.soundstep.somacolor.controllers.events.ChainEvent;
    import com.soundstep.somacolor.controllers.events.ColorDataEvent;
    import com.soundstep.somacolor.controllers.events.ColorEvent;
    import com.soundstep.somacolor.controllers.events.MoveViewEvent;
    import com.soundstep.somacolor.controllers.events.SequenceEvent;
    import com.soundstep.somacolor.controllers.events.TweenEvent;
    import com.soundstep.somacolor.controllers.events.TweenSequenceEvent;
    import com.soundstep.somacolor.models.ColorModel;
    import com.soundstep.somacolor.views.ColorReceiver;
    import com.soundstep.somacolor.views.ColorSelector;
    import com.soundstep.somacolor.views.ColorSquare;
    import com.soundstep.somacolor.wires.ColorWire;

    import flash.display.Stage;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;

    public class SomaApplication extends Soma implements ISoma {

        private var _debug:Boolean;

        public var name:String = "SomaColor";
        
        public function SomaApplication(stage:Stage, debug:Boolean = false) {
            _debug = debug;
            super(stage, SomaInjector);
        }
        
        override protected function initialize():void {
            TweenPlugin.activate([TintPlugin]);
            stage.frameRate = 41;
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            // injector
            injector.mapSingleton(ColorWire);
            injector.mapSingleton(ColorModel);
            injector.mapSingleton(ColorReceiver);
            injector.mapSingleton(ColorSelector);
            injector.mapSingleton(ColorSquare);
        }
        
        override protected function registerCommands():void {
            addCommand(ChainEvent.CHAIN, ParallelTestCommand);
            addCommand(ASyncEvent.CALL, ASyncCommand);
            addCommand(ASyncEvent.CHAIN, SequenceTestCommand);
            addCommand(TweenEvent.TWEEN, TweenCommand);
            addCommand(TweenSequenceEvent.SEQUENCE, TweenSequenceCommand);
            addCommand(SequenceEvent.STOP_ALL_SEQUENCES, SequenceStopCommand);
            addCommand(ColorDataEvent.LOAD, ColorCommand);
            addCommand(ColorDataEvent.UPDATED, ColorCommand);
            addCommand(ColorEvent.CHANGE_COLOR, ColorCommand);
            addCommand(MoveViewEvent.MOVE_VIEW, MoveViewCommand);
        }

        override protected function registerPlugins():void {
            if (_debug) {
                var pluginVO:SomaDebuggerVO = new SomaDebuggerVO(this, SomaDebugger.NAME_DEFAULT, getCommands(), true, false);
                createPlugin(SomaDebugger, pluginVO) as SomaDebugger;
            }
        }
        
        override protected function start():void {
            dispatchEvent(new ColorEvent(ColorDataEvent.LOAD));
            dispatchEvent(new SomaDebuggerEvent(SomaDebuggerEvent.MOVE_TO_TOP));
        }
        
        public function debug(value:Object):void {
            if (_debug) dispatchEvent(new SomaDebuggerEvent(SomaDebuggerEvent.PRINT, value));
        }
        
    }
}
package com.cafetownsend {

    import com.cafetownsend.commands.EmployeeCommand;
    import com.cafetownsend.commands.LoginCommand;
    import com.cafetownsend.commands.NavigationCommand;
    import com.cafetownsend.events.EmployeeEvent;
    import com.cafetownsend.events.LoginEvent;
    import com.cafetownsend.events.NavigationEvent;
    import com.cafetownsend.models.EmployeeModel;
    import com.cafetownsend.views.MainView;
    import com.cafetownsend.views.components.EmployeeDetails;
    import com.cafetownsend.views.components.EmployeeList;
    import com.cafetownsend.views.components.LoginView;
    import com.cafetownsend.views.mediators.EmployeeDetailsMediator;
    import com.cafetownsend.views.mediators.EmployeeListMediator;
    import com.cafetownsend.views.mediators.LoginViewMediator;
    import com.soma.core.Soma;
    import com.soma.core.di.SomaInjector;
    import com.soma.core.interfaces.ISoma;
    import com.soma.debugger.SomaDebugger;
    import com.soma.debugger.vo.SomaDebuggerVO;
    
    import flash.events.Event;
    
    import mx.core.IVisualElement;

    public class SomaApplication extends Soma implements ISoma {
        
        private var _container:SomaCoreCafeTownSend;

        private function added(event:Event):void {
            // initialize application (stage needed)
            setup(_container.stage, SomaInjector);
        }
        
        override protected function initialize():void {
            // map the Main View and the model to instantiated only once
            injector.mapSingleton(MainView);
            injector.mapSingleton(EmployeeModel);
            // map views to mediators
            mediators.mapView(LoginView, LoginViewMediator);
            mediators.mapView(EmployeeList, EmployeeListMediator);
            mediators.mapView(EmployeeDetails, EmployeeDetailsMediator);
        }
        
        override protected function registerCommands():void {
            // login
            addCommand(LoginEvent.LOGIN, LoginCommand);
            addCommand(LoginEvent.LOGOUT, LoginCommand);
            addCommand(LoginEvent.SUCCESS, LoginCommand);
            addCommand(LoginEvent.ERROR, LoginCommand);
            addCommand(LoginEvent.MESSAGE, LoginCommand);
            // navigation
            addCommand(NavigationEvent.SELECT, NavigationCommand);
            // command
            addCommand(EmployeeEvent.SELECT, EmployeeCommand);
            addCommand(EmployeeEvent.DELETE, EmployeeCommand);
            addCommand(EmployeeEvent.CREATE, EmployeeCommand);
            addCommand(EmployeeEvent.EDIT, EmployeeCommand);
            addCommand(EmployeeEvent.UPDATED, EmployeeCommand);
        }
        
        override protected function registerViews():void {
            // add Main View (ViewStack) to the display list
            _container.addElement(IVisualElement(injector.getInstance(MainView)));
        }
        
        override protected function registerPlugins():void {
            // create Soma Debugger
            createPlugin(SomaDebugger, new SomaDebuggerVO(this, SomaDebugger.NAME_DEFAULT, getCommands(), true, false));
        }
        
        public function set container(value:SomaCoreCafeTownSend):void {
            // register container, listen to the added to stage event
            _container = value;
            _container.addEventListener(Event.ADDED_TO_STAGE, added);
        }

    }
}
package com.cafetownsend {
    
    import com.cafetownsend.commands.NavigationCommand;
    import com.cafetownsend.commands.StartCommand;
    import com.cafetownsend.events.NavigationEvent;
    import com.cafetownsend.events.StartEvent;
    import com.cafetownsend.wires.EmployeeWire;
    import com.cafetownsend.wires.LoginWire;
    import com.soma.core.Soma;
    import com.soma.core.interfaces.ISoma;
    import com.soma.debugger.SomaDebugger;
    import com.soma.debugger.vo.SomaDebuggerVO;

    public class SomaApplication extends Soma implements ISoma {
        
        private var _app:SomaCoreCafeTownSend;
        
        public function SomaApplication(app:SomaCoreCafeTownSend) {
            _app = app;
            super(app.stage);
        }
        
        override protected function registerCommands():void {
            addCommand(StartEvent.START, StartCommand);
            addCommand(NavigationEvent.SELECT, NavigationCommand);
        }
        
        override protected function registerViews():void {
            addView(LoginWire.NAME_VIEW_LOGIN, app.loginView);
            addView(EmployeeWire.NAME_VIEW_EMPLOYEE_LIST, app.employeList);
            addView(EmployeeWire.NAME_VIEW_EMPLOYEE_DETAILS, app.employeDetails);
        }
        
        override protected function registerWires():void {
            addWire(LoginWire.NAME, new LoginWire());
            addWire(EmployeeWire.NAME, new EmployeeWire());
        }
        
        override protected function registerPlugins():void {
            // debugger plugin
            createPlugin(SomaDebugger, new SomaDebuggerVO(this, SomaDebugger.NAME_DEFAULT, getCommands(), true, false));
        }
        
        override protected function start():void {
            dispatchEvent(new StartEvent(StartEvent.START));
        }
        
        public function get app():SomaCoreCafeTownSend {
            return _app;
        }
        
    }
}
package com.soma.core.demo.twittersearch {
    import com.soma.core.demo.twittersearch.views.MainView;
    import com.soma.core.Soma;
    import com.soma.core.demo.twittersearch.controller.commands.SearchCommand;
    import com.soma.core.demo.twittersearch.controller.events.TwitterEvent;
    import com.soma.core.demo.twittersearch.services.TwitterService;
    import com.soma.core.demo.twittersearch.wires.SearchWire;
    import com.soma.core.di.SomaInjector;
    import com.soma.core.interfaces.ISoma;

    import flash.display.StageAlign;
    import flash.display.StageScaleMode;

    /**
     * @author romuald
     */
    public class SomaApplication extends Soma implements ISoma {
        
        private var _container:Main;

        public function SomaApplication(container:Main) {
            _container = container;
            super(_container.stage, SomaInjector);
        }

        override protected function initialize():void {
            // stage
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            // injector
            injector.map(MainView, MainView);
            injector.mapSingleton(TwitterService);
            injector.mapSingleton(SearchWire);
            injector.createInstance(SearchWire);
        }
        
        override protected function registerCommands():void {
            addCommand(TwitterEvent.SEARCH, SearchCommand);
        }
        
    }
}
Something went wrong with that request. Please try again.