Nope, haven't figured out. I don't think modular utilities is
something for me since I just load external SWFs in a new
ApplicationDomain (it's not modules in RL concept, but just
external RL-powered SWFs that should not be affected by shell's
injector). So it's seems more like SwiftSuspenders question
Support Staff6 Posted by Stray on 25 May, 2011 10:49 AM
well, you do have a multi-context app - and there are 3
solutions for that - one is the new modular utils, another is the
old modular utils, and the 3rd is to keep your contexts totally
separate - you've gone for the 3rd.
I'll see if Till has any more thoughts about it, but I don't see
a problem with what you're doing. The concept of 'contextView'
means 'the view used for this context' - not just 'main view'. So
it does have implications - which you've got a good work around
Stray, I still think it's an issue. Because I could really need
to put my external swf somewhere into shell's context view, but
still preserve it as a completely separate piece (not having any
injections into it). So some (SOME!) sort of
injector.preventFromInjection(view:DisplayObject) could make the
trick... So unlike most "modular" topics I want to get non-modular
behavior when loading the module =)
Or maybe I miss something regarding modular utilities?
The mediatorMap waits for ADDED_TO_STAGE events on the contextView - so if your child views are inside your contextView, and you add something to the stage, ALL context views that this element is inside of will try to create a mediator for it - because all those contextViews will fire the ADDED_TO_STAGE event. Perhaps? Unless I'm wrong about the way this event works in this scenario.
If it is that the event is being fired in every parent in the chain, I'm not really sure there is anything that can be done about that in terms of the robotlegs side - there's no way for it interrogate the whole container (parent) chain to check for nested contextViews, because each mediatorMap is ignorant of the others, and a contextView is only an instance of DisplayObjectContainer, it has no special properties in terms of extending a class etc.
So - how could any one contextView/mediatorMap know that it's not really supposed to mediate/map this class? Injection will only happen on mediators, commands and items marked for injection - so the example you cite (with the swf not having injections) wouldn't be a problem.
Did I miss something? If I've got it wrong that you've got a view of the same type mapped to the mediatorMap in both your shell and your loaded swf then I could be way off here!
Nope, you didn't miss anything: Your description of what's going on
and why is spot on.
The only thing I might add is that not only is this behavior hard to
change from a technical point of view, it's also desirable in some
I've been thinking about how to optimize the case of nested
contextViews for quite some time now and one idea I've had is to let
mediatorMaps try to combine their ADDED_TO_STAGE/ REMOVED_FROM_STAGE
listeners in the outermost contextView. That would allow for the
creation of more complex behavior such as the innermost mediatorMap
declaring a view as "handled" and thus stopping outer contexts from
trying to map the view, too. I'm not sure if the advantages are worth
the increased complexity, though.
OK, here's proof of concept that actually worked as desired:
ShellContext extends Context/SignalContext:
override protected function get viewMap():IViewMap
return _viewMap ||= new ShellViewMap(contextView, injector);
ShellViewMap extends ViewMap:
override protected function onViewAdded(e:Event):void
if (isValidView(e.target as DisplayObject))
private function isValidView(target:DisplayObject):Boolean
var valid:Boolean = true;
if (target is ModuleView)
target = target.parent;
Not the most optimal & flexible code, but just to make an
example. This allows me to add external RL module (loaded swf into
new ApplicationDomain) into main contextView WITHOUT injecting
anything into it, so two RL contexts becomes completely
independent... well looks like =) haven't tested in all the
possible ways. Now. Questions is — is it worth to add
something into ModularUtilities (which is the last and popular
one?) to implement this workflow?
At least in the implementation you give, this is bound to be
excessively slow: The loop in isValidView will be invoked for each and
every DisplayObject hitting the display list anywhere below the
contextView. What you could do instead is to at least check if the
ShellViewMap itself is even interested in the DisplayObject being
added. If that is not the case, then you don't need to invoke
isValidView at all.
Other than that: Sure, this approach works. I'd be hesitant to add it
to the ModularUtilities, though, as it is very specialized and only
works for exactly you use-case, while disabling other use-cases such
as views that should be handled by both the outer as well as the inner
Adding flexible support for several nested contexts-scenarios is high
on my list of priorities for RL 2, though.