Widening.

git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@356 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Michael Bayne
2007-07-13 22:23:39 +00:00
parent a49e2c26f3
commit a33bf1762f
@@ -31,7 +31,6 @@ import com.threerings.presents.data.ClientObject;
import com.threerings.presents.dobj.AttributeChangeListener; import com.threerings.presents.dobj.AttributeChangeListener;
import com.threerings.presents.dobj.AttributeChangedEvent; import com.threerings.presents.dobj.AttributeChangedEvent;
import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.DObjectManager;
import com.threerings.presents.dobj.ObjectAccessException; import com.threerings.presents.dobj.ObjectAccessException;
import com.threerings.presents.dobj.Subscriber; import com.threerings.presents.dobj.Subscriber;
@@ -54,23 +53,20 @@ import com.threerings.whirled.spot.data.SpotCodes;
import com.threerings.whirled.spot.data.SpotScene; import com.threerings.whirled.spot.data.SpotScene;
/** /**
* Extends the standard scene director with facilities to move between * Extends the standard scene director with facilities to move between locations within a scene.
* locations within a scene.
*/ */
public class SpotSceneDirector extends BasicDirector public class SpotSceneDirector extends BasicDirector
implements SpotCodes, Subscriber, AttributeChangeListener implements SpotCodes, Subscriber, AttributeChangeListener
{ {
/** /**
* Creates a new spot scene director with the specified context and * Creates a new spot scene director with the specified context and which will cooperate with
* which will cooperate with the supplied scene director. * the supplied scene director.
* *
* @param ctx the active client context. * @param ctx the active client context.
* @param locdir the location director with which we will be * @param locdir the location director with which we will be cooperating.
* cooperating.
* @param scdir the scene director with which we will be cooperating. * @param scdir the scene director with which we will be cooperating.
*/ */
public SpotSceneDirector (WhirledContext ctx, LocationDirector locdir, public SpotSceneDirector (WhirledContext ctx, LocationDirector locdir, SceneDirector scdir)
SceneDirector scdir)
{ {
super(ctx); super(ctx);
@@ -87,8 +83,8 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Configures this spot scene director with a chat director, with * Configures this spot scene director with a chat director, with which it will coordinate to
* which it will coordinate to implement cluster chatting. * implement cluster chatting.
*/ */
public void setChatDirector (ChatDirector chatdir) public void setChatDirector (ChatDirector chatdir)
{ {
@@ -96,8 +92,8 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Returns our current location unless we have a location change * Returns our current location unless we have a location change pending, in which case our
* pending, in which case our pending location is returned. * pending location is returned.
*/ */
public Location getIntendedLocation () public Location getIntendedLocation ()
{ {
@@ -105,13 +101,12 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Requests that this client move to the location specified by the * Requests that this client move to the location specified by the supplied portal id. A
* supplied portal id. A request will be made and when the response is * request will be made and when the response is received, the location observers will be
* received, the location observers will be notified of success or * notified of success or failure.
* failure.
* *
* @return true if the request was issued, false if it was rejected by * @return true if the request was issued, false if it was rejected by a location observer or
* a location observer or because we have another request outstanding. * because we have another request outstanding.
*/ */
public boolean traversePortal (int portalId) public boolean traversePortal (int portalId)
{ {
@@ -119,52 +114,45 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Requests that this client move to the location specified by the * Requests that this client move to the location specified by the supplied portal id. A
* supplied portal id. A request will be made and when the response is * request will be made and when the response is received, the location observers will be
* received, the location observers will be notified of success or * notified of success or failure.
* failure.
*/ */
public boolean traversePortal (int portalId, ResultListener rl) public boolean traversePortal (int portalId, ResultListener rl)
{ {
// look up the destination scene and location // look up the destination scene and location
SpotScene scene = (SpotScene)_scdir.getScene(); SpotScene scene = (SpotScene)_scdir.getScene();
if (scene == null) { if (scene == null) {
Log.warning("Requested to traverse portal when we have " + Log.warning("Requested to traverse portal when we have no scene " +
"no scene [portalId=" + portalId + "]."); "[portalId=" + portalId + "].");
return false; return false;
} }
// sanity check the server's notion of what scene we're in with // sanity check the server's notion of what scene we're in with our notion of it
// our notion of it
int sceneId = _scdir.getScene().getId(); int sceneId = _scdir.getScene().getId();
ScenedBodyObject sbobj = (ScenedBodyObject) ScenedBodyObject sbobj = (ScenedBodyObject)_ctx.getClient().getClientObject();
_ctx.getClient().getClientObject();
if (sceneId != sbobj.getSceneId()) { if (sceneId != sbobj.getSceneId()) {
Log.warning("Client and server differ in opinion of what scene " + Log.warning("Client and server differ in opinion of what scene we're in " +
"we're in [sSceneId=" + sbobj.getSceneId() + "[sSceneId=" + sbobj.getSceneId() + ", cSceneId=" + sceneId + "].");
", cSceneId=" + sceneId + "].");
return false; return false;
} }
// find the portal they're talking about // find the portal they're talking about
Portal dest = scene.getPortal(portalId); Portal dest = scene.getPortal(portalId);
if (dest == null) { if (dest == null) {
Log.warning("Requested to traverse non-existent portal " + Log.warning("Requested to traverse non-existent portal [portalId=" + portalId +
"[portalId=" + portalId + ", portals=" + ", portals=" + StringUtil.toString(scene.getPortals()) + "].");
StringUtil.toString(scene.getPortals()) + "].");
return false; return false;
} }
// prepare to move to this scene (sets up pending data) // prepare to move to this scene (sets up pending data)
if (!_scdir.prepareMoveTo(dest.targetSceneId, rl)) { if (!_scdir.prepareMoveTo(dest.targetSceneId, rl)) {
Log.info("Portal traversal vetoed by scene director " + Log.info("Portal traversal vetoed by scene director [portalId=" + portalId + "].");
"[portalId=" + portalId + "].");
return false; return false;
} }
// check the version of our cached copy of the scene to which // check the version of our cached copy of the scene to which we're requesting to move; if
// we're requesting to move; if we were unable to load it, assume // we were unable to load it, assume a cached version of zero
// a cached version of zero
int sceneVer = 0; int sceneVer = 0;
SceneModel pendingModel = _scdir.getPendingModel(); SceneModel pendingModel = _scdir.getPendingModel();
if (pendingModel != null) { if (pendingModel != null) {
@@ -172,33 +160,28 @@ public class SpotSceneDirector extends BasicDirector
} }
// issue a traversePortal request // issue a traversePortal request
Log.info("Issuing traversePortal(" + Log.info("Issuing traversePortal(" + sceneId + ", " + dest + ", " + sceneVer + ").");
sceneId + ", " + dest + ", " + sceneVer + ")."); _sservice.traversePortal(_ctx.getClient(), sceneId, portalId, sceneVer, _scdir);
_sservice.traversePortal(
_ctx.getClient(), sceneId, portalId, sceneVer, _scdir);
return true; return true;
} }
/** /**
* Issues a request to change our location within the scene to the * Issues a request to change our location within the scene to the specified location.
* specified location.
* *
* @param loc the new location to which to move. * @param loc the new location to which to move.
* @param listener will be notified of success or failure. Most client * @param listener will be notified of success or failure. Most client entities find out about
* entities find out about location changes via changes to the * location changes via changes to the occupant info data, but the initiator of a location
* occupant info data, but the initiator of a location change request * change request can be notified of its success or failure, primarily so that it can act in
* can be notified of its success or failure, primarily so that it can * anticipation of a successful location change (like by starting a sprite moving toward the
* act in anticipation of a successful location change (like by * new location), but backtrack if it finds out that the location change failed.
* starting a sprite moving toward the new location), but backtrack if
* it finds out that the location change failed.
*/ */
public void changeLocation (Location loc, final ResultListener listener) public void changeLocation (Location loc, final ResultListener listener)
{ {
// refuse if there's a pending location change or if we're already // refuse if there's a pending location change or if we're already at the specified
// at the specified location // location
if (loc.equivalent(_location)) { if (loc.equivalent(_location)) {
Log.info("Not going to " + loc + "; we're at " + _location + Log.info("Not going to " + loc + "; we're at " + _location + " and we're headed to " +
" and we're headed to " + _pendingLoc + "."); _pendingLoc + ".");
if (listener != null) { if (listener != null) {
// This isn't really a failure, it's just a no-op. // This isn't really a failure, it's just a no-op.
listener.requestCompleted(_location); listener.requestCompleted(_location);
@@ -207,8 +190,8 @@ public class SpotSceneDirector extends BasicDirector
} }
if (_pendingLoc != null) { if (_pendingLoc != null) {
Log.info("Not going to " + loc + "; we're at " + _location + Log.info("Not going to " + loc + "; we're at " + _location + " and we're headed to " +
" and we're headed to " + _pendingLoc + "."); _pendingLoc + ".");
if (listener != null) { if (listener != null) {
// Already moving, best thing to do is ignore it. // Already moving, best thing to do is ignore it.
listener.requestCompleted(_pendingLoc); listener.requestCompleted(_pendingLoc);
@@ -218,8 +201,8 @@ public class SpotSceneDirector extends BasicDirector
SpotScene scene = (SpotScene)_scdir.getScene(); SpotScene scene = (SpotScene)_scdir.getScene();
if (scene == null) { if (scene == null) {
Log.warning("Requested to change locations, but we're not " + Log.warning("Requested to change locations, but we're not currently in any scene " +
"currently in any scene [loc=" + loc + "]."); "[loc=" + loc + "].");
if (listener != null) { if (listener != null) {
listener.requestFailed(new Exception("m.cant_get_there")); listener.requestFailed(new Exception("m.cant_get_there"));
} }
@@ -227,8 +210,7 @@ public class SpotSceneDirector extends BasicDirector
} }
int sceneId = _scdir.getScene().getId(); int sceneId = _scdir.getScene().getId();
Log.info("Sending changeLocation request [scid=" + sceneId + Log.info("Sending changeLocation request [scid=" + sceneId + ", loc=" + loc + "].");
", loc=" + loc + "].");
_pendingLoc = (Location)loc.clone(); _pendingLoc = (Location)loc.clone();
ConfirmListener clist = new ConfirmListener() { ConfirmListener clist = new ConfirmListener() {
@@ -251,19 +233,19 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Issues a request to join the cluster associated with the specified * Issues a request to join the cluster associated with the specified user (starting one if
* user (starting one if necessary). * necessary).
* *
* @param froid the bodyOid of another user; the calling user will * @param froid the bodyOid of another user; the calling user will be made to join the target
* be made to join the target user's cluster. * user's cluster.
* @param listener will be notified of success or failure. * @param listener will be notified of success or failure.
*/ */
public void joinCluster (int froid, final ResultListener listener) public void joinCluster (int froid, final ResultListener listener)
{ {
SpotScene scene = (SpotScene)_scdir.getScene(); SpotScene scene = (SpotScene)_scdir.getScene();
if (scene == null) { if (scene == null) {
Log.warning("Requested to join cluster, but we're not " + Log.warning("Requested to join cluster, but we're not currently in any scene " +
"currently in any scene [froid=" + froid + "]."); "[froid=" + froid + "].");
if (listener != null) { if (listener != null) {
listener.requestFailed(new Exception("m.cant_get_there")); listener.requestFailed(new Exception("m.cant_get_there"));
} }
@@ -278,7 +260,6 @@ public class SpotSceneDirector extends BasicDirector
listener.requestCompleted(null); listener.requestCompleted(null);
} }
} }
public void requestFailed (String reason) { public void requestFailed (String reason) {
if (listener != null) { if (listener != null) {
listener.requestFailed(new Exception(reason)); listener.requestFailed(new Exception(reason));
@@ -288,11 +269,11 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Sends a chat message to the other users in the cluster to which the * Sends a chat message to the other users in the cluster to which the location that we
* location that we currently occupy belongs. * currently occupy belongs.
* *
* @return true if a cluster speak message was delivered, false if we * @return true if a cluster speak message was delivered, false if we are not in a valid
* are not in a valid cluster and refused to deliver the request. * cluster and refused to deliver the request.
*/ */
public boolean requestClusterSpeak (String message) public boolean requestClusterSpeak (String message)
{ {
@@ -300,19 +281,19 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Sends a chat message to the other users in the cluster to which the * Sends a chat message to the other users in the cluster to which the location that we
* location that we currently occupy belongs. * currently occupy belongs.
* *
* @return true if a cluster speak message was delivered, false if we * @return true if a cluster speak message was delivered, false if we are not in a valid
* are not in a valid cluster and refused to deliver the request. * cluster and refused to deliver the request.
*/ */
public boolean requestClusterSpeak (String message, byte mode) public boolean requestClusterSpeak (String message, byte mode)
{ {
// make sure we're currently in a scene // make sure we're currently in a scene
SpotScene scene = (SpotScene)_scdir.getScene(); SpotScene scene = (SpotScene)_scdir.getScene();
if (scene == null) { if (scene == null) {
Log.warning("Requested to speak to cluster, but we're not " + Log.warning("Requested to speak to cluster, but we're not currently in any scene " +
"currently in any scene [message=" + message + "]."); "[message=" + message + "].");
return false; return false;
} }
@@ -337,8 +318,8 @@ public class SpotSceneDirector extends BasicDirector
int oid = object.getOid(); int oid = object.getOid();
if (oid != _self.getClusterOid()) { if (oid != _self.getClusterOid()) {
// we got it too late, just unsubscribe // we got it too late, just unsubscribe
DObjectManager omgr = _ctx.getDObjectManager(); _ctx.getDObjectManager().unsubscribeFromObject(oid, this);
omgr.unsubscribeFromObject(oid, this);
} else { } else {
// it's our new cluster! // it's our new cluster!
_clobj = object; _clobj = object;
@@ -351,8 +332,8 @@ public class SpotSceneDirector extends BasicDirector
// documentation inherited from interface // documentation inherited from interface
public void requestFailed (int oid, ObjectAccessException cause) public void requestFailed (int oid, ObjectAccessException cause)
{ {
Log.warning("Unable to subscribe to cluster chat object " + Log.warning("Unable to subscribe to cluster chat object [oid=" + oid +
"[oid=" + oid + ", cause=" + cause + "]."); ", cause=" + cause + "].");
} }
// documentation inherited from interface // documentation inherited from interface
@@ -423,14 +404,13 @@ public class SpotSceneDirector extends BasicDirector
} }
/** /**
* Checks to see if our cluster has changed and does the necessary * Checks to see if our cluster has changed and does the necessary subscription machinations if
* subscription machinations if necessary. * necessary.
*/ */
protected void maybeUpdateCluster () protected void maybeUpdateCluster ()
{ {
int cloid = _self.getClusterOid(); int cloid = _self.getClusterOid();
if ((_clobj == null && cloid <= 0) || if ((_clobj == null && cloid <= 0) || (_clobj != null && cloid == _clobj.getOid())) {
(_clobj != null && cloid == _clobj.getOid())) {
// our cluster didn't change, we can stop now // our cluster didn't change, we can stop now
return; return;
} }
@@ -440,27 +420,23 @@ public class SpotSceneDirector extends BasicDirector
// if there's a new cluster object, subscribe to it // if there's a new cluster object, subscribe to it
if (_chatdir != null && cloid > 0) { if (_chatdir != null && cloid > 0) {
DObjectManager omgr = _ctx.getDObjectManager();
// we'll wire up to the chat director when this completes // we'll wire up to the chat director when this completes
omgr.subscribeToObject(cloid, this); _ctx.getDObjectManager().subscribeToObject(cloid, this);
} }
} }
/** /**
* Convenience routine to unwire chat for and unsubscribe from our * Convenience routine to unwire chat for and unsubscribe from our current cluster, if any.
* current cluster, if any.
* *
* @param force clear the cluster even if we're still apparently in it. * @param force clear the cluster even if we're still apparently in it.
*/ */
protected void clearCluster (boolean force) protected void clearCluster (boolean force)
{ {
if (_clobj != null && if (_clobj != null && (force || (_clobj.getOid() != _self.getClusterOid()))) {
(force || (_clobj.getOid() != _self.getClusterOid()))) {
if (_chatdir != null) { if (_chatdir != null) {
_chatdir.removeAuxiliarySource(_clobj); _chatdir.removeAuxiliarySource(_clobj);
} }
DObjectManager omgr = _ctx.getDObjectManager(); _ctx.getDObjectManager().unsubscribeFromObject(_clobj.getOid(), this);
omgr.unsubscribeFromObject(_clobj.getOid(), this);
_clobj = null; _clobj = null;
} }
} }
@@ -483,8 +459,7 @@ public class SpotSceneDirector extends BasicDirector
/** The location we currently occupy. */ /** The location we currently occupy. */
protected Location _location; protected Location _location;
/** The location to which we have an outstanding change location /** The location to which we have an outstanding change location request. */
* request. */
protected Location _pendingLoc; protected Location _pendingLoc;
/** The cluster chat object for the cluster we currently occupy. */ /** The cluster chat object for the cluster we currently occupy. */