package com.threerings.util { import flash.events.IEventDispatcher; import com.threerings.mx.events.CommandEvent; public class Controller { /** * Set the panel being controlled. */ protected function setControlledPanel (panel :IEventDispatcher) :void { if (_controlledPanel != null) { _controlledPanel.removeEventListener( CommandEvent.TYPE, handleCommandEvent); } _controlledPanel = panel; if (_controlledPanel != null) { _controlledPanel.addEventListener( CommandEvent.TYPE, handleCommandEvent); } } /** * Post an action so that it can be handled by this controller or * another controller above it in the display list. */ public final function postAction (cmd :String, arg :Object = null) :void { CommandEvent.dispatch(_controlledPanel, cmd, arg); } /** * Handle an action that was generated by our panel or some child. * * @return true if the specified action was handled, false otherwise. * * When creating your own controller, override this function and return * true for any command handled, and call super for any unknown commands. */ public function handleAction (cmd :String, arg :Object) :Boolean { // fall back to a method named the cmd var fn :Function = null; try { fn = (this[cmd] as Function); } catch (e :Error) { // suppress //Log.testing("Caught error finding '" + cmd + "()' [" + this + "]"); } if (fn == null) { // try the old style with "handle" prepended try { fn = (this["handle" + cmd] as Function); } catch (e :Error) { // suppress //Log.testing("Caught error finding 'handle" + cmd + "()' [" + // this + "]"); } } if (fn != null) { try { try { // try calling it with the arg fn(arg); } catch (ae :ArgumentError) { if (arg == null) { // try calling it without the arg fn(); } else { throw ae; } } } catch (e :Error) { var log :Log = Log.getLog(this); log.warning("Error handling controller " + "command [error=" + e + ", cmd=" + cmd + ", arg=" + arg + "]."); log.logStackTrace(e); } // we "handled" the event, even if it threw an error return true; } return false; // not handled } /** * Private function to handle the controller event and call * handleAction. */ private function handleCommandEvent (event :CommandEvent) :void { if (handleAction(event.command, event.arg)) { // if we handle the event, stop it from moving outward to another // controller event.markAsHandled(); } } /** The panel currently being controlled. */ protected var _controlledPanel :IEventDispatcher; } }