diff --git a/src/java/com/threerings/crowd/client/LocationDirector.java b/src/java/com/threerings/crowd/client/LocationDirector.java index 3fac15a4d..c5564179f 100644 --- a/src/java/com/threerings/crowd/client/LocationDirector.java +++ b/src/java/com/threerings/crowd/client/LocationDirector.java @@ -41,33 +41,31 @@ import com.threerings.crowd.data.PlaceObject; import com.threerings.crowd.util.CrowdContext; /** - * The location director provides a means by which entities on the client - * can request to move from place to place and can be notified if other - * entities have caused the client to move to a new place. It also - * provides a mechanism for ratifying a request to move to a new place - * before actually issuing the request. + * The location director provides a means by which entities on the client can request to move from + * place to place and can be notified if other entities have caused the client to move to a new + * place. It also provides a mechanism for ratifying a request to move to a new place before + * actually issuing the request. */ public class LocationDirector extends BasicDirector implements LocationCodes, Subscriber, LocationReceiver, LocationService.MoveListener { /** - * Used to recover from a moveTo request that was accepted but - * resulted in a failed attempt to fetch the place object to which we - * were moving. + * Used to recover from a moveTo request that was accepted but resulted in a failed attempt to + * fetch the place object to which we were moving. */ public static interface FailureHandler { /** - * Should instruct the client to move to the last known working - * location (as well as clean up after the failed moveTo request). + * Should instruct the client to move to the last known working location (as well as clean + * up after the failed moveTo request). */ public void recoverFailedMove (int placeId); } /** - * Constructs a location director which will configure itself for - * operation using the supplied context. + * Constructs a location director which will configure itself for operation using the supplied + * context. */ public LocationDirector (CrowdContext ctx) { @@ -77,14 +75,12 @@ public class LocationDirector extends BasicDirector _ctx = ctx; // register for location notifications - _ctx.getClient().getInvocationDirector().registerReceiver( - new LocationDecoder(this)); + _ctx.getClient().getInvocationDirector().registerReceiver(new LocationDecoder(this)); } /** - * Adds a location observer to the list. This observer will - * subsequently be notified of potential, effected and failed location - * changes. + * Adds a location observer to the list. This observer will subsequently be notified of + * potential, effected and failed location changes. */ public void addLocationObserver (LocationObserver observer) { @@ -100,8 +96,8 @@ public class LocationDirector extends BasicDirector } /** - * Returns the place object for the location we currently occupy or - * null if we're not currently occupying any location. + * Returns the place object for the location we currently occupy or null if we're not currently + * occupying any location. */ public PlaceObject getPlaceObject () { @@ -117,13 +113,11 @@ public class LocationDirector extends BasicDirector } /** - * Requests that this client be moved to the specified place. A - * request will be made and when the response is received, the - * location observers will be notified of success or failure. + * Requests that this client be moved to the specified place. A request will be made and when + * the response is received, the location observers will be notified of success or failure. * - * @return true if the move to request was issued, false if it was - * rejected by a location observer or because we have another request - * outstanding. + * @return true if the move to request was issued, false if it was rejected by a location + * observer or because we have another request outstanding. */ public boolean moveTo (int placeId) { @@ -133,31 +127,26 @@ public class LocationDirector extends BasicDirector return false; } - // first check to see if our observers are happy with this move - // request + // first check to see if our observers are happy with this move request if (!mayMoveTo(placeId, null)) { return false; } - // we need to call this both to mark that we're issuing a move - // request and to check to see if the last issued request should - // be considered stale + // we need to call this both to mark that we're issuing a move request and to check to see + // if the last issued request should be considered stale boolean refuse = checkRepeatMove(); // complain if we're over-writing a pending request if (_pendingPlaceId != -1) { - // if the pending request has been outstanding more than a - // minute, go ahead and let this new one through in an attempt - // to recover from dropped moveTo requests + // if the pending request has been outstanding more than a minute, go ahead and let + // this new one through in an attempt to recover from dropped moveTo requests if (refuse) { Log.warning("Refusing moveTo; We have a request outstanding " + - "[ppid=" + _pendingPlaceId + - ", npid=" + placeId + "]."); + "[ppid=" + _pendingPlaceId + ", npid=" + placeId + "]."); return false; } else { - Log.warning("Overriding stale moveTo request " + - "[ppid=" + _pendingPlaceId + + Log.warning("Overriding stale moveTo request [ppid=" + _pendingPlaceId + ", npid=" + placeId + "]."); } } @@ -172,11 +161,10 @@ public class LocationDirector extends BasicDirector } /** - * Requests to move to the room that we last occupied, if such a room - * exists. + * Requests to move to the room that we last occupied, if such a room exists. * - * @return true if we had a previous room and we requested to move to - * it, false if we had no previous room. + * @return true if we had a previous room and we requested to move to it, false if we had no + * previous room. */ public boolean moveBack () { @@ -192,8 +180,8 @@ public class LocationDirector extends BasicDirector /** * Issues a request to leave our current location. * - * @return true if we were able to leave, false if we are in the - * middle of moving somewhere and can't yet leave. + * @return true if we were able to leave, false if we are in the middle of moving somewhere and + * can't yet leave. */ public boolean leavePlace () { @@ -207,16 +195,15 @@ public class LocationDirector extends BasicDirector } /** - * This can be called by cooperating directors that need to coopt the - * moving process to extend it in some way or other. In such - * situations, they should call this method before moving to a new - * location to check to be sure that all of the registered location - * observers are amenable to a location change. + * This can be called by cooperating directors that need to coopt the moving process to extend + * it in some way or other. In such situations, they should call this method before moving to a + * new location to check to be sure that all of the registered location observers are amenable + * to a location change. * * @param placeId the place oid of our tentative new location. * - * @return true if everyone is happy with the move, false if it was - * vetoed by one of the location observers. + * @return true if everyone is happy with the move, false if it was vetoed by one of the + * location observers. */ public boolean mayMoveTo (final int placeId, ResultListener rl) { @@ -228,12 +215,11 @@ public class LocationDirector extends BasicDirector } }); - // if we're actually going somewhere, let the controller know that - // we might be leaving + // if we're actually going somewhere, let the controller know that we might be leaving mayLeavePlace(); - // if we have a result listener, let it know if we failed - // or keep it for later if we're still going + // if we have a result listener, let it know if we failed or keep it for later if we're + // still going if (rl != null) { if (vetoed[0]) { rl.requestFailed(new MoveVetoedException()); @@ -246,8 +232,7 @@ public class LocationDirector extends BasicDirector } /** - * Called to inform our controller that we may be leaving the current - * place. + * Called to inform our controller that we may be leaving the current place. */ protected void mayLeavePlace () { @@ -255,19 +240,17 @@ public class LocationDirector extends BasicDirector try { _controller.mayLeavePlace(_plobj); } catch (Exception e) { - Log.warning("Place controller choked in " + - "mayLeavePlace [plobj=" + _plobj + "]."); + Log.warning("Place controller choked in mayLeavePlace [plobj=" + _plobj + "]."); Log.logStackTrace(e); } } } /** - * This can be called by cooperating directors that need to coopt the - * moving process to extend it in some way or other. In such - * situations, they will be responsible for receiving the successful - * move response and they should let the location director know that - * the move has been effected. + * This can be called by cooperating directors that need to coopt the moving process to extend + * it in some way or other. In such situations, they will be responsible for receiving the + * successful move response and they should let the location director know that the move has + * been effected. * * @param placeId the place oid of our new location. * @param config the configuration information for the new place. @@ -294,8 +277,7 @@ public class LocationDirector extends BasicDirector // start up a new place controller to manage the new place _controller = createController(config); if (_controller == null) { - Log.warning("Place config returned null controller " + - "[config=" + config + "]."); + Log.warning("Place config returned null controller [config=" + config + "]."); return; } _controller.init(_ctx, config); @@ -305,9 +287,8 @@ public class LocationDirector extends BasicDirector } /** - * Called when we're leaving our current location. Informs the - * location's controller that we're departing, unsubscribes from the - * location's place object, and clears out our internal place + * Called when we're leaving our current location. Informs the location's controller that we're + * departing, unsubscribes from the location's place object, and clears out our internal place * information. */ public void didLeavePlace () @@ -318,16 +299,14 @@ public class LocationDirector extends BasicDirector try { _controller.didLeavePlace(_plobj); } catch (Exception e) { - Log.warning("Place controller choked in " + - "didLeavePlace [plobj=" + _plobj + "]."); + Log.warning("Place controller choked in didLeavePlace [plobj=" + _plobj + "]."); Log.logStackTrace(e); } _controller = null; } // unsubscribe from our old place object - _ctx.getDObjectManager().unsubscribeFromObject( - _plobj.getOid(), this); + _ctx.getDObjectManager().unsubscribeFromObject(_plobj.getOid(), this); _plobj = null; // and clear out the associated place id @@ -336,10 +315,9 @@ public class LocationDirector extends BasicDirector } /** - * This can be called by cooperating directors that need to coopt the - * moving process to extend it in some way or other. If the coopted - * move request fails, this failure can be propagated to the location - * observers if appropriate. + * This can be called by cooperating directors that need to coopt the moving process to extend + * it in some way or other. If the coopted move request fails, this failure can be propagated + * to the location observers if appropriate. * * @param placeId the place oid to which we failed to move. * @param reason the reason code given for failure. @@ -359,8 +337,8 @@ public class LocationDirector extends BasicDirector } /** - * Called to test and set a time stamp that we use to determine if a - * pending moveTo request is stale. + * Called to test and set a time stamp that we use to determine if a pending moveTo request is + * stale. */ public boolean checkRepeatMove () { @@ -381,16 +359,12 @@ public class LocationDirector extends BasicDirector // subscribe to our body object Subscriber sub = new Subscriber() { - public void objectAvailable (BodyObject object) - { + public void objectAvailable (BodyObject object) { gotBodyObject(object); } - - public void requestFailed (int oid, ObjectAccessException cause) - { - Log.warning("Location director unable to fetch body " + - "object; all has gone horribly wrong" + - "[cause=" + cause + "]."); + public void requestFailed (int oid, ObjectAccessException cause) { + Log.warning("Location director unable to fetch body object; all has gone " + + "horribly wrong [cause=" + cause + "]."); } }; int cloid = client.getClientOid(); @@ -409,8 +383,8 @@ public class LocationDirector extends BasicDirector // let our observers know that we're no longer in a location _observers.apply(_didChangeOp); - // clear out everything else (it's possible that we were logged - // off in the middle of a change location request) + // clear out everything else (it's possible that we were logged off in the middle of a + // change location request) _pendingPlaceId = -1; _previousPlaceId = -1; _lastRequestTime = 0L; @@ -432,8 +406,8 @@ public class LocationDirector extends BasicDirector protected void gotBodyObject (BodyObject clobj) { - // check to see if we are already in a location, in which case - // we'll want to be going there straight away + // TODO? check to see if we are already in a location, in which case we'll want to be going + // there straight away } // documentation inherited from interface @@ -453,8 +427,7 @@ public class LocationDirector extends BasicDirector int placeId = _pendingPlaceId; _pendingPlaceId = -1; - Log.info("moveTo failed [pid=" + placeId + - ", reason=" + reason + "]."); + Log.info("moveTo failed [pid=" + placeId + ", reason=" + reason + "]."); // let our observers know that something has gone horribly awry notifyFailure(placeId, reason); @@ -476,21 +449,23 @@ public class LocationDirector extends BasicDirector } /** - * Called when we receive the place object to which we subscribed - * after a successful moveTo request. + * Called when we receive the place object to which we subscribed after a successful moveTo + * request. */ public void objectAvailable (PlaceObject object) { // yay, we have our new place object _plobj = object; + // fill in our manager caller + _plobj.initManagerCaller(_ctx.getClient().getDObjectManager()); + // let the place controller know that we're ready to roll if (_controller != null) { try { _controller.willEnterPlace(_plobj); } catch (Exception e) { - Log.warning("Controller choked in willEnterPlace " + - "[place=" + _plobj + "]."); + Log.warning("Controller choked in willEnterPlace [place=" + _plobj + "]."); Log.logStackTrace(e); } } @@ -500,17 +475,15 @@ public class LocationDirector extends BasicDirector } /** - * Called if we are unable to subscribe to the place object that was - * provided to us with our successful moveTo request. This is - * generally a bad scene and we do our best to recover by going back - * to the previously known location. + * Called if we are unable to subscribe to the place object that was provided to us with our + * successful moveTo request. This is generally a bad scene and we do our best to recover by + * going back to the previously known location. */ public void requestFailed (int oid, ObjectAccessException cause) { - // aiya! we were unable to fetch our new place object; something - // is badly wrong - Log.warning("Aiya! Unable to fetch place object for new location " + - "[plid=" + oid + ", reason=" + cause + "]."); + // aiya! we were unable to fetch our new place object; something is badly wrong + Log.warning("Aiya! Unable to fetch place object for new location [plid=" + oid + + ", reason=" + cause + "]."); // clear out our half initialized place info int placeId = _placeId; @@ -519,9 +492,8 @@ public class LocationDirector extends BasicDirector // let the kids know shit be fucked notifyFailure(placeId, "m.unable_to_fetch_place_object"); - // we need to sort out what to do about the half-initialized place - // controller. presently we punt and hope that calling - // didLeavePlace() without ever having called willEnterPlace() + // we need to sort out what to do about the half-initialized place controller. presently we + // punt and hope that calling didLeavePlace() without ever having called willEnterPlace() // does whatever's necessary // try to return to our previous location @@ -529,9 +501,8 @@ public class LocationDirector extends BasicDirector _failureHandler.recoverFailedMove(placeId); } else { - // if we were previously somewhere (and that somewhere isn't - // where we just tried to go), try going back to that happy - // place + // if we were previously somewhere (and that somewhere isn't where we just tried to + // go), try going back to that happy place if (_previousPlaceId != -1 && _previousPlaceId != placeId) { moveTo(_previousPlaceId); } @@ -539,23 +510,20 @@ public class LocationDirector extends BasicDirector } /** - * Sets the failure handler which will recover from place object - * fetching failures. In the event that we are unable to fetch our - * place object after making a successful moveTo request, we attempt - * to rectify the failure by moving back to the last known working - * location. Because entites that cooperate with the location director - * may need to become involved in this failure recovery, we provide - * this interface whereby they can interject themseves into the + * Sets the failure handler which will recover from place object fetching failures. In the + * event that we are unable to fetch our place object after making a successful moveTo request, + * we attempt to rectify the failure by moving back to the last known working location. Because + * entites that cooperate with the location director may need to become involved in this + * failure recovery, we provide this interface whereby they can interject themseves into the * failure recovery process and do their own failure recovery. */ public void setFailureHandler (FailureHandler handler) { if (_failureHandler != null) { - Log.warning("Requested to set failure handler, but we've " + - "already got one. The conflicting entities will " + - "likely need to perform more sophisticated " + - "coordination to deal with failures. " + - "[old=" + _failureHandler + ", new=" + handler + "]."); + Log.warning("Requested to set failure handler, but we've already got one. The " + + "conflicting entities will likely need to perform more sophisticated " + + "coordination to deal with failures. [old=" + _failureHandler + + ", new=" + handler + "]."); } else { _failureHandler = handler; @@ -573,10 +541,9 @@ public class LocationDirector extends BasicDirector } /** - * Called to create our place controller using the supplied place - * configuration. This lives in a separate method so that derived instances - * can do funny class loader business if necessary to load the place - * controller using a sandboxed class loader. + * Called to create our place controller using the supplied place configuration. This lives in + * a separate method so that derived instances can do funny class loader business if necessary + * to load the place controller using a sandboxed class loader. */ protected PlaceController createController (PlaceConfig config) { @@ -590,8 +557,8 @@ public class LocationDirector extends BasicDirector protected LocationService _lservice; /** Our location observer list. */ - protected ObserverList _observers = - new ObserverList(ObserverList.SAFE_IN_ORDER_NOTIFY); + protected ObserverList _observers = new ObserverList( + ObserverList.SAFE_IN_ORDER_NOTIFY); /** The oid of the place we currently occupy. */ protected int _placeId = -1; @@ -602,10 +569,8 @@ public class LocationDirector extends BasicDirector /** The place controller in effect for our current place. */ protected PlaceController _controller; - /** - * The oid of the place for which we have an outstanding moveTo - * request, or -1 if we have no outstanding request. - */ + /** The oid of the place for which we have an outstanding moveTo request, or -1 if we have no + * outstanding request. */ protected int _pendingPlaceId = -1; /** The oid of the place we previously occupied. */ @@ -614,24 +579,21 @@ public class LocationDirector extends BasicDirector /** The last time we requested a move to. */ protected long _lastRequestTime; - /** The entity that deals when we fail to subscribe to a place - * object. */ + /** The entity that deals when we fail to subscribe to a place object. */ protected FailureHandler _failureHandler; - /** A listener that wants to know if we succeeded or - * how we failed to move. */ + /** A listener that wants to know if we succeeded or how we failed to move. */ protected ResultListener _moveListener; /** The operation used to inform observers that the location changed. */ - protected ObserverOp _didChangeOp = - new ObserverOp() { + protected ObserverOp _didChangeOp = new ObserverOp() { public boolean apply (LocationObserver obs) { obs.locationDidChange(_plobj); return true; } }; - /** We require that a moveTo request be outstanding for one minute - * before it is declared to be stale. */ + /** We require that a moveTo request be outstanding for one minute before it is declared to be + * stale. */ protected static final long STALE_REQUEST_DURATION = 60L * 1000L; } diff --git a/src/java/com/threerings/crowd/data/PlaceObject.java b/src/java/com/threerings/crowd/data/PlaceObject.java index 47d9d165f..a8047d06b 100644 --- a/src/java/com/threerings/crowd/data/PlaceObject.java +++ b/src/java/com/threerings/crowd/data/PlaceObject.java @@ -26,6 +26,7 @@ import java.util.Iterator; import com.threerings.util.Name; import com.threerings.presents.dobj.DObject; +import com.threerings.presents.dobj.DObjectManager; import com.threerings.presents.dobj.DSet; import com.threerings.presents.dobj.OidList; import com.threerings.presents.dobj.ServerMessageEvent; @@ -35,10 +36,9 @@ import com.threerings.crowd.chat.data.SpeakMarshaller; import com.threerings.crowd.chat.data.SpeakObject; /** - * A distributed object that contains information on a place that is - * occupied by bodies. This place might be a chat room, a game room, an - * island in a massively multiplayer piratical universe, anything that has - * occupants that might want to chat with one another. + * A distributed object that contains information on a place that is occupied by bodies. This place + * might be a chat room, a game room, an island in a massively multiplayer piratical universe, + * anything that has occupants that might want to chat with one another. */ public class PlaceObject extends DObject implements SpeakObject @@ -55,37 +55,42 @@ public class PlaceObject extends DObject // AUTO-GENERATED: FIELDS END /** - * Exists solely to make calls into the manager look sensible: + * Exists to make calls into the manager look sensible: + * *
_plobj.manager.invoke("someMethod", args);
+ * + * and to route events through the right distributed object manager if we are running in + * standalone/single-player mode where both client and server are running in the same VM. */ public class ManagerCaller { public void invoke (String method, Object ... args) { - postEvent(new ServerMessageEvent(_oid, method, args)); + _omgr.postEvent(new ServerMessageEvent(_oid, method, args)); } + protected ManagerCaller (DObjectManager omgr) { + _omgr = omgr; + } + protected DObjectManager _omgr; } /** * Allows the client to call methods on the manager. */ - public transient ManagerCaller manager = new ManagerCaller(); + public transient ManagerCaller manager; /** - * Tracks the oid of the body objects of all of the occupants of this - * place. + * Tracks the oid of the body objects of all of the occupants of this place. */ public OidList occupants = new OidList(); /** - * Contains an info record (of type {@link OccupantInfo}) for each - * occupant that contains information about that occupant that needs - * to be known by everyone in the place. Note: Don't obtain - * occupant info records directly from this set when on the server, + * Contains an info record (of type {@link OccupantInfo}) for each occupant that contains + * information about that occupant that needs to be known by everyone in the place. + * Note: Don't obtain occupant info records directly from this set when on the server, * use PlaceManager.getOccupantInfo() instead (along with - * PlaceManager.updateOccupantInfo()) because it does - * some special processing to ensure that readers and updaters don't - * step on one another even if they make rapid fire changes to a - * user's occupant info. + * PlaceManager.updateOccupantInfo()) because it does some special processing to + * ensure that readers and updaters don't step on one another even if they make rapid fire + * changes to a user's occupant info. */ public DSet occupantInfo = new DSet(); @@ -93,8 +98,16 @@ public class PlaceObject extends DObject public SpeakMarshaller speakService; /** - * Used to indicate whether broadcast chat messages should be dispatched - * on this place object. + * Called on the client when the location director receives this place object to configure our + * manager caller using the client's distributed object manager. + */ + public void initManagerCaller (DObjectManager omgr) + { + manager = new ManagerCaller(omgr); + } + + /** + * Used to indicate whether broadcast chat messages should be dispatched on this place object. */ public boolean shouldBroadcast () { @@ -104,8 +117,8 @@ public class PlaceObject extends DObject /** * Looks up a user's occupant info by name. * - * @return the occupant info record for the named user or null if no - * user in the room has that username. + * @return the occupant info record for the named user or null if no user in the room has that + * username. */ public OccupantInfo getOccupantInfo (Name username) {