mikebritton
|
|
« Reply #2 on: June 04, 2008, 11:33:14 » |
|
Here's my problem in detail, so pardon the massive code dump. Hopefully my issue can be solved easily; the main issue is my attempt to rearchitect an existing application with Pipes before writing a simple boilerplate :-)
I have a Shell MovieClip that kicks it all off.
package { import com.multicastmedia.shell.ApplicationFacade; import flash.display.DisplayObject; import flash.display.MovieClip; public class Shell extends MovieClip { public static const NAME:String = "Shell"; private var facade:ApplicationFacade = ApplicationFacade.getInstance( NAME ); public function Shell():void { facade.startup( this ); } public function addLivePlayer(livePlayer:DisplayObject):void { addChild(livePlayer); } public function addSlides(slides:DisplayObject):void { addChild(slides); } public function removeLivePlayer(livePlayer:DisplayObject):void { removeChild(livePlayer); } public function removeSlides(slides:DisplayObject):void { removeChild(slides); } } }
Picture three modules, a live video player, a slide display, and shell. My Shell's ApplicationFacade:
package com.multicastmedia.shell { import org.puremvc.as3.multicore.patterns.facade.Facade; import com.multicastmedia.shell.controller.StartupCommand;
public class ApplicationFacade extends Facade { // Notification constants public static const STARTUP:String = 'startup'; public static const CONNECT_SHELL_TO_LIVEPLAYER:String = 'connectshelltoliveplayer'; public static const CONNECT_SHELL_TO_LIVESLIDES:String = 'connectshelltoliveslides'; public static const CONNECT_MODULE_TO_LIVEPLAYER:String = 'connectmoduletoliveplayer'; public static const CONNECT_MODULE_TO_SLIDES:String = 'connectmoduletoslides'; public static const CONNECT_MODULE_TO_SHELL:String = 'connectmoduletoshell'; public function ApplicationFacade( key:String ) { super(key); }
public static function getInstance( key:String ):ApplicationFacade { if ( instanceMap[ key ] == null ) instanceMap[ key ] = new ApplicationFacade( key ); return instanceMap[ key ] as ApplicationFacade; } override protected function initializeController( ) : void { super.initializeController(); registerCommand( STARTUP, StartupCommand ); } /** * Application startup * * @param app a reference to the application component */ public function startup( app:Shell ):void { sendNotification( STARTUP, app ); } } }
My Shell's StartupCommand executes:
package com.multicastmedia.shell.controller { import com.multicastmedia.shell.view.ShellJunctionMediator; import com.multicastmedia.shell.view.ApplicationMediator; import com.multicastmedia.shell.view.LivePlayerModuleMediator; import com.multicastmedia.shell.view.SlideModuleMediator; import com.multicastmedia.shell.ApplicationFacade; import fl.motion.SimpleEase; import org.puremvc.as3.interfaces.ICommand; import org.puremvc.as3.multicore.interfaces.ICommand; import org.puremvc.as3.multicore.interfaces.INotification; import org.puremvc.as3.multicore.patterns.command.SimpleCommand; import org.osflash.thunderbolt.Logger; public class StartupCommand extends SimpleCommand implements ICommand { override public function execute( note:INotification ):void { Logger.debug("StartupCommand:execute"); facade.registerMediator(new LivePlayerModuleMediator()); facade.registerMediator(new SlideModuleMediator()); facade.registerMediator(new ShellJunctionMediator()); var app:Shell = note.getBody() as Shell; facade.registerMediator(new ApplicationMediator( app )); sendNotification(ApplicationFacade.CONNECT_SHELL_TO_LIVEPLAYER); } } }
The first mediator, LivePlayerModuleMediator, registered is really the only one related to this issue; when I understand why this is erroring out, I'll be able to fix for all modules. So, I register this mediator, which looks like this:
package com.multicastmedia.shell.view { import org.puremvc.as3.multicore.interfaces.INotification; import org.puremvc.as3.multicore.patterns.mediator.Mediator; import org.puremvc.as3.multicore.utilities.pipes.plumbing.Pipe; import org.puremvc.as3.multicore.utilities.pipes.plumbing.TeeMerge; import org.puremvc.as3.multicore.utilities.pipes.plumbing.Junction; import org.puremvc.as3.multicore.utilities.pipes.interfaces.IPipeFitting; import com.multicastmedia.common.IPipeAware; import com.multicastmedia.common.JunctionMediator; import com.multicastmedia.apps.live.LivePlayerModule; import com.multicastmedia.shell.ApplicationFacade;
import org.osflash.thunderbolt.Logger; public class LivePlayerModuleMediator extends Mediator { public static const NAME:String = 'LivePlayerModuleMediator'; public function LivePlayerModuleMediator() { super(NAME, new LivePlayerModule()); }
/** * LivePlayerModule related Notification list. */ override public function listNotificationInterests():Array { return [ ApplicationFacade.CONNECT_SHELL_TO_LIVEPLAYER ]; } /** * Handle LivePlayerModule related Notifications. * * Connecting modules and the Shell to the LivePlayerModule. */ override public function handleNotification( note:INotification ):void { switch( note.getName() ) { case ApplicationFacade.CONNECT_SHELL_TO_LIVEPLAYER: Logger.debug("CONNECT_SHELL_TO_LIVEPLAYER"); var module:IPipeAware = note.getBody() as IPipeAware; var pipe:Pipe = new Pipe(); module.acceptOutputPipe(JunctionMediator.STDLOG,pipe); livePlayer.acceptInputPipe(JunctionMediator.STDIN,pipe); break; } } /** * The Logger Module. */ private function get livePlayer():LivePlayerModule { return viewComponent as LivePlayerModule; } } }
My LivePlayerFacade is instantiated and started. It looks like this:
package com.multicastmedia.apps.live.liveplayer { import com.multicastmedia.apps.live.liveplayer.model.vo.ConfigVO; import com.multicastmedia.apps.live.LivePlayerModule; import org.puremvc.as3.multicore.interfaces.IFacade; import org.puremvc.as3.multicore.patterns.facade.Facade; import com.multicastmedia.apps.live.liveplayer.controller.StartupCommand; import com.multicastmedia.apps.live.liveplayer.controller.GetLiveEventCommand; import com.multicastmedia.apps.live.liveplayer.controller.LiveConnectionCommand; import com.multicastmedia.apps.live.liveplayer.controller.LiveStreamControlCommand; import com.multicastmedia.apps.live.liveplayer.controller.SharedObjectCommand; import com.multicastmedia.apps.live.liveplayer.controller.PollForSlideCommand; import org.osflash.thunderbolt.Logger; import flash.display.StageDisplayState; import flash.events.FullScreenEvent;
public class LivePlayerFacade extends Facade implements IFacade { // Notification name constants only public static const STARTUP:String = "startup"; public static const CONFIG_LOADED:String = "config_loaded"; public static const GET_EVENT_INFO:String = "get_event_info"; public static const GET_SETTINGS:String = "get_settings"; public static const SETTINGS_RETURNED:String = "settings_returned"; public static const EVENT_LOADED:String = "event_loaded"; public static const EVENT_COMPLETE:String = "event_complete"; public static const CONNECT:String = "connect"; public static const CONNECTED:String = "connected"; public static const CONNECTION_FAILED:String = "connection_failed"; public static const POLL_LIVE_EVENT:String = "poll_live_event"; public static const POLL_DURATION_COMPLETE:String = "poll_duration_complete"; public static const POLL_COMPLETE:String = "poll_complete"; public static const POLL_DURATION:String = "poll_duration"; public static const POLL_FOR_SLIDE:String = "poll_for_slide"; public static const POLL_SLIDE_RETURNED:String = "poll_slide_returned"; public static const COUNTDOWN_COMPLETE:String = "countdown_complete"; public static const START_COUNTDOWN:String = "start_countdown"; public static const START_PREROLL:String = "start_preroll"; public static const START_POSTROLL:String = "start_postroll"; public static const TIME:String = "time"; public static const BUFFER_FULL:String = "buffer_full"; public static const DESTROY_NETSTREAM:String = "destroy_netstream"; public static const PAUSE_LIVE_STREAM:String = "pause_live_stream"; public static const STOP_LIVE_STREAM:String = "stop_live_stream"; public static const RESUME_LIVE_STREAM:String = "resume_live_stream"; public static const TOGGLE_FULLSCREEN:String = "toggle_fullscreen"; public static const ADJUST_VOLUME:String = "adjust_volume"; public static const ADJUST_PLAYER_SCALE:String = "adjust_player_scale"; // Failures public static const EVENT_FAILED:String = "event_failed"; public static const GENERAL_FAILURE:String = "general_failure"; public function LivePlayerFacade( key:String ):void { super(key); } public static function getInstance( key:String ):LivePlayerFacade { if ( instanceMap[ key ] == null ) instanceMap[ key ] = new LivePlayerFacade( key ); return instanceMap[ key ] as LivePlayerFacade; } /** * Map all Commands to Notifications here */ override protected function initializeController( ):void { super.initializeController(); registerCommand( STARTUP, StartupCommand ); registerCommand( GET_EVENT_INFO, GetLiveEventCommand ); registerCommand( GET_SETTINGS, SharedObjectCommand ); registerCommand( CONNECT, LiveConnectionCommand ); registerCommand( POLL_LIVE_EVENT, GetLiveEventCommand ); registerCommand( PAUSE_LIVE_STREAM, LiveStreamControlCommand ); registerCommand( RESUME_LIVE_STREAM, LiveStreamControlCommand ); registerCommand( STOP_LIVE_STREAM, LiveStreamControlCommand ); registerCommand( ADJUST_VOLUME, LiveStreamControlCommand ); } public function startup( app:LivePlayerModule ):void { Logger.debug("LivePlayerFacade::startup"); sendNotification( STARTUP, app ); } } }
The command it executes is a MacroCommand which initializes the liveplayer model and view using separate commands. Here's the command that initializes the view. This is where the problem occurs.
package com.multicastmedia.apps.live.liveplayer.controller { import com.multicastmedia.apps.live.liveplayer.view.components.ControlsView; import com.multicastmedia.apps.live.liveplayer.view.components.CountdownView; import LivePlayer; import com.multicastmedia.apps.live.LivePlayerModule; import org.puremvc.as3.multicore.interfaces.ICommand; import org.puremvc.as3.multicore.patterns.command.SimpleCommand; import org.puremvc.as3.multicore.interfaces.INotification; import com.multicastmedia.apps.live.liveplayer.view.mediator.ControlsMediator; import com.multicastmedia.apps.live.liveplayer.view.mediator.ApplicationMediator; import com.multicastmedia.apps.live.liveplayer.view.mediator.VideoDisplayMediator; import com.multicastmedia.apps.live.liveplayer.view.mediator.CountdownMediator; import org.osflash.thunderbolt.Logger; public class ViewPrepCommand extends SimpleCommand implements ICommand { override public function execute( note:INotification ):void { var lp:LivePlayer = note.getBody() as LivePlayer; Logger.debug("ViewPrepCommand::execute"); facade.registerMediator( new ApplicationMediator( note.getBody() ) ); // BLOWUP: TypeError: Error #1009: Cannot access a property or method of a null object reference. at com.multicastmedia.apps.live.liveplayer.controller::ViewPrepCommand/execute()[C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\mediaplayer_live_working\mediaplayer_live\src\com\multicastmedia\apps\live\liveplayer\controller\ViewPrepCommand.as:35] facade.registerMediator( new VideoDisplayMediator( lp.videoDisplayView )); facade.registerMediator( new ControlsMediator( lp.controlsView ) ); facade.registerMediator( new CountdownMediator( lp.countdownView )); } } }
I'm sure my mistake is obvious to the experienced eye, but I am stuck nonetheless. Any idea what could be happening?
Thanks in advance.
|