From 817b733ff0d34bcc129567e8c7ca3b2307222fe1 Mon Sep 17 00:00:00 2001 From: Par Winzell Date: Sun, 5 Dec 2010 03:58:38 +0000 Subject: [PATCH] Clarify that BodyLocator.forClient() should return null if the user is not currently driving a BodyObject. Use this fact to avoid various NPEs. Also introduce a reverse mapping of forClient(); it should always be possible to ask a BodyObject what its ClientObject connection to the user is. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6340 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../com/threerings/crowd/data/BodyObject.java | 10 ++++++++++ .../threerings/crowd/server/BodyLocator.java | 6 ++++-- .../threerings/crowd/server/BodyManager.java | 2 +- .../threerings/crowd/server/CrowdSession.java | 17 ++++++++++++----- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/threerings/crowd/data/BodyObject.java b/src/main/java/com/threerings/crowd/data/BodyObject.java index 087495dda..a45275ed0 100644 --- a/src/main/java/com/threerings/crowd/data/BodyObject.java +++ b/src/main/java/com/threerings/crowd/data/BodyObject.java @@ -130,6 +130,16 @@ public class BodyObject extends ClientObject op.apply(getVisibleName()); } + /** + * Return the {@link ClientObject} that represent our driving user's connection. This is + * the reverse operation of {@link BodyLocator#forClient} and should match it. The default + * implementation assumes the client object and the body object are one and the same. + */ + public ClientObject getClientObject () + { + return this; + } + @Override public String who () { diff --git a/src/main/java/com/threerings/crowd/server/BodyLocator.java b/src/main/java/com/threerings/crowd/server/BodyLocator.java index fe670dd44..c7dc8e8a9 100644 --- a/src/main/java/com/threerings/crowd/server/BodyLocator.java +++ b/src/main/java/com/threerings/crowd/server/BodyLocator.java @@ -50,8 +50,10 @@ public class BodyLocator } /** - * Returns the body object to be used for the given client. The default implementation - * assumes they are one and the same. + * Returns the body object to be used for the given client. This is the reverse operation of + * {@link BodyObject#getClientObject} and the two should match. The default implementation + * assumes they are one and the same. This method should return null if the client is not + * currently controlling a body. */ @EventThread public BodyObject forClient (ClientObject client) diff --git a/src/main/java/com/threerings/crowd/server/BodyManager.java b/src/main/java/com/threerings/crowd/server/BodyManager.java index e4f010c04..e55e7a07c 100644 --- a/src/main/java/com/threerings/crowd/server/BodyManager.java +++ b/src/main/java/com/threerings/crowd/server/BodyManager.java @@ -91,7 +91,7 @@ public class BodyManager // determine the body's proposed new status byte nstatus = (idle) ? OccupantInfo.IDLE : OccupantInfo.ACTIVE; - if (bobj.status == nstatus) { + if (bobj == null || bobj.status == nstatus) { return; // ignore NOOP attempts } diff --git a/src/main/java/com/threerings/crowd/server/CrowdSession.java b/src/main/java/com/threerings/crowd/server/CrowdSession.java index ac7243787..46cc5a4e1 100644 --- a/src/main/java/com/threerings/crowd/server/CrowdSession.java +++ b/src/main/java/com/threerings/crowd/server/CrowdSession.java @@ -42,7 +42,9 @@ public class CrowdSession extends PresentsSession if (_clobj != null) { // note that the user is disconnected BodyObject bobj = _locator.forClient(_clobj); - _bodyman.updateOccupantStatus(bobj, OccupantInfo.DISCONNECTED); + if (bobj != null) { + _bodyman.updateOccupantStatus(bobj, OccupantInfo.DISCONNECTED); + } } } @@ -53,7 +55,9 @@ public class CrowdSession extends PresentsSession // note that the user's active once more BodyObject bobj = _locator.forClient(_clobj); - _bodyman.updateOccupantStatus(bobj, OccupantInfo.ACTIVE); + if (bobj != null) { + _bodyman.updateOccupantStatus(bobj, OccupantInfo.ACTIVE); + } } @Override @@ -63,6 +67,11 @@ public class CrowdSession extends PresentsSession BodyObject body = _locator.forClient(_clobj); + // if we no longer have a body, there's nothing more to do + if (body == null) { + return; + } + // clear out our location so that anyone listening will know that we've left clearLocation(body); @@ -71,9 +80,7 @@ public class CrowdSession extends PresentsSession _bodyman.updateOccupantStatus(body, OccupantInfo.ACTIVE); // clear our chat history - if (body != null) { - SpeakUtil.clearHistory(body.getVisibleName()); - } + SpeakUtil.clearHistory(body.getVisibleName()); } /**