Best approach for shutting down a context

Weyert's Avatar

Weyert

27 Jul, 2011 11:29 PM via web

I am using Joel's ModuleContext so that one expect of my application basically running in it's own world able to receive events the application context using a Gateway-class. This Gateway-class decides which events dispatched are of interest for the child context. Now this child context is running is own life, creating views, loading images, using model data form the application context etc.

This is all working fine but whats the best approach the kill such context. Because I am have cases where this child context needs to be killed because a different one needs to become active. Only at the moment I am dubbing about whats the way right way clean up the active child context.

The ModuleContext-class comes with a dispose-method which dispatches ContextEvent.SHUTDOWN. My idea is to make a command mapping for this and then do the following things:

  • Clear all injection mappings created by the context
  • Stop any running services (if necessary)
  • Remove all children from the contextView
  • Dispatch the event ContextEvent.SHUTDOWN_COMPLETE

Is this a good approach? And how do I know when onRemove-method is called for all mediators of views that got removed? The problem I am having is that I have views which play videos which can be on-going when the child context needs to be shutdown. The video get be finished playing just before or while shutdown the context.

  1. Support Staff 2 Posted by Shaun Smith on 29 Jul, 2011 02:49 PM

    Shaun Smith's Avatar

    Hi Weyert,

    Yes, that sounds like a valid approach. I might change the order a little bit:

    • Remove all children from contextView (do this first so that all the mediators can clean themselves up. I imagine that this would "stop" any running videos)
    • Stop any running services (if necessary)
    • Any other custom cleanup
    • Dispatch ContextEvent.SHUTDOWN_COMPLETE

    I would not bother unmapping things from the injector. The injector is local to your modular context and should be free for GC once you let go of the context (and all references to it).

    If you are using FlashBuilder make sure to profile your application to see if any references are left loitering around after shutdown (but remember that the Flash Player might only run GC when it needs some extra memory - in other words, it may take a little while to release all the references).

    Hope that helps.

  2. 3 Posted by Weyert on 03 Aug, 2011 03:07 PM

    Weyert's Avatar

    Hi Shaun,

    Thanks for your reply! I have been experimenting with improving the shutdown process of my ModuleContext-based RL movie. This SWF movie then gets loaded in a simple Loader()-based loader application.

    Only when I am now trying to profile the application and it's loading it looks like it's still keep hold of a bunch of RobotLegs classes. But I am not sure why. I already called ModuleContext#shutdown and ModuleContext#dispose (in that order). These methods nullifying a bunch of instance variables like _moduleEventDispatcher etc.

    Only for some odd reason it not calling onRemove on the mediators after executing the below code to remove all the views:

        while ( contextView.numChildren != 0) {
            var child: DisplayObject = contextView.getChildAt(0);
            if ( child is IDisposable ) {
                trace("Trying to call dispose() on the view: " + child + " -> " + child.name);
                IDisposable(child).dispose();
            }
    
            contextView.removeChild( child );
            child = null;
        }
    

    After this method I start calling the earlier mentioned methods shutdown and dispose. Only if I check in the profiler the LogoView and LogoMediator class are still having one instance. Even after the view removed so something keep it hanging there.

    For some reason MediatorMap.onViewRemoved() get called but here it setts enterFrame event handler but the event handler never gets triggered. Looks like the enterFrame event is never dispatched.

    What could be the cause of this? Because now it will still keep LogoMediator in the mediator mappings.

  3. Support Staff 4 Posted by Shaun Smith on 03 Aug, 2011 03:35 PM

    Shaun Smith's Avatar

    Hi Weyert,

    I'm not sure exactly what's causing the problem, but there are a couple of things you can try:

    1. Wait a frame between shutdown and dispose. This might give the mediatorMap a chance to remove the mediators before it gets destroyed.

    2. Instead of looping through the contextView, add listeners for the shutdown event in your mediators. When a mediator catches that event call view.parent.removeChild(view);. This moves the responsibility of removing views into the mediators.

    Let me know how it goes!

  4. 5 Posted by Weyert on 05 Aug, 2011 09:44 AM

    Weyert's Avatar

    Thanks, that seems to have improved a lot. As you can see in the attached screenshot. Only it still keeps swiftsuspender related classes listed, especially the injectionpoint classes.

    Can I safely ignore this or should I somehow find out how to get rid of those?

    Instead of looping through the contextView, add listeners for the shutdown event in your mediators. When a mediator catches that event call view.parent.removeChild(view);. This moves the responsibility of removing views into the mediators.

    Interesting approach, I will give this a try.

  5. 6 Posted by Weyert on 10 Aug, 2011 08:56 AM

    Weyert's Avatar

    Hmm, looks like after a while the injector is loosing the injection mappings :(

  6. Support Staff 7 Posted by Shaun Smith on 10 Aug, 2011 11:03 AM

    Shaun Smith's Avatar

    Hi Weyert,

    That is probably just due to the nature of the garbage collector - as I mentioned previously it won't necessarily release garbage until the player needs the memory.

    Does this mean that your issue is resolved?

  7. 8 Posted by Weyert on 10 Aug, 2011 07:02 PM

    Weyert's Avatar

    Hi Shaun,

    Yes, I have partly solved the problem. I haven't been able to get rid of the hundreds of injectionpoint instances after running it for a few hours. I want to try to improve that a bit but not much luck yet.

    Regarding my earlier comment about loosing injection mappings. I think this might be a racing condition problem where its unloaded an old video while a new one gets started. The unloaded unmaps a value if this happens after I set the value for the new video it will fail. Maybe I should the mapValue statement out of the comment and into the view... Because it's the loaded SWF (containing the video) which needs the mapped value, anyways.

    The view already uses the injector to do injector.injectInto(mySWFContent);

  8. Weyert closed this discussion on 17 Sep, 2011 01:46 PM.

Comments are currently closed for this discussion. You can start a new one.