Initialization Sequence

mbarjawi's Avatar

mbarjawi

01 Oct, 2012 05:37 AM

Examining the Robotlegs 2 Examples List, we can see that multiple initialization sequences are being followed by developers. I never thought about any of them being correct or not... until I tried to create a simple project in which initialization failed.

I have created the RL2ModularCommuncations example. Then I tried to create a similar example to test communication with Sub-Modules... I used the same initialization process in the aforementioned project... but it failed. I started looking around for solutions and examining the RL2 examples list to see how other developers have initialized their applications. I failed again... until I found out that I was failing because of race-condition. Then I learned that the context lifecycle initialization process actually starts once the context.configure( contextView ) is called.

I used to call this function along with the creation of the context itself like this:

context = new Context()
    .extend( MVCSBundle )
    .extend( OtherExtentions )
    .configure( contextView );

then I would do other stuff like listening for the context.lifecycle.afterInitializing callback to be called. But it never gets called. Especially if the afterInitializing callback is being set in the creationComplete of the main Application.

So my solution was to separate the call for the configure function in a separate public function that gets called after all the callbacks are set on the lifecycle object. It works. But not sure if this is the best way.

Examining the examples list, I find the following initializing processes:

1- Extending the IContextConfig: This can be seen in the Simple-Project-with-Popup project and the CafeTownsend project.

  • I haven't personally tried this method. It seems strange as I don't see the contextView being set anywhere... however, contextView being used inside the Config files.
  • I cannot see where the context.configure is being called. Not calling this function manually means that if I want to listen to any of the lifecycle callbacks I might fail because of race conditions.

2- Using MXML configuration:

  • Not sure when the context.configure is being called... so again, race-conditions might happen here.
  • Using mxml configuration prevents from extending things like .extend( new ScopedEventDispatcherExtension("global", "module") )

3- An AS3 configuration by initializing the config file in the preinitialize of the view:

  • I used this process in my example mentioned above. Using this process, I can manually control the creation of the context and the call to the context.configure function.

I haven't had time to examine all of the projects... so maybe there are other ways of doing this.

Its getting late overhere, so I'll wrap up quickly.

Basically, my question is which method is a solid method that wouldn't fail because of race conditions and allows for listening for lifecycle callbacks?

Is the process that I used in the end (having a separate public function in my config file that calls the context.configure()) a good one?

Thanks for taking the time to read this :) and sorry if my English language has failed me to deliver my question in a proper way... I am not a native English language speaker :p

  1. 1 Posted by Michal Wroblews... on 01 Oct, 2012 07:45 AM

    Michal Wroblewski's Avatar

    Hi Mutasem,

    Your way of setting up Context is perfectly fine:
    1. Add extensions and configurations
    2. Add listener to after initialization
    3. Configure contextView
    I also use the same steps and that works great.

    The main thing that auto kicks off the initialization process when contextView lands on stage (or is already added) is StageSyncExtension. It listens when instance of DisplayObjectContainer is configured in context.

    OK, so let's quickly go through points you mentioned here.

    [1] When using ContextBuilderTag it iterates over all values declared in that view and uses extend for Extensions and configure for other objects. After that contextView (class where ContextBuilderTag is used) is configured to the context instance. ContextBuilderTag is used here. When contextView is configured then AppConfig extensions is calls handleContextView (it listens when DisplayObject is configured).

    [2] I described when context.configure(contextView) is called in the first point. And you're right about constructing ScopedEventDispatcherExtension. There should be something like that:

    <rl2:ContextBuilderTag>
        <scopedEventDispatcher:ScopedEventDispatcherExtension>
            <scopedEventDispatcher:names>
                <String>global</String>
                <String>local</String>
            </scopedEventDispatcher:names>
        </scopedEventDispatcher:ScopedEventDispatcherExtension>
    </rl2:ContextBuilderTag>
    

    [3] Not sure about this one. I think you created Context, added extensions, added listener for preinitialize that configures the context, and then configure(contextView) that kicks off the initialization process. Anyway if it launches correctly it's fine.

    Hope that helps a bit, making initialization process clearer.

    Cheers,
    Michał

  2. 2 Posted by mbarjawi on 01 Oct, 2012 02:20 PM

    mbarjawi's Avatar

    Hi Michal,

    Thank you for helping me understand the initializing process.

    • I just noticed the following statement:

        _contextView ||= document as DisplayObjectContainer;
      

      inside the ContextBuilderTag, which explains how the _contextView is being set even though no contextView="{this}" is being set on the ContextBuilder's mxml tag.

    Things are more clear now that I understand how the ContextBuilderTag works.

    The other question that comes to my mind, is that why sometimes we need to manually .mediate() a view... I understand the we do it manually because the view is already on stage before the _mediatorMap.map().toMediator() is called. However, this is exactly what I don't understand.

    For example, if you take a look at the config file here, I had to manually mediate the _contextView or else things won't work. What doesn't make sense to me is that the configureMediators() method is being called during the preinitialize phase of the _contextViews's lifecycle... which (I think) means that this is before the _contextView is added to stage. And since the mediation (I also think) happens when views are added to stage, there shouldn't be a problem in automatically mediating the _contextView. So the question remains: why do I have to manually mediate it?

    Thanks for your help,

  3. 3 Posted by Michal Wroblews... on 01 Oct, 2012 02:27 PM

    Michal Wroblewski's Avatar

    You need to manually mediate() only when view is already on stage or auto-mediation is not used. When on preinitialize contextView is already on stage because contextView ADDED_TO_STAGE event caused initialization process.

  4. 4 Posted by mbarjawi on 01 Oct, 2012 03:38 PM

    mbarjawi's Avatar

    Thanks again for putting the time to answer my questions.

    or auto-mediation is not used.

    How can auto mediation be not used? is there a flag for it or something?

    • Is there a way to finish configuring the application BEFORE the contextView is added to stage? (so that it gets automatically mediated by the rules set during configuration)

    • Is there also a way to finish configuring the application BEOFRE the contents of the contextView are added to stage? or do we always have to manually use addElement to ensure that contextView's elements are added after all mediation rules are set?

  5. 5 Posted by Michal Wroblews... on 01 Oct, 2012 06:58 PM

    Michal Wroblewski's Avatar

    auto-mediation is when using StageObserverExtension - mediators are assigned when view is added to contextView tree.
    manual-mediation is when using ManualStageObserverExtension - your view needs to dispatch special event requesting mediation.
    MVCSBundle uses auto-mediation

    And about your questions:

    • Don't mediate your main swf class but a child that is added there. Like in the first example you provided Only MainView is mediated - not Robotlegs2Example class.

    • Don't create and add subviews in constructor of your MainView. You can use some kind of a navigator (with state machine) that start on afterInitialization when context is configured.

  6. 6 Posted by mbarjawi on 02 Oct, 2012 04:10 AM

    mbarjawi's Avatar

    Ahh... finally I was able to understand those two classes. There is no comments on those classes and I wasn't able to figure them all by myself.. :) thanks!

    Don't mediate your main swf class but a child that is added there.

    Thanks for the idea... it seems a better approach.. I will start using it.

    Don't create and add subviews in constructor of your MainView. You can use some kind of a navigator (with state machine) that start on afterInitialization when context is configured.

    Not sure I understand your point. Do you mean that I create for example a ViewStack object. and leave index=0 with empty Group for example, and put the rest of my views in the index >= 1 ?

    I guess I don't understand what you mean by "navigator". If you can support with example it would help me better understand.

    Thanks,

  7. 7 Posted by Michal Wroblews... on 02 Oct, 2012 07:29 AM

    Michal Wroblewski's Avatar

    The simplest would be something like that. Implementation of that class has contextView injected and adds and manages views added to contexView. Any command or else can call methods to navigate to a certain view. You kick off with empty contextView and on startup you call to add first view. For more complex navigation you can use any state machine like one here (more functional that visual but serves well) or here visually oriented. First one has extension for Robotlegs2.
    Empty ViewStack would also work of course.

  8. 8 Posted by mbarjawi on 02 Oct, 2012 02:56 PM

    mbarjawi's Avatar

    Wow... this whole navigators and state machines are new to me. It will take me a little while to read those links and examine with them.

    Thanks a lot for your help Michal.

    I think I am good now in terms of how to initialize my application (the simple way)... I'll be back if I have more questions about the state machines.

  9. mbarjawi closed this discussion on 02 Oct, 2012 02:56 PM.

  10. mbarjawi re-opened this discussion on 04 Oct, 2012 04:32 AM

  11. 9 Posted by mbarjawi on 04 Oct, 2012 04:32 AM

    mbarjawi's Avatar

    I have read those links. I think it should be very useful to use the state machines. However, one thing that I am having difficulty with is: how to figure out the states in my application?

    I attempted to layout states in my application (a project I am working on right now)... but found that it is difficult to do so. I don't have a clear understanding of what exactly a state is.

    For example, here are some states that I came up with: (in no certain order)

    • LOADING (the application module)
    • INITIALIZING (inititalizing rl2 and any other initializations)
    • EXPLORING STUDY PLAN (when the user is exploring their study plan, adding, deleting, modifying..etc.)
    • EXPLORING AVAILABLE COURSES (self descriptive)
    • PRINTING (the study plan)

    Not sure if these are any close to be good ones... and not sure how the transitions would be between them... maybe that is why I feel that they are not good states.

    Finally, About the IMyViewNavigator that you posted, how is that supposed to be used. I mean for my application I have lots of dialogs to popup and lots of things to add to screen. The ones that are already done, they all get loaded/added in commands or the views themselves after receiving signals from the mediators. So is it in addition to those commands, I still need to add this navigation system?

    I guess, my question would be what is the value of having a navigation class instead of just using commands to navigate around?

  12. 10 Posted by Michal Wroblews... on 04 Oct, 2012 07:37 AM

    Michal Wroblewski's Avatar

    Let's start from the end. IMyViewNavigator should contain all loading, adding, fading logic. You shouldn't do it in Commands as it may introduce duplication code, unless it's just calling PopUpManager to open popup class. Commands should be short in code just giving commands to execute by other tiers (like to view navigator here). Not sure what exactly code you have in your Commands but you should get the point.

    And now about the states. Your states should be good for your app. You can define processes for those states like: NEXT, BACK, EXPLORE_STUDY_PLAN, EXPLORE_AVAILABLE_COURSES, PRINT and using those processes connect your states (define available routes). Having NEXT and BACK processes is nice because your view doesn't need to know anything about previous and next states, just about a direction. Here is a nice description of using of neil's state machine with more insight into the concept https://gist.github.com/1277913 and http://statemachine.org/?p=219 . Another good point is that state machine doesn't need to be only view oriented, so you can have nested functional state machine for a complex loading process etc.

  13. 11 Posted by mbarjawi on 12 Oct, 2012 06:05 PM

    mbarjawi's Avatar

    Thanks Michal for your answer.
    I looked more into these states and I actually liked the concept and used the TryHarderStateMachine in a small project.

    However, I still feel it is a little bit confusing. I think my main confusion point is again understanding states. Its easy for me to comprehend states like (Initialized, GameStarted, GamePaused, GameEnded, Destroying...etc.)... but its really difficult to understand in a normal application where you just have screens that allows the user to interact with them. USER_DIALOG_SHOWN is not a state, even though that is what the user is currently doing, i.e., looking/interacting the the user dialog. However, it gets more complicated when you have two states that need to happen at the same time USER_DIALOG_SHOWN and USERS_LIST_SHOWN or whatever other thing to show at the same time as the user dialog.

    In the first states examples, it is very clear that you can be at a single state at a single time... but in the second its not.

    If I want to create states for a normal application I would name them (Initialized, AppStarted, AppDestroyed)... thats it... but maybe thats because of my lack of understanding. Do you know any complete examples (not only code snippits) that shows states in action for a normal application like the users example I have been using?

    Thanks,

  14. 12 Posted by Michal Wroblews... on 12 Oct, 2012 08:39 PM

    Michal Wroblewski's Avatar

    This presentation helped me alot figuring out. It talks about AS3-Navigator (doesn't have Robotlegs 2 extension) And it supports multiple states. There you can have /userDialog and /usersList states that stack on them into something like this: /userView/userDialog/usersList. Not really sure if that's a good approach putting that detail into states but just showing how it would look like.

    Mike

  15. Support Staff 13 Posted by Ondina D.F. on 17 Oct, 2012 12:30 PM

    Ondina D.F.'s Avatar

    @Mutasem I think, Michal has answered all your questions. So, I’m going to close this thread, but as you know, you can re-open it, if need be.

  16. Ondina D.F. closed this discussion on 17 Oct, 2012 12:30 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