diff --git a/src/as/com/threerings/crowd/client/PlaceController.as b/src/as/com/threerings/crowd/client/PlaceController.as index 143f82e1d..0221d6be9 100644 --- a/src/as/com/threerings/crowd/client/PlaceController.as +++ b/src/as/com/threerings/crowd/client/PlaceController.as @@ -57,12 +57,10 @@ public /*abstract*/ class PlaceController extends Controller // create our user interface _view = createPlaceView(_ctx); -// // initialize our delegates -// applyToDelegates(new DelegateOp() { -// public void apply (PlaceControllerDelegate delegate) { -// delegate.init(_ctx, _config); -// } -// }); + // initialize our delegates + applyToDelegates(function (del :PlaceControllerDelegate) :void { + del.init(_ctx, _config); + }); // let the derived classes do any initialization stuff didInit(); @@ -130,12 +128,10 @@ public /*abstract*/ class PlaceController extends Controller _ctx.setPlaceView(_view); } -// // let our delegates know what's up -// applyToDelegates(new DelegateOp() { -// public void apply (PlaceControllerDelegate delegate) { -// delegate.willEnterPlace(plobj); -// } -// }); + // let our delegates know what's up + applyToDelegates(function (del :PlaceControllerDelegate) :void { + del.willEnterPlace(plobj); + }); } /** @@ -151,12 +147,10 @@ public /*abstract*/ class PlaceController extends Controller */ public function mayLeavePlace (plobj :PlaceObject) :void { -// // let our delegates know what's up -// applyToDelegates(new DelegateOp() { -// public void apply (PlaceControllerDelegate delegate) { -// delegate.mayLeavePlace(plobj); -// } -// }); + // let our delegates know what's up + applyToDelegates(function (del :PlaceControllerDelegate) :void { + del.mayLeavePlace(plobj); + }); } /** @@ -168,12 +162,10 @@ public /*abstract*/ class PlaceController extends Controller */ public function didLeavePlace (plobj :PlaceObject) :void { -// // let our delegates know what's up -// applyToDelegates(new DelegateOp() { -// public void apply (PlaceControllerDelegate delegate) { -// delegate.didLeavePlace(plobj); -// } -// }); + // let our delegates know what's up + applyToDelegates(function (del :PlaceControllerDelegate) :void { + del.didLeavePlace(plobj); + }); setControlledPanel(null); @@ -192,71 +184,42 @@ public /*abstract*/ class PlaceController extends Controller * should be sure to call super.handleAction for events * they don't specifically handle. */ -// public boolean handleAction (final ActionEvent action) -// { -// final boolean[] handled = new boolean[1]; -// -// // let our delegates have a crack at the action -// applyToDelegates(new DelegateOp() { -// public void apply (PlaceControllerDelegate delegate) { -// // we take advantage of short-circuiting here -// handled[0] = handled[0] || delegate.handleAction(action); -// } -// }); -// -// // if they didn't handly it, pass it off to the super class -// return handled[0] ? true : super.handleAction(action); -// } + override public function handleAction (cmd :String, arg :Object) :Boolean + { + var handled :Boolean = false; + + // let our delegates have a crack at the action + applyToDelegates(function (del :PlaceControllerDelegate) :void { + // we take advantage of short-circuiting here + handled = handled || del.handleAction(cmd, arg); + }); + + // if they didn't handly it, pass it off to the super class + return handled || super.handleAction(cmd, arg); + } /** * Adds the supplied delegate to the list for this controller. */ -// protected void addDelegate (PlaceControllerDelegate delegate) -// { -// if (_delegates == null) { -// _delegates = new ArrayList(); -// } -// _delegates.add(delegate); -// } - - /** - * Used to call methods in delegates. - */ -// protected static interface DelegateOp -// { -// public void apply (PlaceControllerDelegate delegate); -// } + protected function addDelegate (delegate :PlaceControllerDelegate) :void + { + if (_delegates == null) { + _delegates = new Array(); + } + _delegates.push(delegate); + } /** * Applies the supplied operation to the registered delegates. */ -// protected void applyToDelegates (DelegateOp op) -// { -// if (_delegates != null) { -// int dcount = _delegates.size(); -// for (int i = 0; i < dcount; i++) { -// op.apply((PlaceControllerDelegate)_delegates.get(i)); -// } -// } -// } - - /** - * Applies the supplied operation to the registered delegates that - * derive from the specified class. - */ -// protected void applyToDelegates (Class dclass, DelegateOp op) -// { -// if (_delegates != null) { -// int dcount = _delegates.size(); -// for (int i = 0; i < dcount; i++) { -// PlaceControllerDelegate delegate = -// (PlaceControllerDelegate)_delegates.get(i); -// if (dclass.isAssignableFrom(delegate.getClass())) { -// op.apply(delegate); -// } -// } -// } -// } + protected function applyToDelegates (visitor :Function) :void + { + if (_delegates != null) { + for (var ii :int = 0; ii < _delegates.length; ii++) { + visitor.call(this, _delegates[ii]); + } + } + } /** A reference to the active client context. */ protected var _ctx :CrowdContext; @@ -270,5 +233,8 @@ public /*abstract*/ class PlaceController extends Controller /** A reference to the root user interface component. */ protected var _view :PlaceView; + + /** A list of the delegates in use by this controller. */ + protected var _delegates :Array; } } diff --git a/src/as/com/threerings/crowd/client/PlaceControllerDelegate.as b/src/as/com/threerings/crowd/client/PlaceControllerDelegate.as new file mode 100644 index 000000000..8f9d544fc --- /dev/null +++ b/src/as/com/threerings/crowd/client/PlaceControllerDelegate.as @@ -0,0 +1,97 @@ +// +// $Id: PlaceControllerDelegate.java 4191 2006-06-13 22:42:20Z ray $ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.crowd.client { + +import com.threerings.crowd.data.PlaceConfig; +import com.threerings.crowd.data.PlaceObject; +import com.threerings.crowd.util.CrowdContext; + +/** + * Provides an extensible mechanism for encapsulating delegated + * functionality that works with the place services. + * + *

Thanks to Java's lack of multiple inheritance, it will likely + * become necessary to factor certain services that might be used by a + * variety of {@link PlaceController} derived classes into delegate + * classes because they do not fit into the single inheritance hierarchy + * that makes sense for a particular application. To facilitate this + * process, this delegate class is provided which the standard place + * controller can be made to call out to for all of the standard methods. + */ +public class PlaceControllerDelegate +{ + /** + * Constructs the delegate with the controller for which it is + * delegating. + */ + public function PlaceControllerDelegate (controller :PlaceController) + { + _controller = controller; + } + + /** + * Called to initialize the delegate. + */ + public function init (ctx :CrowdContext, config :PlaceConfig) :void + { + } + + /** + * Called to let the delegate know that we're entering a place. + */ + public function willEnterPlace (plobj :PlaceObject) :void + { + } + + /** + * Called before a request is submitted to the server to leave the + * current place. The request to leave may be rejected, but if a place + * controller needs to make a final communication to the place manager + * before it leaves, it should so do here. This is the only place in + * which the controller is guaranteed to be able to communicate to the + * place manager, as by the time {@link #didLeavePlace} is called, the + * place manager may have already been destroyed. + */ + public function mayLeavePlace (plobj :PlaceObject) :void + { + } + + /** + * Called to let the delegate know that we've left the place. + */ + public function didLeavePlace (plobj :PlaceObject) :void + { + } + + /** + * Called to give the delegate a chance to handle controller actions + * that weren't handled by the main controller. + */ + public function handleAction (cmd :String, arg :Object) :Boolean + { + return false; + } + + /** A reference to the controller for which we are delegating. */ + protected var _controller :PlaceController; +} +}