Robotlegs Workshop
                                       29 january 2011
                           Eric-Paul Lecluse & Erik van Nieuwburg


Monday, January 31, 2011
What is Robotlegs?
                • MVC framework
                • Looks a lot like pureMVC
                • Focused on wiring application tiers
                • Lightweight / small footprint
                • Based on ‘dependency injection’ via
                           SwiftSuspenders library


Monday, January 31, 2011
Dependency Injection?

                     • It’s the act of supplying objects with their
                           required data.
                     • Passing an argument to a constructor is an
                           example of dependency injection.
                     • Less boilerplate code
                     • Flexible adding of alternative
                           implementations of a given service.


Monday, January 31, 2011
Robotlegs + Dependency Injection
                   • Based on SwiftSuspenders (metadata driven
                           Inversion Of Control solution for AS3)
                   • Evolves around 2 meta tags: [Inject] and
                           [PostConstruct]
                   • If you don’t use the supplied SWC files ,
                           add these parameters to MXMLC:
                            • -keep-as3-metadata+=Inject
                            • -keep-as3-metadata+=PostConstruct
Monday, January 31, 2011
So what does a class look like?
               package com.rumblingskies.view
               {
                 import com.rumblingskies.model.ScoreModel;
                 import org.robotlegs.mvcs.Mediator;

                     public class BallMediator extends Mediator
                     {
                       [Inject]
                       public var scoreModel:ScoreModel;

                           override public function onRegister() : void
                           {
                           }
                     }
               }



Monday, January 31, 2011
But how to inject?	

                 Typically, during startup of your app, you define
                 injector rules. You can do that in 4 ways:

                  injector.mapValue(MyClass, myClassInstance);

                  injector.mapClass(MyClass, MyClass);

                  injector.mapSingleton(MyClass);

                  injector.mapSingletonOf(IMyClass, MyClass);




Monday, January 31, 2011
injector.mapValue
           (MyClass, myClassInstance);
     When asked for
                 a specific class,
                     use this specific instance of the class
                     for injection.




Monday, January 31, 2011
injector.mapClass
            (MyClass, MyClass);
     When asked for
                 a specific class,
                   create and inject a new instance
                                            of that class.




Monday, January 31, 2011
injector.mapSingleton(MyClass);

     When asked for
                 a specific class,
                 always provide the same instance
                                           of that class.

     No more writing Singleton logic :-)
     This is a managed single instance, enforced by the
     framework, and not a Singleton enforced within the
     class itself.
Monday, January 31, 2011
injector.mapSingletonOf
      	

 	

 	

 	

 (IMyClass, MyClass);
     When asked for
                 a specific class,
                 always provide the same instance
                         of the implementation that class.

     No more writing Singleton logic :-)
     This is a managed single instance, enforced by the
     framework, and not a Singleton enforced within the
     class itself.
Monday, January 31, 2011
Robotlegs Architecture
                 Built up in 4 tiers:
                 •Model
                 •View
                 •Controller
                 •Services
                 Services are models, but for communication with
                 the outside world. For instance loading an image
                 from Flickr.


Monday, January 31, 2011
Model

                 Contains / maintains your application’s data /
                 state

                 Extends ‘Actor’ class so it can dispatch events

                 Dumb objects: receive value changes and then
                 dispatch events. That’s it.



Monday, January 31, 2011
public class ScoreModel extends Actor
            {
              private var _score:Number;

                  public function ScoreModel()
                  {
                  }

                  public function get score() : Number
                  {
                    return _score;
                  }

                  public function set score(score : Number) : void
                  {
                    _score = score;
                    dispatch(new ScoreEvent(ScoreEvent.UPDATE));
                  }
            }

Monday, January 31, 2011
Model Instantiation

                 Typically, you inject Model instances.

                 So during system startup, define injector rules for
                 injection of Models:

                           injector.mapSingleton(ScoreModel);

                 This way your ScoreModel class is behaving as a
                 Singleton.

Monday, January 31, 2011
View

                 The visual elements of your app

                 To interact with the framework they have a
                 seperate Mediator class

                 Mediators listen to
                 • events travelling through the framework
                 • events sent by their view component


Monday, January 31, 2011
View instantiation
                 Again, during system startup you typically tell the
                 framework which views and mediators work
                 together.
                 mediatorMap.mapView( viewClass, mediatorClass, injectViewAs,
                 autoCreate, autoRemove );




                 By default, mediators are auto-created when a
                 view is ADDED_TO_STAGE!

                 It’s fully automated! Yeah.....i know.....it rocks :-)

Monday, January 31, 2011
public class Ball extends Sprite
       {
         public function Ball()
         {
           redraw();
         }

                 public function redraw() : void
                 {
                   graphics.clear();
                   graphics.beginFill(0xffffff *
                             Math.random());
                   graphics.drawCircle(0, 0, 25);
                 }
           }



Monday, January 31, 2011
public class BallMediator extends Mediator
      {
        [Inject]
        public var ballView : Ball;

               [Inject]
               public var stats:StatsModel;

        override public function onRegister() : void
        {
           addViewListener(MouseEvent.CLICK, handleViewClick);
           addContextListener(HelloRobotLegsEvent.BALL_CLICKED,
   handleBallClicked);
        }

        private function handleViewClick(e : MouseEvent) : void
        {
           stats.recordBallClick();
           dispatch(new HelloRobotLegsEvent
   (HelloRobotLegsEvent.BALL_CLICKED));
        }

               private function handleBallClicked(e : HelloRobotLegsEvent) : void
               {
                  ballView.redraw();
               }
         }

Monday, January 31, 2011
Commands
                 Are similar to pureMVC commands.

                 Run an execute() method

                 At system startup, map your Commands to
                 framework Events like this:
                       commandMap.mapEvent(MyAppDataEvent.DATA_WAS_RECEIVED,
                                        MyCoolCommand, MyAppDataEvent);



                 Robotlegs natively does not have a
                 MacroCommand like pureMVC.
Monday, January 31, 2011
public class CreateBallCommand extends Command
            {
              [Inject]
              public var event:HelloRobotLegsEvent;

                  override public function execute() : void
                  {
                    var ball : Ball = new Ball(event.ballName);
                    ball.x = Math.random() * 500;
                    ball.y = Math.random() * 400;
                    contextView.addChildAt(ball, 0);
                  }
            }




Monday, January 31, 2011
Quickstart Help
     Download ZIP file here:
     www.rumblingskies.com/files/robotlegs-workshop/pong.zip

     1) Subclass Context class and overwrite the startup() method
     2) Configure the injector
     3) fill mediatorMap
     4) fill commandMap
     5) add children to contextView
     6) start writing logic in Model, Mediator,View and Command
     classes.
Monday, January 31, 2011

Robotlegs Introduction

  • 1.
    Robotlegs Workshop 29 january 2011 Eric-Paul Lecluse & Erik van Nieuwburg Monday, January 31, 2011
  • 2.
    What is Robotlegs? • MVC framework • Looks a lot like pureMVC • Focused on wiring application tiers • Lightweight / small footprint • Based on ‘dependency injection’ via SwiftSuspenders library Monday, January 31, 2011
  • 3.
    Dependency Injection? • It’s the act of supplying objects with their required data. • Passing an argument to a constructor is an example of dependency injection. • Less boilerplate code • Flexible adding of alternative implementations of a given service. Monday, January 31, 2011
  • 4.
    Robotlegs + DependencyInjection • Based on SwiftSuspenders (metadata driven Inversion Of Control solution for AS3) • Evolves around 2 meta tags: [Inject] and [PostConstruct] • If you don’t use the supplied SWC files , add these parameters to MXMLC: • -keep-as3-metadata+=Inject • -keep-as3-metadata+=PostConstruct Monday, January 31, 2011
  • 5.
    So what doesa class look like? package com.rumblingskies.view { import com.rumblingskies.model.ScoreModel; import org.robotlegs.mvcs.Mediator; public class BallMediator extends Mediator { [Inject] public var scoreModel:ScoreModel; override public function onRegister() : void { } } } Monday, January 31, 2011
  • 6.
    But how toinject? Typically, during startup of your app, you define injector rules. You can do that in 4 ways: injector.mapValue(MyClass, myClassInstance); injector.mapClass(MyClass, MyClass); injector.mapSingleton(MyClass); injector.mapSingletonOf(IMyClass, MyClass); Monday, January 31, 2011
  • 7.
    injector.mapValue (MyClass, myClassInstance); When asked for a specific class, use this specific instance of the class for injection. Monday, January 31, 2011
  • 8.
    injector.mapClass (MyClass, MyClass); When asked for a specific class, create and inject a new instance of that class. Monday, January 31, 2011
  • 9.
    injector.mapSingleton(MyClass); When asked for a specific class, always provide the same instance of that class. No more writing Singleton logic :-) This is a managed single instance, enforced by the framework, and not a Singleton enforced within the class itself. Monday, January 31, 2011
  • 10.
    injector.mapSingletonOf (IMyClass, MyClass); When asked for a specific class, always provide the same instance of the implementation that class. No more writing Singleton logic :-) This is a managed single instance, enforced by the framework, and not a Singleton enforced within the class itself. Monday, January 31, 2011
  • 11.
    Robotlegs Architecture Built up in 4 tiers: •Model •View •Controller •Services Services are models, but for communication with the outside world. For instance loading an image from Flickr. Monday, January 31, 2011
  • 12.
    Model Contains / maintains your application’s data / state Extends ‘Actor’ class so it can dispatch events Dumb objects: receive value changes and then dispatch events. That’s it. Monday, January 31, 2011
  • 13.
    public class ScoreModelextends Actor { private var _score:Number; public function ScoreModel() { } public function get score() : Number { return _score; } public function set score(score : Number) : void { _score = score; dispatch(new ScoreEvent(ScoreEvent.UPDATE)); } } Monday, January 31, 2011
  • 14.
    Model Instantiation Typically, you inject Model instances. So during system startup, define injector rules for injection of Models: injector.mapSingleton(ScoreModel); This way your ScoreModel class is behaving as a Singleton. Monday, January 31, 2011
  • 15.
    View The visual elements of your app To interact with the framework they have a seperate Mediator class Mediators listen to • events travelling through the framework • events sent by their view component Monday, January 31, 2011
  • 16.
    View instantiation Again, during system startup you typically tell the framework which views and mediators work together. mediatorMap.mapView( viewClass, mediatorClass, injectViewAs, autoCreate, autoRemove ); By default, mediators are auto-created when a view is ADDED_TO_STAGE! It’s fully automated! Yeah.....i know.....it rocks :-) Monday, January 31, 2011
  • 17.
    public class Ballextends Sprite { public function Ball() { redraw(); } public function redraw() : void { graphics.clear(); graphics.beginFill(0xffffff * Math.random()); graphics.drawCircle(0, 0, 25); } } Monday, January 31, 2011
  • 18.
    public class BallMediatorextends Mediator { [Inject] public var ballView : Ball; [Inject] public var stats:StatsModel; override public function onRegister() : void { addViewListener(MouseEvent.CLICK, handleViewClick); addContextListener(HelloRobotLegsEvent.BALL_CLICKED, handleBallClicked); } private function handleViewClick(e : MouseEvent) : void { stats.recordBallClick(); dispatch(new HelloRobotLegsEvent (HelloRobotLegsEvent.BALL_CLICKED)); } private function handleBallClicked(e : HelloRobotLegsEvent) : void { ballView.redraw(); } } Monday, January 31, 2011
  • 19.
    Commands Are similar to pureMVC commands. Run an execute() method At system startup, map your Commands to framework Events like this: commandMap.mapEvent(MyAppDataEvent.DATA_WAS_RECEIVED, MyCoolCommand, MyAppDataEvent); Robotlegs natively does not have a MacroCommand like pureMVC. Monday, January 31, 2011
  • 20.
    public class CreateBallCommandextends Command { [Inject] public var event:HelloRobotLegsEvent; override public function execute() : void { var ball : Ball = new Ball(event.ballName); ball.x = Math.random() * 500; ball.y = Math.random() * 400; contextView.addChildAt(ball, 0); } } Monday, January 31, 2011
  • 21.
    Quickstart Help Download ZIP file here: www.rumblingskies.com/files/robotlegs-workshop/pong.zip 1) Subclass Context class and overwrite the startup() method 2) Configure the injector 3) fill mediatorMap 4) fill commandMap 5) add children to contextView 6) start writing logic in Model, Mediator,View and Command classes. Monday, January 31, 2011