Module Loading in a PureMVC Pipe Application

Since the PureMVC Pipes Utility was released I have been trying to find the best and most comfortable way for me to load and unload Modules in the main Shell application. A couple of things pertinent to my method of development: + Looking at the kind of builds that I would utilise the MultiCore framework, most would load multiple single instances of modules. + I prefer to reference as little of the framework or Pipe logic as possible in the main application Shell and defer this to the Application Mediator. + I want the code structured in a manner that adding future modules will take the minimum time possible.

With these points in mind I opted for (a) the IModuleInfo as the handle for the modules and (b) the ModuleManager for loading and unloading of the modules. Heres how: + Container to load a module into

1
<mx:HBox id="moduleContainer"/>
  • Click event on a button to load a particular module
1
click="loadModule( VIDEO_MODULE )"
  • Load module method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
           * Button clicked to either load or unload a module.
           * String passed with the name of the module to load.
           * Determine if this module has been loaded then
           * load or unload accrodingly...
           */
          public static const VIDEO_MODULE_URL:String  = "VideoModule.swf";
           
          private function loadModule( module:String ):void
          {
              CursorManager.setBusyCursor();
              
              switch ( module )
              {
                  case VIDEO_MODULE:
                      if( !_video || !_video.loaded )
                      {
                          _video = ModuleManager.getModule( VIDEO_MODULE_URL );
                          _video.addEventListener( ModuleEvent.READY, onModuleReady );
                          _video.load();
                      }
                      else
                      {
                          _video.addEventListener( ModuleEvent.UNLOAD, onModuleUnload );
                          _video.unload();
                      }
                      break;
              }
          }
  • Module ready method fired from ModuleEvent.READY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
           * Module loaded succesfully, create a reference to the loaded instance
           * type casting to the appropriate Module Class.  Create a new instance
           * of our custom (Add) Event class passing the module instance type casted 
           * to DisplayObject.  DispatchEvent to ApplicationMediator to load into 
           * moduleContainer and set up within the rest of the framework...
           */
          private function onModuleReady( e:ModuleEvent ):void
          {
              var event:AddModuleEvent;
              
              switch ( e.module )
              {
                  case _video:
                      video_instance = _video.factory.create() as VideoModule;
                      event = new AddModuleEvent( video_instance as DisplayObject );
                      dispatchEvent( event );
                      _video.removeEventListener( ModuleEvent.READY, onModuleReady );
                      break;
              }
                                          
              CursorManager.removeBusyCursor();
          }
  • Module unload method fired from ModuleEvent.UNLOAD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
           * Module unloaded succesfully, Create a new instance of our custom
           * (Remove) Event class passing the module instance type casted to
           * DisplayObject.  DispatchEvent to ApplicationMediator to unload from 
           * moduleContainer and remove from the rest of the framework using Garbage
           * Collection...
           */
          private function onModuleUnload( e:ModuleEvent ):void
          {
              var event:RemoveModuleEvent;
              
              switch ( e.module )
              {
                  case _video:
                      event = new RemoveModuleEvent( video_instance as DisplayObject );
                      dispatchEvent( event );
                      _video.removeEventListener( ModuleEvent.UNLOAD, onModuleUnload );
                      break;
              }
                          
              CursorManager.removeBusyCursor();
          }
  • On dispatching custom add/remove module Events these methods are fired in the ApplicationMediator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private function onModuleAdd( e:AddModuleEvent ):void
      {
          app.moduleContainer.addChild( e.component );
          
          var module:IPipeAwareModule = e.component as IPipeAwareModule;
          
          sendNotification( ApplicationFacade.MODULE_ADDED, module );
      }
      
      private function onModuleRemove( e:RemoveModuleEvent ):void
      {
          sendNotification( ApplicationFacade.MODULE_REMOVED );
          
          IPipeAwareModule( e.component ).garbageCollection();
          
          app.moduleContainer.removeChild( e.component );
      }

I would like to hear how others are handling this :)

A little reminder to read this post on Garbage Collection: http://www.newtriks.com/?p=132.

Comments