Passing Data into Robotlegs Context

Tay511's Avatar

Tay511

17 Sep, 2010 11:12 AM

I have read a few posts around this subject but find a clear solution to my problem.

I have a RL video play which handles all video functionality and UI, and will be use in other RL and non RL projects. I'm trying to pass data into the RL framework context so it's available to the model after the ContextEvent.STARTUP_COMPLETE event is received by the relevant command.

I'm trying to make the code to use the video player is a simple one liner: var videoPlayer:RL_VideoPlayer = new RL_VideoPlayer({a:1, b:2, etc..}); with the video player constructor looking something like this:

protected var context:ApplicationContext;

public function RL_VideoPlayer(videoVars:Object)
{
// Create an instance of the ApplicationContext 
context = new ApplicationContext(this, videoVars);
}

I'm not sure if this approach is good, bad or indifferent but hopefully someone can suggest a good way of doing this.

Thanks.

  1. Support Staff 1 Posted by Shaun Smith on 17 Sep, 2010 11:18 AM

    Shaun Smith's Avatar

    Looks good to me!

  2. 2 Posted by Tay511 on 17 Sep, 2010 04:40 PM

    Tay511's Avatar

    Thanks Shaun.

    OK, got a solution to my problem. May be helpful to others so here's how.

    Here's the code I've added to what's in my original post.

    My context looks like this:

    public static var videoVars:Object;
    
    public function ApplicationContext(contextView:DisplayObjectContainer, vars:Object)
        {
            videoVars = vars;
            super(contextView);
        }
    
    override public function startup():void
    {
        commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, InitPlayerCommand, ContextEvent, true);
        // Other Context Mapping
        super.startup();
    }

    The InitPlayerCommand looks like this:

    [Inject]
    public var model:ApplicationModel;
    
    override public function execute():void
    {
        model.initModel(ApplicationContext.videoVars);
    }

    And in the model..

    public var videoVars:Object;
    
    public function initModel(vars:Object):void
    {
        videoVars = vars;
        trace(vars.a);
    }

    The data object that I send into my RL_VideoPlayer is now in the framework model.

  3. Support Staff 3 Posted by Shaun Smith on 17 Sep, 2010 05:32 PM

    Shaun Smith's Avatar

    Nooooooo! Statics are globals, and globals are bad :) Now you can only have one video player component in the Flash Player at a time (because all instances of your player will use the same static ApplicationContext.videoVars reference).

    You should never use statics to pass object references around (that's the opposite of Dependency Injection). Statics are good for Constant definitions, but otherwise should be avoided in Object Oriented systems :)

    Instead of the static, just store a normal reference in your constructor, and map it for injection in startup():

    // No statics pls! Keep it OO yo! 
    private var videoVars:Object;
    
    public function ApplicationContext(contextView:DisplayObjectContainer, vars:Object)
    {
        videoVars = vars;
        super(contextView);
    }
    
    override public function startup():void
    {
        commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, InitPlayerCommand, ContextEvent, true);
        // Map the videoVars object for named injection
        injector.mapValue(Object, videoVars, "VideoConfig");
        super.startup();
    }
    

    Note: We have to use Named Injection here because we are mapping a plain old Object (instead of a more specific class).

    And then in your model you'd just declare a normal dependency:

    [Inject(name="VideoConfig")]
    public var videoVars:Object;
    

    It might be a good idea to create a proper class for the config object (in which case you won't need to use named injection - also, users of your Video Player will be able to see what options they can pass in):

    // Keep it strongly-typed yo!
    private var config:VideoPlayerConfig;
    
    // Also, ApplicationContext is very generic - VideoPlayerContext might be better
    public function VideoPlayerContext(contextView:DisplayObjectContainer, config:VideoPlayerConfig)
    {
        this.config = config;
        super(contextView);
    }
    
    override public function startup():void
    {
        commandMap.mapEvent(ContextEvent.STARTUP_COMPLETE, InitPlayerCommand, ContextEvent, true);
        // Map it - no need for a "name" any more:
        injector.mapValue(VideoPlayerConfig, config);
        super.startup();
    }
    

    And then in your model:

    [Inject]
    public var config:VideoPlayerConfig;
    

    If you need to know when injection has been performed on your model you can mark any public method with [PostConstruct]:

    [Inject]
    public var config:VideoPlayerConfig;
    
    [PostConstruct]
    public function init():void
    {
        trace(config);
    }
    

    Hope that helps! Let me know if you need any more info :)

  4. 4 Posted by Tay511 on 20 Sep, 2010 02:46 PM

    Tay511's Avatar

    Thanks Shaun - your explanation was also very helpful too.

    Implemented the VideoPlayerConfig as an object and the Context name change. Makes perfect sense as the player will end up in other RL projects.

    Ty

  5. Stray closed this discussion on 10 Feb, 2011 05:48 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