SyntaxScrewer's Blog

February 11, 2010

RobotLegs – What is it ?

Filed under: ActionScript 3.0 — geekymaira @ 5:17 pm

RobotLegs Example : Get it here (I would recommend that you go through this post or the RobotLegs docs once before attempting to go through the example).

I was asked to mess around with RobotLegs and try and understand how it works in the process. Now, I’ve been coding for a few years but never have I formally implemented a design pattern or framework. Well at least not ‘consciously’. So this really gave me a chance to dive into all that good stuff. It wasn’t easy to be honest but Google & the RobotLegs documentation helped a lot.

NOTE: I still haven’t completely figured out the framework. There are certain things I’m confused about. But I’ve managed to build an example which actually works in Flash CS4 successfully. I will make an attempt at explaining the basics of the framework in this article and you can read more about the example I created here.  Also, this post is going to be longggggggggggggg. The best way to go through it is read it all at once. You might not understand all of it but keep going and give it one complete reading.  Then look at the example I’ve linked to. I’ve got comments in there so it shouldn’t be hard :).

So let’s get started.

Here’s a quick navigation to help you hunt 🙂

What is a Design Pattern ?
What is an Architectural Pattern ?
What is a Framework ?
Relationship b/w framework and design patterns
What is the MVC architectural pattern ?
What is Dependency Injection ?
Using SwiftSuspender for Dependency Injections.
What is the Context ?
What is the Command ?
What is the Mediator ?
Relationship b/w framework events, command & mediator
What is a the Model ?

There are a few concepts that you should be familiar with before starting out. I’ll go over those first.

What is a Design Pattern ?

To put it very simply, a design pattern is a tried & tested solution to a complex software design problem. It’s called a pattern because software design problems can be thought of as following a  pattern. So you can think of “design” patterns as something which helps you solve a common design problem that you may run into while  you’re designing your software. There are various design patterns, and each solves specific design problems.

For example: You find yourself in a situation where you figure out that for a particular class, lets call it “MyClass”, you need only 1 object, lets call it “MyObject”, throughout the scope of your project. So what is the first thing that you do ? Well, you make “MyClass” a singleton. I’m sure you’ve done this a lot of times (and if you haven’t you should!) but did you know that you’ve been “unknowingly” implementing the “Singleton” design pattern?  😮
UPDATE: Check out “Amy Blankenship” comment for more about Singleton & RobotLegs

Once you are familiar with the basics of each design pattern, it’s just a matter of implementing the “right” one to help you solve your problem. It is important to note that design patterns are a “way” of doing things. They don’t translate directly into the code that you’d write to get it done. That depends on your expertise. Lastly, using design patterns can help speed up your design and tackle subtle problems that you might not anticipate right now (but the design pattern does 🙂 ). But please read about them before you start implementing them.

What is an Architectural Pattern ?

You can think of Architectural patterns as being similar to design patterns but much larger in scope. Like design patterns focus on specific software “design” problems in software engineering, architectural patterns tackle “architectural” problems in software engineering. A typical architectural pattern would provide an organized structure for your software system. In simpler words, it’ll help you define subsystems, their responsibilities and interlinking. Choice of an architectural pattern depends on the various qualities that an architect would want in the software.

For example: If you want a system which has the “quality” of being “high” in performance, you’d probably go with an architectural pattern that helps you just that. Since qualities like “performance” may be common to many systems, it’s not surprising to find that most of them follow the same architectural pattern.

RobotLegs is based on the Model,View,Controller (MVC) architectural pattern. I’ll explain what that is soon.

What is a Framework ?

Wikipedia has a nice succinct explanation for this.

A software framework is a re-usable design for a software system (or subsystem). A software framework may include support programs, code libraries, a scripting language, or other software to help develop and glue together the different components of a software project. Various parts of the framework may be exposed through an API.

In other words, a framework can be thought of as a skeleton of code that we use to create our applications. A framework is developed using one or more design/architectural patterns. In turn, it provides implementations to those design/architectural patterns. In layman terms, a framework can be thought of something that bridges a gap between you & the design/architectural pattern

What is the relation between a framework and a design pattern ?

If you look over my explanation of design patterns, I mentioned that they are a “way” of doing things and not actually the “code” to do those things. Well, framework is that actual “code”.

This will be clearer when we look at the RobotLegs definition later.

What is the MVC architectural pattern ?

The MVC architectural pattern stands for the “Model View Controller” architectural pattern. I’m not going to venture deep into the details of MVC, I’ll leave the research to you. But to give you a broad overview : MVC comprises of 3 things, A Model, A View & A Controller. Your software is divided into these 3 tiers if you use the MVC pattern. The reason to do this is to reduce “coupling”, which basically means reducing the interdependence between the layers/tiers. The MVC pattern, isolates the “application logic” from the “presentation” & “input”. Lets quickly go over the 3 components of MVC.

VIEWS : This is what a user sees on the screen and interacts with. Typically these are User Interface(UI) elements. The view works on the model to which its linked and presents the data to the user via the UI element.

MODEL : This is where you house the logic for the views that are associated with the model.

CONTROLLER : This component receives user inputs and makes calls on the model.

Oooo I forgot to mention that a typical application would have multiple sets of Views-Model-Controllers , one for each UI element.

What is Dependency Injection ?

I’m going to leave this one out for you to understand yourself :). Wikipedia has a nice explanation and you should be able to understand what this is and why this is needed after going through the following link. However, if you’re still confused. Feel free to ask me over email/comments.

http://en.wikipedia.org/wiki/Dependency_injection

Okay, so now that we’ve got all of the basics out of the way lets look at RobotLegs!

RobotLegs is an AS3 framework for Flash & Flex that implements the MVC (Model View Controller) architectural pattern using Dependency Injection(DI).

For DI RobotLegs relies on SwiftSuspenders. I’m hoping that you will now be able to see sense in the definition. There are various MVC based frameworks for web technologies. If we talk about Actionscript specifically we have PureMVC. Similarly, we now have RobotLegs too.

Lets quickly go over the basics of RobotLegs and understand the terminologies etc. The RobotLegs Best Practices documentation is an elaborate explanation of the whole framework and you should definitely go through it once. You can also start by going over the RobotLegs overview document which is a quick explanation of the framework actors (I’ll explain what these are in a minute) .  I will be explaining the same things, but I will try to keep them simple. But, please keep in mind that I am also starting out with it and my knowledge on the subject is limited to only what I’ve figured out. (Right or Wrong, only time will tell!).

Hmmm, so we know that RobotLegs is based on MVC. However, it extends this pattern by adding a “Service” to it , thus making it the MVCS pattern. But we will not really talk about the Service part in this example because I still don’t know what it is :). I just don’t want you to be alarmed and confused when you read “MVCS” instead of “MVC”. The RobotLegs framework has some fancy sounding terms that we really need to understand. Collectively, these are called the “framework actors” and comprise of the following: Contexts, Mediators, View Components, Models, Services and Commands. There is also the Injector but we won’t categorize under the framework actors. We also have a commandMap and a mediatorMap but more on those later too.

Dependency Injections using an Injector & the SwiftSuspenders Adapter
The SwiftSuspernders Adapter is a library to carry out Dependency Injections automatically in RobotLegs.  You should now know what DI actually means.

The adapter offers 3 ways to carry out dependency injections.

  1. Field/Property  Injections
  2. Method Injections (typically for getter ad setter methods).
  3. Constructor Injections.

Lets look at how property injections work, first by understanding what they are, and then by looking at some code. Also, please note that I’m heavily borrowing from the RobotLegs best practices documentation. So the rest of this article would be an explanation on subjects already explained in the documentation. I know it’s a lot of rework but it helps me understand the concepts better when  I try and explain them in my own language.

Field/Property injections occur when you want to inject the value of a field/property (nothing but a data member) into your class.

For example :

package
{
public class MyClass
{
[Inject]
var myProperty: MyOtherClass;
}
}

In the example above, we have a dependency in class “MyClass” to an object of the class “MyOtherClass”. To use property injection we write “[Inject]” on top of the variable name and
the injection is carried out automatically. Of course we have to setup the injection first. There are 2 kinds of property injections. The example above is an “unnamed” injection. The
“named” injections look something like this.

[Inject(name="injectionName")]
var myProperty: MyOtherClass;

The ‘injector’ is used to carry out all the injections. It is a SwiftSuspenderInject object and is usually used to inject “framework actors” but is not limited to that. If you want to define an injection
mapping of any class object in your application, you’d most probably do it using the ‘injector’ object. The actual instantiation of the object will be discussed later, for now just assume that you have the
object available to play around with.

There are 4 kinds of injection mappings that can be used with the ‘injector’ object. This concept “Injection mapping” will be clear to you soon.

1. mapValue
2. mapClass
3. mapSingleton
4. mapSingletonOf

mapValue : Let me take you through an example first.

package
{
import org.robotlegs.mvcs.Context
import org.robotlegs.adapters.SwiftSuspendersInjector
import flash.display.MovieClip
import xx.xx.MyDependentClass

public class  MyExample extends Context
{

public function MyExample(contextView:DisplayObjectContainer):void
{
super(contextView); //Don't worry about this for now
}

override public function startup():void
{
var newObject:MovieClip= new MovieClip();
//Setting up an injection mapping using mapValue mapping.
injector.mapValue(MovieClip, newObject);
var myDependentObject:MyDependentClass = new MyDependentClass();
//Manually inject the mapping into the dependent class.
injector.injectInto(myDependentObject);
}
}
}

The code above sets up a mapValue mapping for the MovieClip class using a specific instance (object) of the class.

Let’s go through the code line by line (only the one’s relevant, ignore the rest for now).

var newObject:MovieClip= new MovieClip();
//Setting up an injection mapping using mapValue mapping.
injector.mapValue(MovieClip, newObject);
var myDependentObject:MyDependentClass = new MyDependentClass();
//Manually inject the mapping into the dependent class.
injector.injectInto(myDependentObject);

Once you import “org.robotlegs.adapters.SwiftSuspendersInjector” class you get a referece to a SwiftSuspendersInjector object called “injector”. Now you know what
I’ve been blabbering about for so long. Previously, whenever I’ve mentioned the word “injector” I was referring to this object. The code above is actually doing the real
work. So what we’re trying to achieve here is this. We want that we setup an injector mapping in such a way, that all the classes which are dependent on the MovieClip
object should get ‘newObject’ . The mapValue(MovieClip, newObject) basically creates a mapping for the ‘injector’ and tells it something like “Whenever you see that there
is an injection call for an object of type MovieClip, inject it with ‘newObject”. The injector.injectInto(myDependentObject) actually carries out the injection.
NOTE :We have to explicitly call the injector.injectInto() function here because we are creating a new object of the dependent
class here which will not have its dependencies injected automatically. So we must invoke the ‘injectInto’ call or alternatively manually add it. (By modifying XML_CONFIG, I think :S).

Let’s look at a class which requires this injection. [ie. a class “dependent” on this injection mapping]

package xx.xx
{
public class MyDependentClass
{
[Inject]
public var NeedAMovieClipInjection:MovieClip
}
}

Assuming, that your Injections are setup properly this would work fine. The “NeedAMovieClipInjection” object would receive the value of “newObject” from the
injector (defined and mapped in the example context class).
NOTE: I am slightly confused as to where the inject.injectInto() method needs to be called. I should figure it out soon and update this post. Please bear with me!

mapClass : Like mapValue, the mapClass method also provides a mapping for the injector. The difference here is that while mapValue injects a *specific*  value into the class requesting the injection, mapClass creates a new Object of the class to be injected. In other words it provides a *unique* instance for injection.  Please note the difference between the words “specific” and “unique”. While specific refers to a “particular” object to be inserted, “unique” refers to a new object that is passed on for injection. So all the requesting classes will get a “new” object.

mapSingleton : In this only one instance of the object to be injected is created and the singleton nature is managed by the framework. This “singleton” object is passed around for injection to requesting classes. NOTE: We don’t have to enforce the concept of “Singleton” in the class. The framework handles this.  The singleton object is created only when the first request for injection is made by any of the dependent classes. Unlike the mapValue method, the object to be inserted is not already created and available for injection.

That’s about it for the injector.We have only gone through the Field/Property injections but there are Constructor & Method injections too. The workings remain the same with just slight tweaks. As you might have guessed, constructor injections pass parameters to dependent class constructors and method injections will most probably pass parameters to dependent methods. For more you information look through examples in the SwiftSuspenders Document and you should be able to understand how these work.

Next we shift our focus to the framework actors, and we start with The Context!

A Context is the heart and soul of the RobotLegs implementation. It provides a mechanism by which all other framework actors (or framework tiers) will communicate. Typically an application would have only 1 context but it may have more if required. According to the RobotLegs docs , “The Context has three functions within an application: provide initialization, provide de-initialization, and provide the central event bus for communication.” Confused??? , I was too :).

Let me break this down for you and the best way to do so is looking at a context class example.

package
{
import org.robotlegs.mvcs.Context
public class  ContextExample extends Context
{
public function ContextExample (contextView:DisplayObjectContainer):void
{
super(contextView); //It's time to worry about this now 🙂
}

//The Context startup function
override public function startup():void
{
//Setup the commandMap

//Setup the mediatorMap

//Setup injector mappings

//Manually add something to stage (if needed)

//Call the base class startup function
super.startup();
}
}

The Context is typically instantiated in your Main (or DocumentMain) class. From there you pass a (DisplayObjectContainer) reference which is usally “this”, to the context constructor.
The contextView now becomes your DisplayObjectContainer for the rest of the application and will function similar to the Stage. So you can addChildren to this and they’ll show up in
the swf.

If we look at the code abaove, we have an import statement to import the Context class from the RobotLegs framework. Your context class will always extend this class.
In the constructor, we have a parameter of type DisplayObjectContainer. This is passed when the Context is created, from your Main class. The DisplayObjectContainer
reference is passed onto the base class constructor.

After that we have the startup function. We must override this because it exists in the base class as well (or it’s in the Interface, not sure). The important thing is that we
must override it. Inside the startup function we set up our mappings ie. Command mappings, Mediator mappings and Injector mappings. Lastly, we make  a call to the
base class startup method.

A context provides a central event bus. It also provides a scope within which all the framework actors live and communicate. A context takes care of its own startup and
shutdown. As stated earlier, there is usually a single context in an application but it is possible to have multiple contexts too. A typical scenario to have multiple context’s
would be when one wants to load up an external module.

Next in line for discussion we have the Command!.

The “Controller” tier in MVC is represented by the Command framework actor in RobotLegs. The simple purpose of this actor is to respond to framework events.
RobotLegs relies on flash events for communication between actors. These are typically custom events but can also be existing flash events.  We’ll talk more about them
later. So a command responds to a framework event. These events are dispatched either from the Mediator , the Model , the Service or other Commands.
Ok but how does the framework know which command to execute for which event?  Well, it uses something called the commandMap. If you glimpse through the startup
function of the context above, you’ll notice that I have a comment there which says , setup the commndMap.  This is where you define the events – to – command mappings :).
The commandMap object is also available in the Command and not only in the Context. So I’m guessing one can define some mappings here too.
But i’m not sure!! Try it out and let me know too 🙂

Commands are stateless and short lived. They perform a unit of work and then die. Commands are used to communicate with application tiers. What does that mean ?
We’ll talk more on how commands do that after we finish our Mediator discussion. For now, lets first look at a command class skeleton, so we know how to create one.
We’ll also look at how a command is mapped to a commandMap by going over the mapping syntax.

public class MyCommand extends Command
{
[Inject]
public var event:MyCustomEvent;

[Inject]
public var model:MyModel;

override public function execute():void
{

 //Do something in response to the event.

//Dispatch an event to the framework, for the mediator to receive.

//Chain commands.
}
}

The first thing to note is that the commands you create will extend the Command class. Next, there are some dependencies that are injected into the command class
by default. Like for example, the event which triggered the command is injected automatically. So we have a few [inject] metadata tags in the class to facilitate  these
dependency injections. Next, we have the “execute” function which we must ovveride. This function is called automatically when the command is instantiated.
The RobotLegs documentation has made it a point to state that the execute() function must never be explicitly invoked. It’s the frameworks
responsibility to call it.

Let’s talk about how the actually “event” to “command” mapping is carried out, in terms of code syntax. Assume that the following is written in the startup() function
of the Context.

commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, CreateRectangleCommand, ContextEvent, true);

So what just happened up there ? We performed a command mapping – to what? – to an event – which event ? – A custom event called STARTUP_COMPLETE – where is it defined?
– in the ContextEvent class – what is the CreateRectangleCommand ? – It’s the command class we want initialized and executed when the event fires – What is the next parameter? –
It’s an optional parameter for the Event class – I don’t know what’s the use of this – and the last parameter ? – That’s a “one off ” setting parameter – What the hell does that mean ? – Well, it
tells the Command if it’s supposed to trigger once and then unregister so that it doesn’t fire again when the same event fires again. ie. The command goes “off” only once.  (triggers once!).
Oh yeah, the commandMap.mapeEvent() function actually performs the mapping 🙂

The command may perform a few tasks in its execute() function. It may call a method of the Model to update some data. It may also dispatch events which may
trigger other commands (this is called chaining of commands). Or it may dispatch events which are received by a Mediator. More on that when we study about
Mediators.

A few last notes on Commands. They are never explicitly instantiated or executed from a Mediator, Model or Service. They always respond to framework events
the mappings to which are defined in the Context. So, when the framework “hears” an event that it’s been “listening” for , and it finds a command mapped to that event
in the commandMap it will instantiate the associated command and also call its execute() function.

A command may do one or more of the following to perform its duties.

– Map Mediators, Models, Services, or other Commands within their Context  ( I don’t know what this means!! sorry 😦 ).
– Dispatch Events to be received by Mediators or trigger other Commands (I’ve already talked about this).
– Be injected with Models, Services, and Mediators to perform work on directly. (I’ve touched upon this too).

Note : The RobotLegs documentation says that it’s not a good idea to interact directly with a Mediator inside a command. This couples the Mediator with the Command
and the whole idea of using MVC (which promotes decoupling) is lost. However, there is a workaround but we’ll talk about that later. You must have noticed that I’ve been
procrastinating talking about some stuff. This stuff is related to the relationship between Mediators and Commands. I took a while to understand this and so I thought
of tackling it later in a separate section rather than mixing it in with all of this. So don’t worry, I will talk about it , but lets finish our discussion on other framework actors first.


Okay, so lets talk about Mediators now. Wait, let me get a cup of coffee. brb!.

Hmmm, so the View tier in RobotLegs is represented by the Mediator. They sit between the framework and the view. All framework interaction with the views, goes through the
Mediator. No wonder it’s name 😛  . 

NOTE : MEDIATORS ARE THE ONLY ACTORS IN THE FRAMEWORK THAT CAN RECEIVE EVENTS. IT MIGHT SEEM LIKE COMMANDS ALSO RECEIVE EVENTS BUT THEY DONT.
THEY ARE TRIGGERED BY EVENTS.

A Mediator will do one or more of the following.

– It will listen for framework events.
– It will add event listeners to view components. (Suppose you have a rectange on the stage , which is a movieClip. You want to detect a rollover on it. You’ll add the event listener for this in the Mediator.)
– Send framework events in response to events received from the View Components they are responsible for. (I have no clue what this means !!! The doc says it. Let me know if u understand pls)

So the thing to remember is that a Mediator is always associated with a View and also that they interact with the framework on behalf of this view.
Let’s look at an example to understand how a mediator would typically work.

Suppose you want a movieclip on stage to do something every frame, maybe change its location. Since, its  a visual element , you’d create a view for the mc. (We’ll see how when we talk about views).
You’d also want to add an ENTER_FRAME event to the framework. You’ll add a listener to this event in the Mediator which is mapped to the view. The mediator will receive the event, and update
the view. (In our case, change the position of the MC).

The Mediator acts upon the view it’s mediating via the Views API. What this simply means is that in the View class we create a public function that we call from the Mediator when we want the
view to act upon an event. All this will be clearer, when you look at the RobotLegs example that I’ve posted.

To connect a Mediator with  a View we need to define  a mapping. We do this using the mediatorMap object. This object is available in the Context, Mediator & Command classes and thus
the mapping can be defined anywhere. However, we will define our mediator mappings  in our Context class (go back to the context class code).

The syntax for the mapping is simple .

mediatorMap.mapView(viewClassOrName:* , mediatorClass:Class , injectViewAs:Class = null , autoCreate:Boolean , autoRemove:Boolean) : void

Let’s look at the parameters :

– viewClassOrName : Simple, the view class which the mediator controls.
– mediatorClass : The class for the mediator.
– injectViewAs : I don’t know what this does. It’s defaulted to  null so I guess we can leave it.
– autoCreate : If true, this specifies that the Mediator will be created automatically whenever the View dispatches is “ADDED_TO_STAGE” event. This happens when the view is added to the Context.
– autoRemove : If true, this removes the mediator object. (Not sure though!!).

Let’s see a typical mapping example.

mediatorMap.mapView(MyView, MyViewMediator, null , true, true);

Now sometimes, you might not want the mediator created automatically and would want to do it manually. You can manually create a mediator as follows :


mediatorMap.mapView(MyView,MyViewMediator, null , false);  // I think by default if you don't specify the autoCreate property it defaults it to true.

mediatorMap.createMediator(contextView);    // This manually creates the mediator.

There might be times where you want to have a mediator for the entire application!!! . ie. You want a mediator for a contextView. How do you achieve this ?
Well, you define the mediator mapping in the startup() function of the Context, and then you manually create the mediator. You don’t have a choice since the
contextView has already been added , and its ADDED_TO_STAGE has already been fired.

ovveride public function startup():void
{
mediatorMap.mapView (myContextExample, myAppMediator);

mediatorMap.createMediator(contextView);
}
}

A property called “viewComponent” is inserted in the Mediator by default. This can be used to interact with the view that the mediator is mapped to. However, this
is of the type “Object”. Instead of using this property we can also inject a type instance of the view being mediated.

Let’s look at some code now on how to write  a mediator.


import org.robotlegs.mvcs.Mediator;

public class RectangleBoxMediator extends Mediator
{
 //Setting up the injection for the view.
[Inject]
public var view:RectangleBox;  //The view associated with this mediator.

[Inject]
 public var appModel:AppModel; //The model

 public function RectangleBoxMediator()
 {
trace("Oooo!! mediator initilized!");
 }

//This is a good place to add event listeners.
//This function is called once the mediator has been mapped to the view.
override public function onRegister():void
{

//Adding framework event listeners.
eventMap.mapListener(eventDispatcher , ContextEvent.BA_BA_BLACK_SHEEP_EVENT , handleBlaBlEvent);

//Add view event listeners.
eventMap.mapListener(view, MouseEvent.ROLL_OVER, rollOverHandler);
eventMap.mapListener(view, MouseEvent.ROLL_OUT, rollOutHandler);
 }
function handleBlaBlEvent(evt:ContextEvent)
{
dispatch (new CustomEvent(CustomEvent.RANDOM_EVENT, view.randomData));
}
function rollOverHandler(evt:MouseEvent)
{
view.doSomething();
}
function rollOutHandler(evt:MouseEvent)
{
view.doSomethingElse();
}
}

The code above creates a mediator class called “RectangleBoxMediator”. It extends the framework Mediator class.  Injections to the view are setup.
A function called OnRegister() is overriden. This is where we’ve added the events we want this mediator to work with. There are 2 kinds of event
listeners that we’ve added.

1) A framework event listener – This is a listener for an event that might occur in the Context. It’s not specific to the view.  Every actor has access to
an “eventDispatcher” property. The mediator uses this for sending / receiving framework events.

2) View event listeners – The mediator also listens for events that are triggered on the view component that it mediates.

The eventMap.mapListener() function adds the listener to the mediator and also removes it when the mediator is unregistered.

The mediator can also dispatch events if needed. (Like shown above).  This is typically done to inform other actors that something
has happened.

That’s enough about the Mediator. Let’s now talk about the relationship between Framework events, the Command & the Mediator.

Relationship b/w framework events – Commands & Mediators.

Ok, no more procrastinating. I’m going to talk about something now, which took me a while to understand. The relationship between the events, commands
and mediators. Where do the events get dispatched from ? Are they handled in the Command or the Mediator ? or both ? What’s correct ?

Well, let me explain to you what can happen. Since a mediator is the only actor that can receive framework events and a command is triggered on a framework
event,  you might find yourself in a situation where you’re making a command for an event and also handling it in the mediator.  If this happens, then the correct
way to do is to first map the event to a command – and in the command execute() – dispatch a custom event which is handled by the mediator.

If you follow this approach, then the flow of  handling events will always be Context -> Event -> Command -> Mediator.

Another thing, I followed the RobotLegs docs and I thought that all the events that I want to listen for, I must map them to Commands. I didn’t understnd the
framework completely. So I had these commands that I had created which were empty, and the events that were mapped to these commnds, I was handling
them in the Mediator. I couldn’t understand why we need to create commands, if the events are handled in the mediator. I hadn’t understood the correct
flow/ handling of events. 🙂

So to summarize, an event can trigger a command and also be handled in a mediator !!
Another important point to note about framework events is that  :

“Events can be dispatched from any framework actor ie. Models, Mediators, Commands & Services (We don’t include Views because those are handled by mediators)
but can only be received by Mediators.

Alright, lets move ahead and wrap up this discussion by talking about the “Model”.

The model is where all the data gets worked upon in your application. Calculations / Updations / Deletions to data will take place in the model class.  The model class gives access
to the applications data model.  The model would typically expose some API (public functions) for other actors to access / manipulate application data. Further, a model class
may also dispatch some events when it wants to inform the actors that changes / updations to the data have been made.

A model is mapped to an injection so that it’s available to other actors. This mapping is done in the Context.

//Setting up an injection mapping using mapSingleton.
injector.mapSingleton(AppModel);    //AppModel is the name of the model class. NOTE: We can use any form of injection mappings.

It is worth noting that while Models can dispatch events, it is HIGHLY DISCOURAGED that models listen for events.

Well, that’s all I have to discuss about RobotLegs for now. I haven’t touched upon “Services” because I haven’t really implemented them. I will try and update this post when I
read and implement them.

I recommend that you check out the RobotLegs example that I’ve written for a better understanding of how the whole framework  works.

Hope this helps 🙂

Cheers!

-SyntaxScrewer

Advertisements

6 Comments »

  1. Excellent, really help to understand this RL complex stuff, many thanks

    Comment by Nikos — July 9, 2010 @ 7:52 pm | Reply

  2. did you find out the answer to your injection query?

    Comment by Nikos — July 9, 2010 @ 7:52 pm | Reply

  3. Hey, thanks for your comment. Which injection query are you referring to?

    Comment by geekymaira — July 9, 2010 @ 11:02 pm | Reply

  4. NOTE: I am slightly confused as to where the inject.injectInto() method needs to be called. I should figure it out soon and update this post. Please bear with me!

    I think this only needs to be called if their is no metadata in the dependant classes.

    Comment by Nikos — August 11, 2010 @ 7:26 pm | Reply

  5. I’m kind of late to this party, but someone posted a link to a RobotLegs Roundup (http://knowledge.robotlegs.org/discussions/examples/6-links-to-robotlegs-resources-examples-tutorials) today, and I spotted your article.

    While much of your information is useful, I would suggest that readers who might be persuaded by your ringing endorsement of Singleton pattern read this first http://www.as3dp.com/2008/11/26/we-don%e2%80%99t-need-no-stinkin%e2%80%99-singletons-why-to-avoid-the-singleton-pattern-in-actionscript-30-programming/. Core to the concept of the Singleton (with a capital S) is the idea that the Singleton can be referenced from any Class at any time, by using a static getInstance() method.

    Use of Singleton is strongly discouraged in Robotlegs, which provides other means to accomplish the goal of one instance (mapSingleton, mapSingletonOf, mapValue). Though two of these have “singleton” in the name, they do not create global variable style singletons. They produce what are refered to as “small s singletons,” single instances managed by the Context. Easy access to these instances is provided by the automated dependency injection, which will provide the one instance to any instance managed by Robotlegs that uses [Inject] metadata to request them. Those managed instances don’t need to know whether the injector is injecting the same instance over and over, or a new instance every time (which is what happens with mapClass).

    Comment by Amy Blankenship — May 25, 2011 @ 5:40 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: