Robotlegs v2 and context

andreas's Avatar

andreas

05 Feb, 2013 10:17 PM

Hi,

I am searching a good tutorial or documentation for someone who is switching from robotlegs 1 to 2.
The tutorials that I have found in this forum are mostly about 1 year old and I think there has been some progress in this last year.
A am also very unsure about the structure of v2 and have some questions:
1) Do I not need a Context anymore?
2) How and when do I use Bundles?
3) How do I find out which Bundle to use or what I need when I want to write my own bundle?

  1. Support Staff 1 Posted by Shaun Smith on 05 Feb, 2013 11:16 PM

    Shaun Smith's Avatar

    Hello Andreas,

    Have you had a look through the readme files on GitHub? They should be enough to get started. For example:

    https://github.com/robotlegs/robotlegs-framework
    https://github.com/robotlegs/robotlegs-framework/tree/master/src

    Just navigate around the source tree on GitHub and you should find readme files in pretty much every package.

    Hope that helps.

  2. 2 Posted by andreas on 05 Feb, 2013 11:45 PM

    andreas's Avatar

    Yes, but these pages did raise my questions:
    The site about Bundles does not explain enough when I have to use which Bundle and when I have to create my own.
    https://github.com/robotlegs/robotlegs-framework/tree/master/src/ro...

    What I miss is a guide or some sort of explanation how these classes and packages should work together. That is why I am confused about the role of the context in v 2.
    https://github.com/robotlegs/robotlegs-framework/tree/master/src/ro... tells something about the context, but does not answer the question how I have to use the context.

    Also I found some slides online that described some of the new features in robotlegs 2, that showed it will be much simpler to set up robotlegs, becauseyou do not need to write so much code for your context.
    http://www.slideshare.net/justinjmoses/introduction-to-robotlegs-2
    but there is not much explanation, either.

  3. Support Staff 3 Posted by Ondina D.F. on 07 Feb, 2013 09:58 AM

    Ondina D.F.'s Avatar

    Hi Andreas,

    The site about Bundles does not explain enough when I have to use which Bundle and when I have to create my own.

    So, let’s take a look at the MVCSBundle (https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...)

    In the following example, a new Context is created, and several extensions installed. I’ve listed all the extensions that are part of the MVCSBundle. I could have used context.install(MVCSBundle); instead of the long list.
    There is just a RootDisplayObject mapped to a RootMediator;

    Root display object, RootView

    private var robotlegsConfig:RobotlegsConfig;
    
    protected function preinitializeHandler(event:FlexEvent):void
    {
    robotlegsConfig = new RobotlegsConfig(this);
    }
    

    RootMediator

    public class RootMediator extends Mediator
    {
    [Inject]
    public var view:RootView;
    
    override public function initialize():void
    {
    addViewListener(SomeEvent.SOME_TYPE, onSomeViewEvent, SomeEvent);
    }
    }
    

    RobotlegsConfig

    public function RobotlegsConfig(rootDisplayObject:DisplayObjectContainer)
    {
    _contextView = new ContextView(rootDisplayObject);
    
    context = new Context();
    
    ((the extensions contained in the MVCSBundle::
    context.install(
    TraceLoggingExtension,
    VigilanceExtension,
    InjectableLoggerExtension,
    ContextViewExtension,
    EventDispatcherExtension,
    ModularityExtension,
    CommandCenterExtension,
    EventCommandMapExtension,
    LocalEventMapExtension,
    ViewManagerExtension,
    StageObserverExtension,
    ManualStageObserverExtension,
    MediatorMapExtension,
    StageSyncExtension);
    
    context.configure(_contextView);
    context.afterInitializing(init);
    
    injector = context.injector;
    mediatorMap = injector.getInstance(IMediatorMap);
    eventDispatcher = injector.getInstance(IEventDispatcher);
    
    mediatorMap.map(RootDisplayObject).toMediator(RootMediator);
    
    }
    
    private function init():void
    {
    mediatorMap.mediate(_contextView.view);
    }
    

    Now, let’s create our own bundle with a minimum of extensions needed for mediating the root display object.

    SomeSimpleBundle will look like this:

    public class SomeSimpleBundle implements IBundle
    {
    
    public class SomeSimpleBundle  implements IBundle
    {       
        public function extend(context:IContext):void
        {
                context.install(                
                    ContextViewExtension,
                    
                    EventDispatcherExtension,                   
                    LocalEventMapExtension,
                    
                    ViewManagerExtension,
                    StageObserverExtension,                 
                    StageSyncExtension,
    
                    MediatorMapExtension                
            );          
            context.configure(ContextViewListenerConfig);
         }  
    }
    

    Now, our RobotlegsConfig would look like this:

    public function RobotlegsConfig(rootDisplayObject:DisplayObjectContainer)
    {
    _contextView = new ContextView(rootDisplayObject);
    
    context = new Context();
    
    context.install(SomeSimpleBundle);
    
    context.configure(_contextView);
    context.afterInitializing(init);
    
    injector = context.injector;
    mediatorMap = injector.getInstance(IMediatorMap);
    eventDispatcher = injector.getInstance(IEventDispatcher);
    
    mediatorMap.map(RootDisplayObject).toMediator(RootMediator);
    }
    
    private function init():void
    {
    mediatorMap.mediate(_contextView.view);
    }
    

    If I needed commands too, I’d have to add
    EventCommandMapExtension and CommandCenterExtension to the SomeSimpleBundle

    And in RobotlegsConfig:
    commandMap = injector.getInstance(IEventCommandMap);
    commandMap.map(SomeEvent.SOME_TYPE, SomeEvent).toCommand(SomeCommand);

    The simple bundle (from the docs on github https://github.com/robotlegs/robotlegs-framework/tree/master/src/ro...):

    Depending on your needs, you can add more extensions to your custom bundle.
    In your robotlegs config, you could use the MVCSBundle or your own custom bundle, or like in my first code snippet a list of extensions:

    context.install(MVCSBundle);

    or
    context.install(SomeSimpleBundle);

    or
    context.install(SomeSimpleBundle,EventCommandMapExtension,
    CommandCenterExtension);

    or
    context.install(MVCSBundle, ScopedEventDispatcherExtension, ViewProcessorMapExtension);

    or
    context.install(
    ContextViewExtension, EventDispatcherExtension,
    LocalEventMapExtension, ViewManagerExtension, StageSyncExtension, MediatorMapExtension );

    About the role of the context: https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...

    There are readme files for almost all extensions or framework classes on github. I don’t know if you’ve already seen all of them.
    If not, go through all the folders… I know, I know, it’s not the same as reading a tutorial, but for the time being you’ll have to live with what is there.
    Don’t hesitate to ask more questions :)

    Ondina

  4. 4 Posted by andreas on 07 Feb, 2013 05:45 PM

    andreas's Avatar

    Thank you, that helped a lot, but I am still learning and not done reading.
    Also I start creating my own little robotlegs2-project and play a bit with the code.
    For now it is just a mediated button, but I want to implement something like a stopwatch in robotlegs v2 (to have an example for the whole MVCS-system: the clock as model, that started on a command and gets updated by a service)

    "Don’t hesitate to ask more questions :)" I will ;-) :
    1) What happened to the "Model"-class? I've seen some people have implemented their own BaseActor, but what is best practice now?
    (this one is vital for my clock-example)

    2) in your code you call

    context.afterInitializing(init);
    
    that init function calls mediatorMap.mediate(_contextView.view);... but why? wont it be enough to map the mediator to the rood display using mediatorMap.map(...) ?
  5. Support Staff 5 Posted by Ondina D.F. on 08 Feb, 2013 10:06 AM

    Ondina D.F.'s Avatar

    Hey Andreas,

    What happened to the "Model"-class?

    Gone.

    I've seen some people have implemented their own BaseActor, but what is best practice now?

    All you need is a shared event dispatcher.
    Either a BaseActor or any class that has a shared event dispatcher injected into it can be used as a Model or a Service. The MVCS best practices are still the same: Models and Services should only dispatch events and not listen to any, but, as always, it’s up to you, how you design your app :)

    in your code you call

    context.afterInitializing(init);
    
    that init function calls mediatorMap.mediate(_contextView.view);... but why? wont it be enough to map the mediator to the rood display using mediatorMap.map(...) ?

    That’s only necessary for the contextView, because it is already on stage when the configuration process is starting,

    It has to do with the lifecycle of the context (https://github.com/robotlegs/robotlegs-framework/blob/master/src/ro...)

    In debug mode, you can see the traces from rl’s LogManager.

    After initialization, all extensions have been installed, all the configurations run, and all the dependencies supplied. If you take a look at the extensions in the simple bundle from my previous post, you can see what’s needed to create and initialize a mediator and to provide the dependencies that it needs. It would take me too long now to mention all the classes involved in the process and to show the order of execution of their methods. Maybe at another time..

    But, keep in mind that context.afterInitializing means that the context is ready, mappings are done, dependencies are supplied, and everything in your app is ready to be used as desired.
    As an exercise, you can call mediatorMap.mediate(_contextView.view); immediately after mediatorMap.map() and look at the traces from the logger and compare them to the ones produced when you call it after initializing the context. Also, remove some extensions from the bundle and see how the injector will complain about the missing parts.

    Note: You also need mediatorMap.mediate() for any other situations where auto mediation is not possible or desired.

    Does this help a little?

    Ondina

  6. Support Staff 6 Posted by Shaun Smith on 08 Feb, 2013 08:55 PM

    Shaun Smith's Avatar

    @Ondina - > That’s only necessary for the contextView, because it is already on stage when the configuration process is starting,

    That's not the case any more. The StageCrawler takes care of traversing existing views when the context initializes.

  7. 7 Posted by andreas on 09 Feb, 2013 12:40 AM

    andreas's Avatar

    Thank you, Ondina, that helped a lot.
    So for a Model to work all I need is to use an eventdispatcher, fine!

    I just created a small example on my github-account which shows the full MVCS-functionality (and explains it with the Class Diagram at http://www.robotlegs.org/diagram/):
    https://github.com/brean/robotlegs2-clock-example .

  8. Support Staff 8 Posted by Ondina D.F. on 09 Feb, 2013 01:09 PM

    Ondina D.F.'s Avatar

    @Shaun Thanks! I pasted the code from an older app, that was using an older rl version and I completely forgot about the StageCrawler. Of course there is no need for a mediatorMap.mediate() anymore for the root display object:)

    @Andreas

    You’re welcome :) I’ll take a look at your code. I’ll add it to our rl2 list of examples.

    Ondina

  9. Ondina D.F. closed this discussion on 09 Feb, 2013 05:51 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac