diff --git a/src/as/com/threerings/whirled/client/SceneDirector.as b/src/as/com/threerings/whirled/client/SceneDirector.as
index 65e8c465..5b744535 100644
--- a/src/as/com/threerings/whirled/client/SceneDirector.as
+++ b/src/as/com/threerings/whirled/client/SceneDirector.as
@@ -265,6 +265,8 @@ public class SceneDirector extends BasicDirector
// and finally create a display scene instance with the model and the place config
_scene = _fact.createScene(_model, config);
+
+ handlePendingForcedMove();
}
// from interface SceneService_SceneMoveListener
@@ -361,6 +363,8 @@ public class SceneDirector extends BasicDirector
// let our observers know that something has gone horribly awry
_locdir.failedToMoveTo(sceneId, reason);
+
+ handlePendingForcedMove();
}
// from interface LocationObserver
@@ -421,8 +425,16 @@ public class SceneDirector extends BasicDirector
// just finish up what we're doing and assume that the repeated move request was the
// spurious one as it would be in the case of lag causing rapid-fire repeat requests
if (movePending()) {
- log.info("Dropping forced move because we have a move pending",
- "pendId", _pendingData.sceneId, "reqId", sceneId);
+ if (_pendingData.sceneId == sceneId) {
+ log.info("Dropping forced move because we have a move pending",
+ "pendId", _pendingData.sceneId, "reqId", sceneId);
+ } else {
+ log.info("Delaying forced move because we have a move pending",
+ "pendId", _pendingData.sceneId, "reqId", sceneId);
+ addPendingForcedMove(new function() :void {
+ forcedMove(sceneId);
+ });
+ }
return;
}
@@ -488,6 +500,12 @@ public class SceneDirector extends BasicDirector
_sservice = null;
}
+ public function cancelMoveRequest () :void
+ {
+ _pendingData = null;
+ handlePendingForcedMove();
+ }
+
/**
* Issues the scene move request using information from the supplied pending data.
*/
@@ -530,6 +548,18 @@ public class SceneDirector extends BasicDirector
_scene = null;
}
+ public function addPendingForcedMove (move :Function) :void
+ {
+ _pendingForcedMoves.push(move);
+ }
+
+ protected function handlePendingForcedMove () :void
+ {
+ if (!_pendingForcedMoves.length == 0) {
+ _ctx.getClient().callLater(_pendingForcedMoves.pop());
+ }
+ }
+
/**
* Loads a scene from the repository. If the scene is cached, it will be returned from the
* cache instead.
@@ -619,5 +649,8 @@ public class SceneDirector extends BasicDirector
/** Reference to our move handler. */
protected var _moveHandler :SceneDirector_MoveHandler = null;
+
+ /** Forced move actions we should take once we complete the move we're in the middle of. */
+ protected var _pendingForcedMoves :Array = [];
}
}
diff --git a/src/as/com/threerings/whirled/spot/client/SpotSceneDirector.as b/src/as/com/threerings/whirled/spot/client/SpotSceneDirector.as
index 23f84ba8..29b20073 100644
--- a/src/as/com/threerings/whirled/spot/client/SpotSceneDirector.as
+++ b/src/as/com/threerings/whirled/spot/client/SpotSceneDirector.as
@@ -159,7 +159,7 @@ public class SpotSceneDirector extends BasicDirector
// issue a traversePortal request
log.info("Issuing traversePortal(" + sceneId + ", " + dest + ", " + sceneVer + ").");
- _sservice.traversePortal(sceneId, portalId, sceneVer, _scdir);
+ _sservice.traversePortal(sceneId, portalId, sceneVer, new SceneDirectorWrapper(_scdir));
return true;
}
@@ -461,3 +461,44 @@ public class SpotSceneDirector extends BasicDirector
protected var _clobj :DObject;
}
}
+
+import com.threerings.crowd.data.PlaceConfig;
+import com.threerings.whirled.client.SceneDirector;
+import com.threerings.whirled.data.SceneModel;
+import com.threerings.whirled.spot.client.SpotService_SpotSceneMoveListener;
+
+class SceneDirectorWrapper
+ implements SpotService_SpotSceneMoveListener
+{
+ public function SceneDirectorWrapper (scdir :SceneDirector) {
+ _scdir = scdir;
+ }
+
+ public function requestFailed (cause :String) :void {
+ _scdir.requestFailed(cause);
+ }
+
+ public function moveSucceeded (placeId :int, config :PlaceConfig) :void {
+ _scdir.moveSucceeded(placeId, config);
+ }
+
+ public function moveSucceededWithUpdates (
+ placeId :int, config :PlaceConfig, updates :TypedArray) :void{
+ _scdir.moveSucceededWithUpdates(placeId, config, updates);
+ }
+
+ public function moveSucceededWithScene (placeId :int, config :PlaceConfig,
+ model :SceneModel) :void {
+ _scdir.moveSucceededWithScene(placeId, config, model);
+ }
+
+ public function moveRequiresServerSwitch (hostname :String, ports :TypedArray) :void {
+ _scdir.moveRequiresServerSwitch(hostname, ports);
+ }
+
+ public function requestCancelled () :void {
+ _scdir.cancelMoveRequest();
+ }
+
+ protected var _scdir :SceneDirector;
+}
\ No newline at end of file
diff --git a/src/as/com/threerings/whirled/spot/client/SpotService.as b/src/as/com/threerings/whirled/spot/client/SpotService.as
index 19779161..b9c100ae 100644
--- a/src/as/com/threerings/whirled/spot/client/SpotService.as
+++ b/src/as/com/threerings/whirled/spot/client/SpotService.as
@@ -24,7 +24,6 @@ package com.threerings.whirled.spot.client {
import com.threerings.presents.client.Client;
import com.threerings.presents.client.InvocationService;
import com.threerings.presents.client.InvocationService_ConfirmListener;
-import com.threerings.whirled.client.SceneService_SceneMoveListener;
import com.threerings.whirled.spot.data.Location;
/**
@@ -42,6 +41,6 @@ public interface SpotService extends InvocationService
function joinCluster (arg1 :int, arg2 :InvocationService_ConfirmListener) :void;
// from Java interface SpotService
- function traversePortal (arg1 :int, arg2 :int, arg3 :int, arg4 :SceneService_SceneMoveListener) :void;
+ function traversePortal (arg1 :int, arg2 :int, arg3 :int, arg4 :SpotService_SpotSceneMoveListener) :void;
}
}
diff --git a/src/as/com/threerings/whirled/spot/data/SpotMarshaller.as b/src/as/com/threerings/whirled/spot/data/SpotMarshaller.as
index e6f6450e..9f365961 100644
--- a/src/as/com/threerings/whirled/spot/data/SpotMarshaller.as
+++ b/src/as/com/threerings/whirled/spot/data/SpotMarshaller.as
@@ -27,9 +27,8 @@ import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.presents.data.InvocationMarshaller_ConfirmMarshaller;
import com.threerings.util.Byte;
import com.threerings.util.Integer;
-import com.threerings.whirled.client.SceneService_SceneMoveListener;
-import com.threerings.whirled.data.SceneMarshaller_SceneMoveMarshaller;
import com.threerings.whirled.spot.client.SpotService;
+import com.threerings.whirled.spot.client.SpotService_SpotSceneMoveListener;
/**
* Provides the implementation of the SpotService interface
@@ -82,9 +81,9 @@ public class SpotMarshaller extends InvocationMarshaller
public static const TRAVERSE_PORTAL :int = 4;
// from interface SpotService
- public function traversePortal (arg1 :int, arg2 :int, arg3 :int, arg4 :SceneService_SceneMoveListener) :void
+ public function traversePortal (arg1 :int, arg2 :int, arg3 :int, arg4 :SpotService_SpotSceneMoveListener) :void
{
- var listener4 :SceneMarshaller_SceneMoveMarshaller = new SceneMarshaller_SceneMoveMarshaller();
+ var listener4 :SpotMarshaller_SpotSceneMoveMarshaller = new SpotMarshaller_SpotSceneMoveMarshaller();
listener4.listener = arg4;
sendRequest(TRAVERSE_PORTAL, [
Integer.valueOf(arg1), Integer.valueOf(arg2), Integer.valueOf(arg3), listener4
diff --git a/src/as/com/threerings/whirled/zone/client/ZoneDirector.as b/src/as/com/threerings/whirled/zone/client/ZoneDirector.as
index 1a96ad79..1c7ce013 100644
--- a/src/as/com/threerings/whirled/zone/client/ZoneDirector.as
+++ b/src/as/com/threerings/whirled/zone/client/ZoneDirector.as
@@ -232,8 +232,16 @@ public class ZoneDirector extends BasicDirector
// just finish up what we're doing and assume that the repeated move request was the
// spurious one as it would be in the case of lag causing rapid-fire repeat requests
if (_scdir.movePending()) {
- log.info("Dropping forced move because we have a move pending",
- "pend", _scdir.getPendingModel(), "rzId", zoneId, "rsId", sceneId);
+ if (_scdir.getPendingSceneId() == sceneId) {
+ log.info("Dropping forced move because we have a move pending",
+ "pend", _scdir.getPendingModel(), "rzId", zoneId, "rsId", sceneId);
+ } else {
+ log.info("Delaying forced move because we have a move pending",
+ "pend", _scdir.getPendingModel(), "rzId", zoneId, "rsId", sceneId);
+ _scdir.addPendingForcedMove(new function() :void {
+ forcedMove(zoneId, sceneId);
+ });
+ }
return;
}
diff --git a/src/java/com/threerings/whirled/client/SceneDirector.java b/src/java/com/threerings/whirled/client/SceneDirector.java
index ef5a66ab..f952c2e4 100644
--- a/src/java/com/threerings/whirled/client/SceneDirector.java
+++ b/src/java/com/threerings/whirled/client/SceneDirector.java
@@ -21,10 +21,13 @@
package com.threerings.whirled.client;
+import java.util.ArrayList;
import java.util.Map;
import java.io.IOException;
+import com.google.common.collect.Lists;
+
import com.samskivert.util.LRUHashMap;
import com.samskivert.util.ResultListener;
import com.threerings.presents.client.BasicDirector;
@@ -248,6 +251,8 @@ public class SceneDirector extends BasicDirector
// and finally create a display scene instance with the model and the place config
_scene = _fact.createScene(_model, config);
+
+ handlePendingForcedMove();
}
// from interface SceneService.SceneMoveListener
@@ -377,14 +382,24 @@ public class SceneDirector extends BasicDirector
}
// from interface SceneReceiver
- public void forcedMove (int sceneId)
+ public void forcedMove (final int sceneId)
{
// if we're in the middle of a move, we can't abort it or we will screw everything up, so
// just finish up what we're doing and assume that the repeated move request was the
// spurious one as it would be in the case of lag causing rapid-fire repeat requests
if (movePending()) {
- log.info("Dropping forced move because we have a move pending",
- "pendId", _pendingSceneId, "reqId", sceneId);
+ if (_pendingSceneId == sceneId) {
+ log.info("Dropping forced move because we have a move pending",
+ "pendId", _pendingSceneId, "reqId", sceneId);
+ } else {
+ log.info("Delaying forced move because we have a move pending",
+ "pendId", _pendingSceneId, "reqId", sceneId);
+ addPendingForcedMove(new Runnable() {
+ public void run () {
+ forcedMove(sceneId);
+ }
+ });
+ }
return;
}
@@ -420,6 +435,8 @@ public class SceneDirector extends BasicDirector
moveTo(_previousSceneId);
}
}
+
+ handlePendingForcedMove();
}
protected void sendMoveRequest ()
@@ -502,10 +519,18 @@ public class SceneDirector extends BasicDirector
_scache.clear();
_pendingSceneId = -1;
_pendingModel = null;
+ _pendingForcedMoves.clear();
_previousSceneId = -1;
_sservice = null;
}
+ public void cancelMoveRequest ()
+ {
+ _pendingSceneId = -1;
+ _pendingModel = null;
+ handlePendingForcedMove();
+ }
+
@Override
protected void registerServices (Client client)
{
@@ -519,6 +544,18 @@ public class SceneDirector extends BasicDirector
_sservice = client.requireService(SceneService.class);
}
+ public void addPendingForcedMove (Runnable move)
+ {
+ _pendingForcedMoves.add(move);
+ }
+
+ protected void handlePendingForcedMove ()
+ {
+ if (!_pendingForcedMoves.isEmpty()) {
+ _ctx.getClient().getRunQueue().postRunnable(_pendingForcedMoves.remove(0));
+ }
+ }
+
/** Access to general client services. */
protected WhirledContext _ctx;
@@ -558,4 +595,8 @@ public class SceneDirector extends BasicDirector
/** Reference to our move handler. */
protected MoveHandler _moveHandler = null;
+
+ /** Forced move actions we should take once we complete the move we're in the middle of. */
+ protected ArrayList _pendingForcedMoves = Lists.newArrayList();
+
}
diff --git a/src/java/com/threerings/whirled/spot/client/SpotSceneDirector.java b/src/java/com/threerings/whirled/spot/client/SpotSceneDirector.java
index 7c8da3bc..a4360a6c 100644
--- a/src/java/com/threerings/whirled/spot/client/SpotSceneDirector.java
+++ b/src/java/com/threerings/whirled/spot/client/SpotSceneDirector.java
@@ -43,6 +43,7 @@ import com.threerings.crowd.data.PlaceObject;
import com.threerings.whirled.client.SceneDirector;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.data.ScenePlace;
+import com.threerings.whirled.data.SceneUpdate;
import com.threerings.whirled.spot.data.ClusteredBodyObject;
import com.threerings.whirled.spot.data.Location;
import com.threerings.whirled.spot.data.Portal;
@@ -161,7 +162,34 @@ public class SpotSceneDirector extends BasicDirector
// issue a traversePortal request
log.info("Issuing traversePortal(" + sceneId + ", " + dest + ", " + sceneVer + ").");
- _sservice.traversePortal(_ctx.getClient(), sceneId, portalId, sceneVer, _scdir);
+ _sservice.traversePortal(_ctx.getClient(), sceneId, portalId, sceneVer,
+ new SpotService.SpotSceneMoveListener() {
+ public void requestFailed (String cause) {
+ _scdir.requestFailed(cause);
+ }
+
+ public void moveSucceeded (int placeId, PlaceConfig config) {
+ _scdir.moveSucceeded(placeId, config);
+ }
+
+ public void moveSucceededWithUpdates (
+ int placeId, PlaceConfig config, SceneUpdate[] updates) {
+ _scdir.moveSucceededWithUpdates(placeId, config, updates);
+ }
+
+ public void moveSucceededWithScene (int placeId, PlaceConfig config,
+ SceneModel model) {
+ _scdir.moveSucceededWithScene(placeId, config, model);
+ }
+
+ public void moveRequiresServerSwitch (String hostname, int[] ports) {
+ _scdir.moveRequiresServerSwitch(hostname, ports);
+ }
+
+ public void requestCancelled () {
+ _scdir.cancelMoveRequest();
+ }
+ });
return true;
}
diff --git a/src/java/com/threerings/whirled/spot/client/SpotService.java b/src/java/com/threerings/whirled/spot/client/SpotService.java
index dc1818f3..3e35fd9d 100644
--- a/src/java/com/threerings/whirled/spot/client/SpotService.java
+++ b/src/java/com/threerings/whirled/spot/client/SpotService.java
@@ -35,6 +35,17 @@ import com.threerings.whirled.spot.data.Location;
*/
public interface SpotService extends InvocationService
{
+ /**
+ * Used to communicate the response to a {@link SceneService#moveTo} request.
+ */
+ public static interface SpotSceneMoveListener extends SceneMoveListener
+ {
+ /**
+ * The request is not going through because it was cancelled due to some other action.
+ */
+ public void requestCancelled ();
+ }
+
/**
* Requests to traverse the specified portal.
*
@@ -46,7 +57,7 @@ public interface SpotService extends InvocationService
*/
public void traversePortal (
Client client, int sceneId, int portalId, int destSceneVer,
- SceneMoveListener listener);
+ SpotSceneMoveListener listener);
/**
* Requests that this client's body be made to move to the specified
diff --git a/src/java/com/threerings/whirled/spot/data/SpotMarshaller.java b/src/java/com/threerings/whirled/spot/data/SpotMarshaller.java
index 49a4d6d1..aa107ea7 100644
--- a/src/java/com/threerings/whirled/spot/data/SpotMarshaller.java
+++ b/src/java/com/threerings/whirled/spot/data/SpotMarshaller.java
@@ -23,11 +23,13 @@ package com.threerings.whirled.spot.data;
import javax.annotation.Generated;
+import com.threerings.crowd.data.PlaceConfig;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.InvocationService;
import com.threerings.presents.data.InvocationMarshaller;
-import com.threerings.whirled.client.SceneService;
-import com.threerings.whirled.data.SceneMarshaller;
+import com.threerings.presents.dobj.InvocationResponseEvent;
+import com.threerings.whirled.data.SceneModel;
+import com.threerings.whirled.data.SceneUpdate;
import com.threerings.whirled.spot.client.SpotService;
/**
@@ -42,6 +44,113 @@ import com.threerings.whirled.spot.client.SpotService;
public class SpotMarshaller extends InvocationMarshaller
implements SpotService
{
+ /**
+ * Marshalls results to implementations of {@link SpotService.SpotSceneMoveListener}.
+ */
+ public static class SpotSceneMoveMarshaller extends ListenerMarshaller
+ implements SpotSceneMoveListener
+ {
+ /** The method id used to dispatch {@link #moveRequiresServerSwitch}
+ * responses. */
+ public static final int MOVE_REQUIRES_SERVER_SWITCH = 1;
+
+ // from interface SpotSceneMoveMarshaller
+ public void moveRequiresServerSwitch (String arg1, int[] arg2)
+ {
+ _invId = null;
+ omgr.postEvent(new InvocationResponseEvent(
+ callerOid, requestId, MOVE_REQUIRES_SERVER_SWITCH,
+ new Object[] { arg1, arg2 }, transport));
+ }
+
+ /** The method id used to dispatch {@link #moveSucceeded}
+ * responses. */
+ public static final int MOVE_SUCCEEDED = 2;
+
+ // from interface SpotSceneMoveMarshaller
+ public void moveSucceeded (int arg1, PlaceConfig arg2)
+ {
+ _invId = null;
+ omgr.postEvent(new InvocationResponseEvent(
+ callerOid, requestId, MOVE_SUCCEEDED,
+ new Object[] { Integer.valueOf(arg1), arg2 }, transport));
+ }
+
+ /** The method id used to dispatch {@link #moveSucceededWithScene}
+ * responses. */
+ public static final int MOVE_SUCCEEDED_WITH_SCENE = 3;
+
+ // from interface SpotSceneMoveMarshaller
+ public void moveSucceededWithScene (int arg1, PlaceConfig arg2, SceneModel arg3)
+ {
+ _invId = null;
+ omgr.postEvent(new InvocationResponseEvent(
+ callerOid, requestId, MOVE_SUCCEEDED_WITH_SCENE,
+ new Object[] { Integer.valueOf(arg1), arg2, arg3 }, transport));
+ }
+
+ /** The method id used to dispatch {@link #moveSucceededWithUpdates}
+ * responses. */
+ public static final int MOVE_SUCCEEDED_WITH_UPDATES = 4;
+
+ // from interface SpotSceneMoveMarshaller
+ public void moveSucceededWithUpdates (int arg1, PlaceConfig arg2, SceneUpdate[] arg3)
+ {
+ _invId = null;
+ omgr.postEvent(new InvocationResponseEvent(
+ callerOid, requestId, MOVE_SUCCEEDED_WITH_UPDATES,
+ new Object[] { Integer.valueOf(arg1), arg2, arg3 }, transport));
+ }
+
+ /** The method id used to dispatch {@link #requestCancelled}
+ * responses. */
+ public static final int REQUEST_CANCELLED = 5;
+
+ // from interface SpotSceneMoveMarshaller
+ public void requestCancelled ()
+ {
+ _invId = null;
+ omgr.postEvent(new InvocationResponseEvent(
+ callerOid, requestId, REQUEST_CANCELLED,
+ new Object[] { }, transport));
+ }
+
+ @Override // from InvocationMarshaller
+ public void dispatchResponse (int methodId, Object[] args)
+ {
+ switch (methodId) {
+ case MOVE_REQUIRES_SERVER_SWITCH:
+ ((SpotSceneMoveListener)listener).moveRequiresServerSwitch(
+ (String)args[0], (int[])args[1]);
+ return;
+
+ case MOVE_SUCCEEDED:
+ ((SpotSceneMoveListener)listener).moveSucceeded(
+ ((Integer)args[0]).intValue(), (PlaceConfig)args[1]);
+ return;
+
+ case MOVE_SUCCEEDED_WITH_SCENE:
+ ((SpotSceneMoveListener)listener).moveSucceededWithScene(
+ ((Integer)args[0]).intValue(), (PlaceConfig)args[1], (SceneModel)args[2]);
+ return;
+
+ case MOVE_SUCCEEDED_WITH_UPDATES:
+ ((SpotSceneMoveListener)listener).moveSucceededWithUpdates(
+ ((Integer)args[0]).intValue(), (PlaceConfig)args[1], (SceneUpdate[])args[2]);
+ return;
+
+ case REQUEST_CANCELLED:
+ ((SpotSceneMoveListener)listener).requestCancelled(
+ );
+ return;
+
+ default:
+ super.dispatchResponse(methodId, args);
+ return;
+ }
+ }
+ }
+
/** The method id used to dispatch {@link #changeLocation} requests. */
public static final int CHANGE_LOCATION = 1;
@@ -83,9 +192,9 @@ public class SpotMarshaller extends InvocationMarshaller
public static final int TRAVERSE_PORTAL = 4;
// from interface SpotService
- public void traversePortal (Client arg1, int arg2, int arg3, int arg4, SceneService.SceneMoveListener arg5)
+ public void traversePortal (Client arg1, int arg2, int arg3, int arg4, SpotService.SpotSceneMoveListener arg5)
{
- SceneMarshaller.SceneMoveMarshaller listener5 = new SceneMarshaller.SceneMoveMarshaller();
+ SpotMarshaller.SpotSceneMoveMarshaller listener5 = new SpotMarshaller.SpotSceneMoveMarshaller();
listener5.listener = arg5;
sendRequest(arg1, TRAVERSE_PORTAL, new Object[] {
Integer.valueOf(arg2), Integer.valueOf(arg3), Integer.valueOf(arg4), listener5
diff --git a/src/java/com/threerings/whirled/spot/server/SpotDispatcher.java b/src/java/com/threerings/whirled/spot/server/SpotDispatcher.java
index 2d95bc3d..65224be8 100644
--- a/src/java/com/threerings/whirled/spot/server/SpotDispatcher.java
+++ b/src/java/com/threerings/whirled/spot/server/SpotDispatcher.java
@@ -27,7 +27,7 @@ import com.threerings.presents.client.InvocationService;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationDispatcher;
import com.threerings.presents.server.InvocationException;
-import com.threerings.whirled.client.SceneService;
+import com.threerings.whirled.spot.client.SpotService;
import com.threerings.whirled.spot.data.Location;
import com.threerings.whirled.spot.data.SpotMarshaller;
@@ -79,7 +79,7 @@ public class SpotDispatcher extends InvocationDispatcher
case SpotMarshaller.TRAVERSE_PORTAL:
((SpotProvider)provider).traversePortal(
- source, ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue(), (SceneService.SceneMoveListener)args[3]
+ source, ((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue(), (SpotService.SpotSceneMoveListener)args[3]
);
return;
diff --git a/src/java/com/threerings/whirled/spot/server/SpotProvider.java b/src/java/com/threerings/whirled/spot/server/SpotProvider.java
index aed35e27..afd801a7 100644
--- a/src/java/com/threerings/whirled/spot/server/SpotProvider.java
+++ b/src/java/com/threerings/whirled/spot/server/SpotProvider.java
@@ -27,7 +27,6 @@ import com.threerings.presents.client.InvocationService;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationException;
import com.threerings.presents.server.InvocationProvider;
-import com.threerings.whirled.client.SceneService;
import com.threerings.whirled.spot.client.SpotService;
import com.threerings.whirled.spot.data.Location;
@@ -58,6 +57,6 @@ public interface SpotProvider extends InvocationProvider
/**
* Handles a {@link SpotService#traversePortal} request.
*/
- void traversePortal (ClientObject caller, int arg1, int arg2, int arg3, SceneService.SceneMoveListener arg4)
+ void traversePortal (ClientObject caller, int arg1, int arg2, int arg3, SpotService.SpotSceneMoveListener arg4)
throws InvocationException;
}
diff --git a/src/java/com/threerings/whirled/spot/server/SpotSceneRegistry.java b/src/java/com/threerings/whirled/spot/server/SpotSceneRegistry.java
index 2358c0b1..a52d61a1 100644
--- a/src/java/com/threerings/whirled/spot/server/SpotSceneRegistry.java
+++ b/src/java/com/threerings/whirled/spot/server/SpotSceneRegistry.java
@@ -115,7 +115,7 @@ public class SpotSceneRegistry extends SceneRegistry
// from interface SpotProvider
public void traversePortal (ClientObject caller, int sceneId, int portalId,
- int destSceneVer, SceneService.SceneMoveListener listener)
+ int destSceneVer, SpotService.SpotSceneMoveListener listener)
throws InvocationException
{
// le sanity check
@@ -125,7 +125,7 @@ public class SpotSceneRegistry extends SceneRegistry
log.info("Ignoring stale traverse portal request [caller=" + caller.who() +
", oSceneId=" + sceneId + ", portalId=" + portalId +
", cSceneId=" + cSceneId + "].");
- InvocationMarshaller.setNoResponse(listener);
+ listener.requestCancelled();
return;
}
diff --git a/src/java/com/threerings/whirled/zone/client/ZoneDirector.java b/src/java/com/threerings/whirled/zone/client/ZoneDirector.java
index 3693e317..c0f13b85 100644
--- a/src/java/com/threerings/whirled/zone/client/ZoneDirector.java
+++ b/src/java/com/threerings/whirled/zone/client/ZoneDirector.java
@@ -253,14 +253,26 @@ public class ZoneDirector extends BasicDirector
}
// documentation inherited from interface
- public void forcedMove (int zoneId, int sceneId)
+ public void forcedMove (final int zoneId, final int sceneId)
{
// if we're in the middle of a move, we can't abort it or we will screw everything up, so
// just finish up what we're doing and assume that the repeated move request was the
// spurious one as it would be in the case of lag causing rapid-fire repeat requests
if (_scdir.movePending()) {
- log.info("Dropping forced move because we have a move pending",
- "pend", _scdir.getPendingModel(), "rzId", zoneId, "rsId", sceneId);
+ if (_scdir.getPendingSceneId() == sceneId) {
+ log.info("Dropping forced move because we have a move pending",
+ "pend", _scdir.getPendingModel(), "rzId", zoneId, "rsId", sceneId);
+ } else {
+ log.info("Delaying forced move because we have a move pending",
+ "pend", _scdir.getPendingModel(), "rzId", zoneId, "rsId", sceneId);
+ // We have a move pending to a DIFFERENT scene - we'll do this as soon as that's
+ // done.
+ _scdir.addPendingForcedMove(new Runnable() {
+ public void run () {
+ forcedMove(zoneId, sceneId);
+ }
+ });
+ }
return;
}