Slide 1

Slide 1 text

2.0 robotlegs Thursday, 27 October 11

Slide 2

Slide 2 text

the goals Thursday, 27 October 11

Slide 3

Slide 3 text

because every project is unique configurable Thursday, 27 October 11

Slide 4

Slide 4 text

rigidity sucks versatile Thursday, 27 October 11

Slide 5

Slide 5 text

use only what you need concise Thursday, 27 October 11

Slide 6

Slide 6 text

make(tea).with(milk).butNot(sugar) fluent Thursday, 27 October 11

Slide 7

Slide 7 text

govt health warning robotlegs 2 is still in alpha these examples are subject to change Thursday, 27 October 11

Slide 8

Slide 8 text

the features Thursday, 27 October 11

Slide 9

Slide 9 text

.context builder Thursday, 27 October 11

Slide 10

Slide 10 text

public class Context { protected var _injector:IInjector; protected var _reflector:IReflector; protected var _contextView:DisplayObjectContainer; protected var _commandMap:ICommandMap; protected var _mediatorMap:IMediatorMap; protected var _viewMap:IViewMap; } Contexts in robotlegs circa v1 Thursday, 27 October 11

Slide 11

Slide 11 text

in version one, features were bound to the context. public class Container { private var youCantSeeMe:SoLetsHopeIKnowWhatImDoing; protected var sureYouCanOverrideMe:ButYouAintGettingRidOfMe; } Thursday, 27 October 11

Slide 12

Slide 12 text

not extended with what you don’t RL2 contexts are created with what you need Thursday, 27 October 11

Slide 13

Slide 13 text

public interface IContextBuilder { build():IContext; withBundle(bundle:IContextBuilderBundle):IContextBuilder; withConfig(config:IContextConfig):IContextBuilder; withContextView(value:DisplayObjectContainer):IContextBuilder; withDispatcher(value:IEventDispatcher):IContextBuilder; withExtension(extension:IContextExtension):IContextBuilder; withInjector(value:Injector):IContextBuilder; withParent(value:IContext):IContextBuilder; withProcessor(processor:IContextProcessor):IContextBuilder; } Introducing the context builder Thursday, 27 October 11

Slide 14

Slide 14 text

setup your configuration to execute once at build. public interface IContextConfig { function configure(context:IContext):void; } .withConfig Thursday, 27 October 11

Slide 15

Slide 15 text

public interface IContextExtension { function initialize(context:IContext):void; function install(context:IContext):void; function uninstall(context:IContext):void; } .withExtension extensions add functionality at any time. Thursday, 27 October 11

Slide 16

Slide 16 text

.withProcessor public interface IContextProcessor { function process(context:IContext, callback:Function):void; } processors asynchronously affect the build state. Thursday, 27 October 11

Slide 17

Slide 17 text

.pre-configured bundles Thursday, 27 October 11

Slide 18

Slide 18 text

each representing a context builder bundle four tasty flavours of robotlegs Thursday, 27 October 11

Slide 19

Slide 19 text

»when plain old vanilla is just right. Original Thursday, 27 October 11

Slide 20

Slide 20 text

l i g h t »when size and performance are paramount. Thursday, 27 October 11

Slide 21

Slide 21 text

»when time is of the essence. rapid Thursday, 27 October 11

Slide 22

Slide 22 text

smart views » when you simply can’t live without view injection. Thursday, 27 October 11

Slide 23

Slide 23 text

.type matching Thursday, 27 October 11

Slide 24

Slide 24 text

flexible and fluent type matching syntax public class TypeMatcher { function anyOf(... params):TypeMatcher; function noneOf(... params):TypeMatcher; function allOf(... params):TypeMatcher; } new TypeMatcher() .allOf(ISpaceShip, IEnemy) .noneOf(DeathStar) Usage Definion Thursday, 27 October 11

Slide 25

Slide 25 text

.view management Thursday, 27 October 11

Slide 26

Slide 26 text

wire view handlers to view watchers viewManager.addContainer(contextView); viewManager.addHandler(mediatorMap); viewManager.addWatcher(stageWatcher); viewManager.addContainer(myPopUp); viewManager.addContainer(myPopUp); native support for flex popups and air windows. Thursday, 27 October 11

Slide 27

Slide 27 text

.mediate anything Thursday, 27 October 11

Slide 28

Slide 28 text

map mediators to interfaces rather than concrete classes. mediatorMap.map(UserDetailsMediator).toView(IUserDetailsAware); use type-matching to refine your mapping mediatorMap .map(SomeMenuMediator) .toMatcher() .anyOf(TopLevelMenu, AdminMenu, FootMenu); Thursday, 27 October 11

Slide 29

Slide 29 text

.guards and hooks Thursday, 27 October 11

Slide 30

Slide 30 text

a guard exposes conditional logic for an action to occur possible use-cases for a guard: • prevent mediation when ... • prevent command execution when ... mediatorMap .map(UserDetailsMediator) .withGuard(UserIsAdminGuard) .toView(IUserDetailsAware); Thursday, 27 October 11

Slide 31

Slide 31 text

a hook enables pre-processing on an action. scenarios for using a hook: • customised logging • view skinning • view localisation • instance configuration prior to command execution commandMap .map(UserLoginCommand) .toEvent(UserLoginEvent.LOGIN, UserLoginEvent) .withHook(ConfigureUserDetails) Thursday, 27 October 11

Slide 32

Slide 32 text

.rule sets and command flow Thursday, 27 October 11

Slide 33

Slide 33 text

a rule can prevent or ensure an action occurring possible uses of a rule: • adding or removing mediators • loading or unloading commands Thursday, 27 October 11

Slide 34

Slide 34 text

flows are pathways between commands command flows: create a workflow of commands to represent a complex sequence Thursday, 27 October 11

Slide 35

Slide 35 text

.swift-suspenders integration Thursday, 27 October 11

Slide 36

Slide 36 text

full integration with swift suspenders 2 leverages the entire toolkit. //creates a new instance per injection injector.map(SomeType); //or injector.map(SomeType, ‘named’); //create new instance per injection and map to injector.map(IService).toType(SomeService); //or value .toValue(someInstance) //map as singleton instance injector.map(SomeService).asSingleton(); //or .toSingleton(SomeService); //allows to easily specify custom providers to use for a mapping injector.map(IService).toProvider(new CustomProvider()); //prevents sharing the mapping with child injectors; injector.map(SomeService).local(); // .shared() reverts it //allow child injector to map if none exists injector.map(SomeService).soft(); // .strong() maps regardless //prevents changes to the mapping; returns a unique key object injector.map(SomeService).seal(); //can revert with key and .unseal() Thursday, 27 October 11

Slide 37

Slide 37 text

.module integration Thursday, 27 October 11

Slide 38

Slide 38 text

in robotlegs 2, modules just work. integrated module automation: • context wired up by parent once added to stage • view events are collated in the one view manager • child injectors created and wired to the parent • default injections to ensure modules work both standalone and when integrated. Thursday, 27 October 11

Slide 39

Slide 39 text

.robotlegs inspector Thursday, 27 October 11

Slide 40

Slide 40 text

info here. new inspector gadget tool to help you with you robotlegging. Thursday, 27 October 11

Slide 41

Slide 41 text

an example in covariance mediate behaviours not views Thursday, 27 October 11

Slide 42

Slide 42 text

let’s look at a simple robotlegs v1 application for comparison Thursday, 27 October 11

Slide 43

Slide 43 text

one mediator per view. invariant mediation (via classes) View Mediator e v e n t s Thursday, 27 October 11

Slide 44

Slide 44 text

what’s wrong with this approach? • the mediator is tightly coupled to the view • view is restricted to one mediator • no reuse of mediation Thursday, 27 October 11

Slide 45

Slide 45 text

using the variance utility how to fix this in v1? Thursday, 27 October 11

Slide 46

Slide 46 text

Mediator C n mediators per view. covariant mediation (via interfaces) View Mediator A IBehaviour A IBehaviour B IBehaviour C Mediator B e v e n t s Thursday, 27 October 11

Slide 47

Slide 47 text

what is wrong with this contract? we have to extend IEventDispatcher and there’s no enforcement of contract. import flash.events.IEventDispatcher; [Event(name="doAsync", type="...ControlEvent")] public interface IServiceStarter extends IEventDispatcher { function serviceReturned():void; } Thursday, 27 October 11

Slide 48

Slide 48 text

.enter signals, stage right Thursday, 27 October 11

Slide 49

Slide 49 text

import org.osflash.signals.ISignal; public interface IServiceStarter { function serviceReturned():void; function get start():ISignal; } with signals, we define the contract import org.osflash.signals.ISignal; private var startSignal:ISignal = new Signal(); public function serviceReturned():void { Alert.show("The service returned.","Guess what?"); } public function get start():ISignal { return startSignal; } ... and force the view to comply Thursday, 27 October 11

Slide 50

Slide 50 text

Mediator C each view is mediated bidirectionally. with covariance and signals View Mediator A IBehaviour A IBehaviour B IBehaviour C Mediator B Thursday, 27 October 11

Slide 51

Slide 51 text

to view this sample online go to j.mp/covariance Libraries used: • robotlegs 1.5.2 • robotlegs variance utility 1.1 • as3-signals 0.9-beta Thursday, 27 October 11

Slide 52

Slide 52 text

so when is robotlegs 2 coming? Thursday, 27 October 11

Slide 53

Slide 53 text

...now. Thursday, 27 October 11

Slide 54

Slide 54 text

as of this afternoon robotlegs 2 is in open beta. Thursday, 27 October 11

Slide 55

Slide 55 text

Stay updated. Add you name to the RL2 beta list by commenting on: j.mp/robotlegs2 Join the robotlegs google group Follow @robotlegs_as3 on Twitter. Thursday, 27 October 11

Slide 56

Slide 56 text

fin. about.me/justinj @justinjmoses Thursday, 27 October 11