diff --git a/src/as/com/threerings/whirled/client/SceneDirector.as b/src/as/com/threerings/whirled/client/SceneDirector.as index 0a1074a2..6ff421a4 100644 --- a/src/as/com/threerings/whirled/client/SceneDirector.as +++ b/src/as/com/threerings/whirled/client/SceneDirector.as @@ -32,6 +32,7 @@ import com.threerings.io.TypedArray; import com.threerings.presents.client.BasicDirector; import com.threerings.presents.client.Client; import com.threerings.presents.client.ClientEvent; +import com.threerings.presents.client.ConfirmAdapter; import com.threerings.presents.data.InvocationCodes; import com.threerings.crowd.client.LocationDirector; @@ -138,16 +139,8 @@ public class SceneDirector extends BasicDirector return false; } - // check the version of our cached copy of the scene to which we're requesting to move; if - // we were unable to load it, assume a cached version of zero - var sceneVers :int = 0; - if (_pendingModel != null) { - sceneVers = _pendingModel.version; - } - - // issue a moveTo request - log.info("Issuing moveTo(" + sceneId + ", " + sceneVers + ")."); - _sservice.moveTo(_wctx.getClient(), sceneId, sceneVers, this); + // do the deed + sendMoveRequest(); return true; } @@ -201,7 +194,7 @@ public class SceneDirector extends BasicDirector return _pendingModel; } - // documentation inherited from interface SceneService_SceneMoveListener + // from interface SceneService_SceneMoveListener public function moveSucceeded (placeId :int, config :PlaceConfig) :void { // our move request was successful, deal with subscribing to our new place object @@ -234,9 +227,9 @@ public class SceneDirector extends BasicDirector _scene = _fact.createScene(_model, config); } - // documentation inherited from interface SceneService_SceneMoveListener + // from interface SceneService_SceneMoveListener public function moveSucceededWithUpdates ( - placeId :int, config :PlaceConfig, updates :Array) :void + placeId :int, config :PlaceConfig, updates :TypedArray) :void { log.info("Got updates [placeId=" + placeId + ", config=" + config + ", updates=" + updates + "]."); @@ -289,7 +282,7 @@ public class SceneDirector extends BasicDirector moveSucceeded(placeId, config); } - // documentation inherited from interface SceneService-SceneMoveListener + // from interface SceneService_SceneMoveListener public function moveSucceededWithScene ( placeId :int, config :PlaceConfig, model :SceneModel) :void { @@ -306,6 +299,21 @@ public class SceneDirector extends BasicDirector moveSucceeded(placeId, config); } + // from interface SceneService_SceneMoveListener + public function moveRequiresServerSwitch (hostname :String, ports :TypedArray) :void + { + // ship on over to the other server + _wctx.getClient().moveToServer(hostname, ports, new ConfirmAdapter( + function (reason :String) :void { // failed + requestFailed(reason); + }, + function () :void { // succeeded + // resend our move request now that we're connected to the new server + sendMoveRequest(); + } + )); + } + // documentation inherited from interface public function requestFailed (reason :String) :void { @@ -391,6 +399,20 @@ public class SceneDirector extends BasicDirector } } + protected function sendMoveRequest () :void + { + // check the version of our cached copy of the scene to which we're requesting to move; if + // we were unable to load it, assume a cached version of zero + var sceneVers :int = 0; + if (_pendingModel != null) { + sceneVers = _pendingModel.version; + } + + // issue a moveTo request + log.info("Issuing moveTo(" + _pendingSceneId + ", " + sceneVers + ")."); + _sservice.moveTo(_wctx.getClient(), _pendingSceneId, sceneVers, this); + } + /** * Clears out our current scene information and releases the scene model for the loaded scene * back to the cache. diff --git a/src/as/com/threerings/whirled/client/SceneService.as b/src/as/com/threerings/whirled/client/SceneService.as index 195c3a98..ff79de19 100644 --- a/src/as/com/threerings/whirled/client/SceneService.as +++ b/src/as/com/threerings/whirled/client/SceneService.as @@ -22,6 +22,7 @@ package com.threerings.whirled.client { import flash.utils.ByteArray; +import com.threerings.io.TypedArray; import com.threerings.crowd.data.PlaceConfig; import com.threerings.presents.client.Client; import com.threerings.presents.client.InvocationService; diff --git a/src/as/com/threerings/whirled/client/SceneService_SceneMoveListener.as b/src/as/com/threerings/whirled/client/SceneService_SceneMoveListener.as index e5995a4d..53de960d 100644 --- a/src/as/com/threerings/whirled/client/SceneService_SceneMoveListener.as +++ b/src/as/com/threerings/whirled/client/SceneService_SceneMoveListener.as @@ -23,6 +23,7 @@ package com.threerings.whirled.client { import flash.utils.ByteArray; import com.threerings.util.*; // for Float, Integer, etc. +import com.threerings.io.TypedArray; import com.threerings.crowd.data.PlaceConfig; import com.threerings.presents.client.Client; @@ -39,6 +40,9 @@ import com.threerings.whirled.data.SceneUpdate; public interface SceneService_SceneMoveListener extends InvocationService_InvocationListener { + // from Java SceneService_SceneMoveListener + function moveRequiresServerSwitch (arg1 :String, arg2 :TypedArray /* of int */) :void + // from Java SceneService_SceneMoveListener function moveSucceeded (arg1 :int, arg2 :PlaceConfig) :void @@ -46,6 +50,6 @@ public interface SceneService_SceneMoveListener function moveSucceededWithScene (arg1 :int, arg2 :PlaceConfig, arg3 :SceneModel) :void // from Java SceneService_SceneMoveListener - function moveSucceededWithUpdates (arg1 :int, arg2 :PlaceConfig, arg3 :Array) :void + function moveSucceededWithUpdates (arg1 :int, arg2 :PlaceConfig, arg3 :TypedArray /* of class com.threerings.whirled.data.SceneUpdate */) :void } } diff --git a/src/as/com/threerings/whirled/data/SceneMarshaller.as b/src/as/com/threerings/whirled/data/SceneMarshaller.as index 13150c2c..691542bb 100644 --- a/src/as/com/threerings/whirled/data/SceneMarshaller.as +++ b/src/as/com/threerings/whirled/data/SceneMarshaller.as @@ -23,6 +23,7 @@ package com.threerings.whirled.data { import flash.utils.ByteArray; import com.threerings.util.*; // for Float, Integer, etc. +import com.threerings.io.TypedArray; import com.threerings.crowd.data.PlaceConfig; import com.threerings.presents.client.Client; diff --git a/src/as/com/threerings/whirled/data/SceneMarshaller_SceneMoveMarshaller.as b/src/as/com/threerings/whirled/data/SceneMarshaller_SceneMoveMarshaller.as index eff9319e..4ee992f0 100644 --- a/src/as/com/threerings/whirled/data/SceneMarshaller_SceneMoveMarshaller.as +++ b/src/as/com/threerings/whirled/data/SceneMarshaller_SceneMoveMarshaller.as @@ -23,6 +23,7 @@ package com.threerings.whirled.data { import flash.utils.ByteArray; import com.threerings.util.*; // for Float, Integer, etc. +import com.threerings.io.TypedArray; import com.threerings.crowd.data.PlaceConfig; import com.threerings.presents.client.Client; @@ -38,19 +39,27 @@ import com.threerings.whirled.data.SceneUpdate; public class SceneMarshaller_SceneMoveMarshaller extends InvocationMarshaller_ListenerMarshaller { + /** The method id used to dispatch {@link #moveRequiresServerSwitch} responses. */ + public static const MOVE_REQUIRES_SERVER_SWITCH :int = 1; + /** The method id used to dispatch {@link #moveSucceeded} responses. */ - public static const MOVE_SUCCEEDED :int = 1; + public static const MOVE_SUCCEEDED :int = 2; /** The method id used to dispatch {@link #moveSucceededWithScene} responses. */ - public static const MOVE_SUCCEEDED_WITH_SCENE :int = 2; + public static const MOVE_SUCCEEDED_WITH_SCENE :int = 3; /** The method id used to dispatch {@link #moveSucceededWithUpdates} responses. */ - public static const MOVE_SUCCEEDED_WITH_UPDATES :int = 3; + public static const MOVE_SUCCEEDED_WITH_UPDATES :int = 4; // from InvocationMarshaller_ListenerMarshaller override public function dispatchResponse (methodId :int, args :Array) :void { switch (methodId) { + case MOVE_REQUIRES_SERVER_SWITCH: + (listener as SceneService_SceneMoveListener).moveRequiresServerSwitch( + (args[0] as String), (args[1] as TypedArray /* of int */)); + return; + case MOVE_SUCCEEDED: (listener as SceneService_SceneMoveListener).moveSucceeded( (args[0] as int), (args[1] as PlaceConfig)); @@ -63,7 +72,7 @@ public class SceneMarshaller_SceneMoveMarshaller case MOVE_SUCCEEDED_WITH_UPDATES: (listener as SceneService_SceneMoveListener).moveSucceededWithUpdates( - (args[0] as int), (args[1] as PlaceConfig), (args[2] as Array)); + (args[0] as int), (args[1] as PlaceConfig), (args[2] as TypedArray /* of class com.threerings.whirled.data.SceneUpdate */)); return; default: diff --git a/src/java/com/threerings/whirled/client/SceneDirector.java b/src/java/com/threerings/whirled/client/SceneDirector.java index 125962b6..31a58d54 100644 --- a/src/java/com/threerings/whirled/client/SceneDirector.java +++ b/src/java/com/threerings/whirled/client/SceneDirector.java @@ -45,15 +45,13 @@ import com.threerings.whirled.util.WhirledContext; import com.threerings.whirled.data.SceneUpdate; /** - * The scene director is the client's interface to all things scene - * related. It interfaces with the scene repository to ensure that scene - * objects are available when the client enters a particular scene. It - * handles moving from scene to scene (it coordinates with the {@link - * LocationDirector} in order to do this). + * The scene director is the client's interface to all things scene related. It interfaces with the + * scene repository to ensure that scene objects are available when the client enters a particular + * scene. It handles moving from scene to scene (it coordinates with the {@link LocationDirector} + * in order to do this). * - *

Note that when the scene director is in use instead of the location - * director, scene ids instead of place oids will be supplied to {@link - * LocationObserver#locationMayChange} and {@link + *

Note that when the scene director is in use instead of the location director, scene ids + * instead of place oids will be supplied to {@link LocationObserver#locationMayChange} and {@link * LocationObserver#locationChangeFailed}. */ public class SceneDirector extends BasicDirector @@ -66,8 +64,8 @@ public class SceneDirector extends BasicDirector public static interface MoveHandler { /** - * Should instruct the client to move the last known working - * location (as well as clean up after the failed moveTo request). + * Should instruct the client to move the last known working location (as well as clean up + * after the failed moveTo request). */ public void recoverMoveTo (int sceneId); } @@ -76,18 +74,16 @@ public class SceneDirector extends BasicDirector * Creates a new scene director with the specified context. * * @param ctx the active client context. - * @param locdir the location director in use on the client, with - * which the scene director will coordinate when changing location. - * @param screp the entity from which the scene director will load - * scene data from the local client scene storage. This may be null - * when the SceneDirector is constructed, but it should be - * supplied via {@link #setSceneRepository} prior to really using - * this director. - * @param fact the factory that knows which derivation of {@link - * Scene} to create for the current system. + * @param locdir the location director in use on the client, with which the scene director will + * coordinate when changing location. + * @param screp the entity from which the scene director will load scene data from the local + * client scene storage. This may be null when the SceneDirector is constructed, but it should + * be supplied via {@link #setSceneRepository} prior to really using this director. + * @param fact the factory that knows which derivation of {@link Scene} to create for the + * current system. */ - public SceneDirector (WhirledContext ctx, LocationDirector locdir, - SceneRepository screp, SceneFactory fact) + public SceneDirector (WhirledContext ctx, LocationDirector locdir, SceneRepository screp, + SceneFactory fact) { super(ctx); @@ -97,13 +93,12 @@ public class SceneDirector extends BasicDirector setSceneRepository(screp); _fact = fact; - // set ourselves up as a failure handler with the location - // director because we need to do special processing + // set ourselves up as a failure handler with the location director because we need to do + // special processing _locdir.setFailureHandler(this); // register for scene notifications - _ctx.getClient().getInvocationDirector().registerReceiver( - new SceneDecoder(this)); + _ctx.getClient().getInvocationDirector().registerReceiver(new SceneDecoder(this)); } /** @@ -116,8 +111,8 @@ public class SceneDirector extends BasicDirector } /** - * Returns the display scene object associated with the scene we - * currently occupy or null if we currently occupy no scene. + * Returns the display scene object associated with the scene we currently occupy or null if we + * currently occupy no scene. */ public Scene getScene () { @@ -125,13 +120,11 @@ public class SceneDirector extends BasicDirector } /** - * Requests that this client move the specified scene. 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 move the specified scene. 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 sceneId) { @@ -143,8 +136,7 @@ public class SceneDirector extends BasicDirector // sanity-check the destination scene id if (sceneId == _sceneId) { - Log.warning("Refusing request to move to the same scene " + - "[sceneId=" + sceneId + "]."); + Log.warning("Refusing request to move to the same scene [sceneId=" + sceneId + "]."); return false; } @@ -153,56 +145,41 @@ public class SceneDirector extends BasicDirector return false; } - // check the version of our cached copy of the scene to which - // we're requesting to move; if we were unable to load it, assume - // a cached version of zero - int sceneVers = 0; - if (_pendingModel != null) { - sceneVers = _pendingModel.version; - } - - // issue a moveTo request - Log.info("Issuing moveTo(" + sceneId + ", " + sceneVers + ")."); - _sservice.moveTo(_ctx.getClient(), sceneId, sceneVers, this); + // do the deed + sendMoveRequest(); return true; } /** - * Prepares to move to the requested scene. The location observers are - * asked to ratify the move and our pending scene mode is loaded from - * the scene repository. This can be called by cooperating directors - * that need to coopt the moveTo process. + * Prepares to move to the requested scene. The location observers are asked to ratify the move + * and our pending scene mode is loaded from the scene repository. This can be called by + * cooperating directors that need to coopt the moveTo process. */ public boolean prepareMoveTo (int sceneId, ResultListener rl) { - // 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 (!_locdir.mayMoveTo(sceneId, rl)) { 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 = _locdir.checkRepeatMove(); // complain if we're over-writing a pending request if (_pendingSceneId != -1) { if (refuse) { Log.warning("Refusing moveTo; We have a request outstanding " + - "[psid=" + _pendingSceneId + - ", nsid=" + sceneId + "]."); + "[psid=" + _pendingSceneId + ", nsid=" + sceneId + "]."); return false; - } else { - Log.warning("Overriding stale moveTo request " + - "[psid=" + _pendingSceneId + + Log.warning("Overriding stale moveTo request [psid=" + _pendingSceneId + ", nsid=" + sceneId + "]."); } } - // load up the pending scene so that we can communicate it's most - // recent version to the server + // load up the pending scene so that we can communicate it's most recent version to the + // server _pendingModel = loadSceneModel(sceneId); // make a note of our pending scene id @@ -213,27 +190,24 @@ public class SceneDirector extends BasicDirector } /** - * Returns the model loaded in preparation for a scene - * transition. This is made available only for cooperating directors - * which may need to coopt the scene transition process. The pending - * model is only valid immediately following a call to {@link - * #prepareMoveTo}. + * Returns the model loaded in preparation for a scene transition. This is made available only + * for cooperating directors which may need to coopt the scene transition process. The pending + * model is only valid immediately following a call to {@link #prepareMoveTo}. */ public SceneModel getPendingModel () { return _pendingModel; } - // documentation inherited from interface + // from interface SceneService.SceneMoveListener public void moveSucceeded (int placeId, PlaceConfig config) { - // our move request was successful, deal with subscribing to our - // new place object + // our move request was successful, deal with subscribing to our new place object _locdir.didMoveTo(placeId, config); - // since we're committed to moving to the new scene, we'll - // parallelize and go ahead and load up the new scene now rather - // than wait until subscription to our place object succeeds + // since we're committed to moving to the new scene, we'll parallelize and go ahead and + // load up the new scene now rather than wait until subscription to our place object + // succeeds // keep track of our previous scene info _previousSceneId = _sceneId; @@ -250,19 +224,16 @@ public class SceneDirector extends BasicDirector // complain if we didn't find a scene if (_model == null) { - Log.warning("Aiya! Unable to load scene [sid=" + _sceneId + - ", plid=" + placeId + "]."); + Log.warning("Aiya! Unable to load scene [sid=" + _sceneId + ", plid=" + placeId + "]."); return; } - // and finally create a display scene instance with the model and - // the place config + // and finally create a display scene instance with the model and the place config _scene = _fact.createScene(_model, config); } - // documentation inherited from interface - public void moveSucceededWithUpdates ( - int placeId, PlaceConfig config, SceneUpdate[] updates) + // from interface SceneService.SceneMoveListener + public void moveSucceededWithUpdates (int placeId, PlaceConfig config, SceneUpdate[] updates) { Log.info("Got updates [placeId=" + placeId + ", config=" + config + ", updates=" + StringUtil.toString(updates) + "]."); @@ -275,8 +246,7 @@ public class SceneDirector extends BasicDirector updates[ii].validate(model); } catch (IllegalStateException ise) { Log.warning("Scene update failed validation [model=" + model + - ", update=" + updates[ii] + - ", error=" + ise.getMessage() + "]."); + ", update=" + updates[ii] + ", error=" + ise.getMessage() + "]."); failure = true; break; } @@ -302,9 +272,8 @@ public class SceneDirector extends BasicDirector Log.logStackTrace(ioe); } - // act as if the scene move failed, though we'll be in a funny - // state because the server thinks we've changed scenes, but - // the client can try again without its booched scene model + // act as if the scene move failed; we'll be in a funny state because the server thinks + // we've changed scenes, but the client can try again without its booched scene model requestFailed(INTERNAL_ERROR); return; } @@ -316,13 +285,11 @@ public class SceneDirector extends BasicDirector moveSucceeded(placeId, config); } - // documentation inherited from interface - public void moveSucceededWithScene ( - int placeId, PlaceConfig config, SceneModel model) + // from interface SceneService.SceneMoveListener + public void moveSucceededWithScene (int placeId, PlaceConfig config, SceneModel model) { - Log.info("Got updated scene model [placeId=" + placeId + - ", config=" + config + ", scene=" + model.sceneId + "/" + - model.name + "/" + model.version + "]."); + Log.info("Got updated scene model [placeId=" + placeId + ", config=" + config + + ", scene=" + model.sceneId + "/" + model.name + "/" + model.version + "]."); // update the model in the repository persistSceneModel(model); @@ -334,7 +301,22 @@ public class SceneDirector extends BasicDirector moveSucceeded(placeId, config); } - // documentation inherited from interface + // from interface SceneService.SceneMoveListener + public void moveRequiresServerSwitch (String hostname, int[] ports) + { + // ship on over to the other server + _ctx.getClient().moveToServer(hostname, ports, new SceneService.ConfirmListener() { + public void requestProcessed () { + // resend our move request now that we're connected to the new server + sendMoveRequest(); + } + public void requestFailed (String reason) { + SceneDirector.this.requestFailed(reason); + } + }); + } + + // from interface SceneService.SceneMoveListener public void requestFailed (String reason) { // clear out our pending request oid @@ -346,8 +328,7 @@ public class SceneDirector extends BasicDirector } /** - * Called by SceneController instances to tell us about an update - * to the current scene. + * Called by SceneController instances to tell us about an update to the current scene. */ public void updateReceived (SceneUpdate update) { @@ -356,8 +337,7 @@ public class SceneDirector extends BasicDirector } /** - * Called to clean up our place and scene state information when we - * leave a scene. + * Called to clean up our place and scene state information when we leave a scene. */ public void didLeaveScene () { @@ -386,11 +366,10 @@ public class SceneDirector extends BasicDirector public void setMoveHandler (MoveHandler handler) { if (_moveHandler != null) { - Log.warning("Requested to set move handler, but we've " + - "already got one. The conflicting entities will " + - "likely need to perform more sophisticated " + - "coordination to deal with failures. " + - "[old=" + _moveHandler + ", new=" + handler + "]."); + Log.warning("Requested to set move handler, but we've already got one. The " + + "conflicting entities will likely need to perform more sophisticated " + + "coordination to deal with failures. [old=" + _moveHandler + + ", new=" + handler + "]."); } else { _moveHandler = handler; @@ -398,8 +377,7 @@ public class SceneDirector extends BasicDirector } /** - * Called when something breaks down in the process of performing a - * moveTo request. + * Called when something breaks down in the process of performing a {@link #moveTo} request. */ public void recoverFailedMove (int placeId) { @@ -409,22 +387,35 @@ public class SceneDirector extends BasicDirector // clear out our now bogus scene tracking info clearScene(); - // 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 (_previousSceneId != -1 && _previousSceneId != sceneId) { // if we have a move handler use that if (_moveHandler != null) { _moveHandler.recoverMoveTo(_previousSceneId); - } else { moveTo(_previousSceneId); } } } + protected void sendMoveRequest () + { + // check the version of our cached copy of the scene to which we're requesting to move; if + // we were unable to load it, assume a cached version of zero + int sceneVers = 0; + if (_pendingModel != null) { + sceneVers = _pendingModel.version; + } + + // issue a moveTo request + Log.info("Issuing moveTo(" + _pendingSceneId + ", " + sceneVers + ")."); + _sservice.moveTo(_ctx.getClient(), _pendingSceneId, sceneVers, this); + } + /** - * Clears out our current scene information and releases the scene - * model for the loaded scene back to the cache. + * Clears out our current scene information and releases the scene model for the loaded scene + * back to the cache. */ protected void clearScene () { @@ -437,8 +428,8 @@ public class SceneDirector extends BasicDirector } /** - * Loads a scene from the repository. If the scene is cached, it will - * be returned from the cache instead. + * Loads a scene from the repository. If the scene is cached, it will be returned from the + * cache instead. */ protected SceneModel loadSceneModel (int sceneId) { @@ -457,8 +448,7 @@ public class SceneDirector extends BasicDirector } catch (IOException ioe) { // complain first, then return null - Log.warning("Error loading scene [scid=" + sceneId + - ", error=" + ioe + "]."); + Log.warning("Error loading scene [scid=" + sceneId + ", error=" + ioe + "]."); } } @@ -474,9 +464,8 @@ public class SceneDirector extends BasicDirector try { _screp.storeSceneModel(model); } catch (IOException ioe) { - Log.warning("Failed to update repository with updated scene " + - "[sceneId=" + model.sceneId + ", nvers=" + model.version + - "]."); + Log.warning("Failed to update repository with updated scene [sceneId=" + model.sceneId + + ", nvers=" + model.version + "]."); Log.logStackTrace(ioe); } } @@ -535,12 +524,11 @@ public class SceneDirector extends BasicDirector /** The id of the scene we currently occupy. */ protected int _sceneId = -1; - /** Our most recent copy of the scene model for the scene we're about - * to enter. */ + /** Our most recent copy of the scene model for the scene we're about to enter. */ protected SceneModel _pendingModel; - /** The id of the scene for which we have an outstanding moveTo - * request, or -1 if we have no outstanding request. */ + /** The id of the scene for which we have an outstanding moveTo request, or -1 if we have no + * outstanding request. */ protected int _pendingSceneId = -1; /** The id of the scene we previously occupied. */ diff --git a/src/java/com/threerings/whirled/client/SceneService.java b/src/java/com/threerings/whirled/client/SceneService.java index 65eff777..a1221c49 100644 --- a/src/java/com/threerings/whirled/client/SceneService.java +++ b/src/java/com/threerings/whirled/client/SceneService.java @@ -30,8 +30,8 @@ import com.threerings.whirled.data.SceneModel; import com.threerings.whirled.data.SceneUpdate; /** - * The scene service class provides the client interface to the scene - * related invocation services (e.g. moving from scene to scene). + * The scene service class provides the client interface to the scene related invocation services + * (e.g. moving from scene to scene). */ public interface SceneService extends InvocationService { @@ -49,38 +49,39 @@ public interface SceneService extends InvocationService public void moveSucceeded (int placeId, PlaceConfig config); /** - * Indicates that a move succeeded and that the client's cached - * scene information should be updated with the supplied data. + * Indicates that a move succeeded and that the client's cached scene information should be + * updated with the supplied data. * * @param placeId the place object id of the newly occupied scene. * @param config metadata related to the newly occupied scene. - * @param updates updates that must be applied to the client's - * copy of a scene model to bring it up to date. + * @param updates updates that must be applied to the client's copy of a scene model to + * bring it up to date. */ - public void moveSucceededWithUpdates (int placeId, PlaceConfig config, - SceneUpdate[] updates); + public void moveSucceededWithUpdates ( + int placeId, PlaceConfig config, SceneUpdate[] updates); /** - * Indicates that a move succeeded and that the client's cached - * scene information should be updated with the supplied data. + * Indicates that a move succeeded and that the client's cached scene information should be + * updated with the supplied data. * * @param placeId the place object id of the newly occupied scene. * @param config metadata related to the newly occupied scene. - * @param model a fresh copy of the most recent scene data for the - * newly occupied scene. + * @param model a fresh copy of the most recent scene data for the newly occupied scene. */ - public void moveSucceededWithScene (int placeId, PlaceConfig config, - SceneModel model); + public void moveSucceededWithScene (int placeId, PlaceConfig config, SceneModel model); + + /** + * Indicates that the client must switch to the specified server and reissue its move + * request in order to relocate to its desired scene. + */ + public void moveRequiresServerSwitch (String hostname, int[] ports); } /** - * Requests that that this client's body be moved to the specified - * scene. + * Requests that that this client's body be moved to the specified scene. * * @param sceneId the scene id to which we want to move. - * @param version the version number of the scene object that we have - * in our local repository. + * @param version the version number of the scene object that we have in our local repository. */ - public void moveTo (Client client, int sceneId, int version, - SceneMoveListener listener); + public void moveTo (Client client, int sceneId, int version, SceneMoveListener listener); } diff --git a/src/java/com/threerings/whirled/data/SceneMarshaller.java b/src/java/com/threerings/whirled/data/SceneMarshaller.java index 9547ede3..f5920edc 100644 --- a/src/java/com/threerings/whirled/data/SceneMarshaller.java +++ b/src/java/com/threerings/whirled/data/SceneMarshaller.java @@ -45,9 +45,22 @@ public class SceneMarshaller extends InvocationMarshaller public static class SceneMoveMarshaller extends ListenerMarshaller implements SceneMoveListener { + /** The method id used to dispatch {@link #moveRequiresServerSwitch} + * responses. */ + public static final int MOVE_REQUIRES_SERVER_SWITCH = 1; + + // from interface SceneMoveMarshaller + public void moveRequiresServerSwitch (String arg1, int[] arg2) + { + _invId = null; + omgr.postEvent(new InvocationResponseEvent( + callerOid, requestId, MOVE_REQUIRES_SERVER_SWITCH, + new Object[] { arg1, arg2 })); + } + /** The method id used to dispatch {@link #moveSucceeded} * responses. */ - public static final int MOVE_SUCCEEDED = 1; + public static final int MOVE_SUCCEEDED = 2; // from interface SceneMoveMarshaller public void moveSucceeded (int arg1, PlaceConfig arg2) @@ -60,7 +73,7 @@ public class SceneMarshaller extends InvocationMarshaller /** The method id used to dispatch {@link #moveSucceededWithScene} * responses. */ - public static final int MOVE_SUCCEEDED_WITH_SCENE = 2; + public static final int MOVE_SUCCEEDED_WITH_SCENE = 3; // from interface SceneMoveMarshaller public void moveSucceededWithScene (int arg1, PlaceConfig arg2, SceneModel arg3) @@ -73,7 +86,7 @@ public class SceneMarshaller extends InvocationMarshaller /** The method id used to dispatch {@link #moveSucceededWithUpdates} * responses. */ - public static final int MOVE_SUCCEEDED_WITH_UPDATES = 3; + public static final int MOVE_SUCCEEDED_WITH_UPDATES = 4; // from interface SceneMoveMarshaller public void moveSucceededWithUpdates (int arg1, PlaceConfig arg2, SceneUpdate[] arg3) @@ -88,6 +101,11 @@ public class SceneMarshaller extends InvocationMarshaller public void dispatchResponse (int methodId, Object[] args) { switch (methodId) { + case MOVE_REQUIRES_SERVER_SWITCH: + ((SceneMoveListener)listener).moveRequiresServerSwitch( + (String)args[0], (int[])args[1]); + return; + case MOVE_SUCCEEDED: ((SceneMoveListener)listener).moveSucceeded( ((Integer)args[0]).intValue(), (PlaceConfig)args[1]); diff --git a/src/java/com/threerings/whirled/server/WhirledServer.java b/src/java/com/threerings/whirled/server/WhirledServer.java index e2cf850e..8b0cf1f5 100644 --- a/src/java/com/threerings/whirled/server/WhirledServer.java +++ b/src/java/com/threerings/whirled/server/WhirledServer.java @@ -35,8 +35,8 @@ import com.threerings.whirled.server.persist.SceneRepository; import com.threerings.whirled.util.SceneFactory; /** - * The whirled server extends the {@link CrowdServer} and provides access - * to managers and the like that are needed by the Whirled serviecs. + * The Whirled server extends the {@link CrowdServer} and provides access to managers and the like + * that are needed by the Whirled serviecs. */ public abstract class WhirledServer extends CrowdServer { @@ -66,17 +66,25 @@ public abstract class WhirledServer extends CrowdServer _screp = createSceneRepository(); // create our scene registry - screg = new SceneRegistry(invmgr, _screp, createSceneFactory(), - createConfigFactory()); + screg = createSceneRegistry(); Log.info("Whirled server initialized."); } + /** + * Creates the scene registry to be used on this server. + */ + protected SceneRegistry createSceneRegistry () + throws Exception + { + return new SceneRegistry(invmgr, _screp, createSceneFactory(), createConfigFactory()); + } + /** * Creates the scene repository that will be used by this server. * - * @exception Exception thrown if any error occurs while instantiating - * or initializing the scene repository. + * @exception Exception thrown if any error occurs while instantiating or initializing the + * scene repository. */ protected abstract SceneRepository createSceneRepository () throws Exception; @@ -84,18 +92,17 @@ public abstract class WhirledServer extends CrowdServer /** * Creates the scene factory that will be used by our scene registry. * - * @exception Exception thrown if any error occurs while instantiating - * or initializing the scene repository. + * @exception Exception thrown if any error occurs while instantiating or initializing the + * scene repository. */ protected abstract SceneFactory createSceneFactory () throws Exception; /** - * Creates the place config factory that will be used our scene - * registry. + * Creates the place config factory that will be used our scene registry. * - * @exception Exception thrown if any error occurs while instantiating - * or initializing the scene repository. + * @exception Exception thrown if any error occurs while instantiating or initializing the + * scene repository. */ protected abstract SceneRegistry.ConfigFactory createConfigFactory () throws Exception;