Understanding the flow of automatically mediated views via ADDED_TO_STAGE

tacklemcclean's Avatar

tacklemcclean

19 Aug, 2010 08:18 AM

What does the flow look like in the following scenario:

I have a "mainScene" view added to contextView in my StartupCommand, and it is mediated with my MainSceneMediator. In the onRegister function of this mediator I simply create a new view component of type TestView and add with addChild to the mainScene view.

In my Context I have mapped both the MainScene view with the MainSceneMediator, and the TestView with a TestViewMediator.

This is where the magic happens which I don't understand. When adding the testView to mainScene, testView automatically gets its mediator just like mainScene. I suppose there's no difference in how it works between the two views/mediators, but I found it less magical when the mainScene was added directly to the contextView.

What does the flow look like? What is listening to ADDED_TO_STAGE on my testView, and how is that event bubbled up without specifically being told to do so?

  1. 1 Posted by Nikos on 19 Aug, 2010 10:39 AM

    Nikos 's Avatar

    when MainSceneMediator adds TestView its ADDED_TO_STAGE gets bubbled up to the context and then handled via the injector.

    not sure what you mean by
    but I found it less magical when the mainScene was added directly to the contextView.

  2. 2 Posted by tacklemcclean on 19 Aug, 2010 11:17 AM

    tacklemcclean's Avatar

    Ok so basically any of the RobotLegs set of actors (Mediators, Commands, Contexts) specifically chooses to bubble the ADDED_TO_STAGE events?

  3. 3 Posted by Nikos on 19 Aug, 2010 11:25 AM

    Nikos 's Avatar

    the ADDED_TO_STAGE has the bubble propery set to true, you would have to override the class to prevent this

  4. Support Staff 4 Posted by Shaun Smith on 19 Aug, 2010 11:51 AM

    Shaun Smith's Avatar

    @tacklemcclean: I think you are misunderstanding how auto-mediation works in Robotlegs. It has nothing to do with Mediators, Commands or the Context, and everything to do with the MediatorMap. Check it out:

    http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org...

    The MediatorMap listens to the contextView for capture-phase, bubbling ADDED_TO_STAGE events. Every single DisplayObject that lands on stage (but inside the contextView) gets looked at to determine whether or not it has an associated Mediator mapping. If it does we create a mediator for it:

    http://github.com/robotlegs/robotlegs-framework/blob/v1.1.2/src/org...

    What this means is that you can add a deeply-nested DisplayObjectContainer to stage and that action might create any number of mediators - in other words automatic mediation creates mediators for display objects no matter where they land up, and no matter who adds them to the display list (so long as they land somewhere inside the contextView).

    The same thing is true for auto-removal: you might remove one display object from the screen and that action might remove any number of mediators.

    I'm not sure that I'm doing a good job of explaining this. Let me know if that makes sense.

  5. 5 Posted by tacklemcclean on 19 Aug, 2010 12:14 PM

    tacklemcclean's Avatar

    I have a hard time understanding the concept even when looking at the actual class.

    The ADDED_TO_STAGE Event has bubbles set to false by default according to AS3 reference, so I'm trying to figure out who what and where bubbles is set to true instead.

    Probably right around where you say "Every single DisplayObject that lands on stage gets looked at". Who looks at it? The MediatorMap? Or the current contextView?

  6. 6 Posted by Nikos on 19 Aug, 2010 12:40 PM

    Nikos 's Avatar

    the mediator map

    protected override function addListeners():void

        {
            if (contextView && enabled && _active)
            {
                contextView.addEventListener(Event.ADDED_TO_STAGE, onViewAdded, useCapture, 0, true);
                contextView.addEventListener(Event.REMOVED_FROM_STAGE, onViewRemoved, useCapture, 0, true);
            }
        }
  7. 7 Posted by Nikos on 19 Aug, 2010 12:51 PM

    Nikos 's Avatar

    the contextView wont listen to it by default, but if you mediate the contexView you can listen to any event from that view by using

    eventMap.mapListener

  8. Support Staff 8 Posted by Shaun Smith on 19 Aug, 2010 01:03 PM

    Shaun Smith's Avatar

    @nikos: that's not quite right.

    Ok cool, let's look at it again:

    contextView.addEventListener(Event.ADDED_TO_STAGE, onViewAdded, useCapture, 0, true);
    

    see L233

    The important thing here is the third parameter: useCapture which is set to true. Even though ADDED_TO_STAGE events do not bubble in the "bubbling phase" (as documented) they DO bubble in the "capture phase". As far as I know, this is the only place where that happens in the Flash Player. So, essentially, every display object that lands on stage, inside the contextView, will be processed by the onViewAdded() handler.

    Cool, let's look at that handler:

    protected override function onViewAdded(e:Event):void
    {
        if (mediatorsMarkedForRemoval[e.target])
        {
            delete mediatorsMarkedForRemoval[e.target];
            return;
        }
        var config:MappingConfig = mappingConfigByViewClassName[getQualifiedClassName(e.target)];
        if (config && config.autoCreate)
        {
            createMediator(e.target);
        }
    }
    

    see L253

    The first block of code deals with the re-parenting of view components and is not relevant to this discussion.

    This line is more important:

    var config:MappingConfig = mappingConfigByViewClassName[getQualifiedClassName(e.target)];
    

    e.target is the view component being processed. We grab its Class Name, and use that as a key to the mappingConfigByViewClassName dictionary.

    If the view component has been mapped for mediation (see: L116) the dictionary will give us back a config object.

    If we get a config object back, and the config specifies auto-mediation, we create a mediator for the view component:

    if (config && config.autoCreate)
    {
        createMediator(e.target);
    }
    

    see L261

    Easy-peesy-lemon-squeezy!

  9. 9 Posted by tacklemcclean on 19 Aug, 2010 01:12 PM

    tacklemcclean's Avatar

    Cool now I get it!
    It all bogged down to the useCapture thingie, so this was essentially me misunderstanding Flash itself rather than the RobotLegs architecture.

    I found this line interesting, quoting from the AS3 reference regarding useCapture in addEventListener:
    To listen for the event in all three phases, call addEventListener twice, once with useCapture set to true, then again with useCapture set to false.

    Thanks for all the great help guys, great community!

  10. 10 Posted by Nikos on 19 Aug, 2010 01:20 PM

    Nikos 's Avatar

    Thanks for all the great help guys, great community!

    yeah, welcome to the fun side

  11. 11 Posted by Nikos on 19 Aug, 2010 01:23 PM

    Nikos 's Avatar

    lol i quoted

    contextView.addEventListener(Event.ADDED_TO_STAGE, onViewAdded, useCapture, 0, true);

    and still got confused, and I'm supposed to be making screencasts on this :)

  12. tacklemcclean closed this discussion on 19 Aug, 2010 01:27 PM.

  13. Nikos re-opened this discussion on 20 Aug, 2010 08:54 AM

  14. 12 Posted by Nikos on 20 Aug, 2010 08:54 AM

    Nikos 's Avatar

    ah finally get it, I never knew about that capture phase until this morning :)

  15. 13 Posted by Nikos on 20 Aug, 2010 08:55 AM

    Nikos 's Avatar

    The capture phase basically allows you to control many children's event stuff from top levels

  16. Support Staff 14 Posted by Shaun Smith on 21 Aug, 2010 02:51 PM

    Shaun Smith's Avatar

    @Nikos: event handing is pretty important stuff when it comes to AS3, so make sure you understand how event propagation and the 3 phases work:

    http://www.adobe.com/devnet/actionscript/articles/event_handling_as...

  17. tacklemcclean closed this discussion on 23 Aug, 2010 07:18 AM.

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