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
This commit is contained in:
Par Winzell
2010-12-05 03:58:38 +00:00
parent 5758499ba0
commit 817b733ff0
4 changed files with 27 additions and 8 deletions
@@ -130,6 +130,16 @@ public class BodyObject extends ClientObject
op.apply(getVisibleName()); 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 @Override
public String who () public String who ()
{ {
@@ -50,8 +50,10 @@ public class BodyLocator
} }
/** /**
* Returns the body object to be used for the given client. The default implementation * Returns the body object to be used for the given client. This is the reverse operation of
* assumes they are one and the same. * {@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 @EventThread
public BodyObject forClient (ClientObject client) public BodyObject forClient (ClientObject client)
@@ -91,7 +91,7 @@ public class BodyManager
// determine the body's proposed new status // determine the body's proposed new status
byte nstatus = (idle) ? OccupantInfo.IDLE : OccupantInfo.ACTIVE; byte nstatus = (idle) ? OccupantInfo.IDLE : OccupantInfo.ACTIVE;
if (bobj.status == nstatus) { if (bobj == null || bobj.status == nstatus) {
return; // ignore NOOP attempts return; // ignore NOOP attempts
} }
@@ -42,7 +42,9 @@ public class CrowdSession extends PresentsSession
if (_clobj != null) { if (_clobj != null) {
// note that the user is disconnected // note that the user is disconnected
BodyObject bobj = _locator.forClient(_clobj); 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 // note that the user's active once more
BodyObject bobj = _locator.forClient(_clobj); BodyObject bobj = _locator.forClient(_clobj);
_bodyman.updateOccupantStatus(bobj, OccupantInfo.ACTIVE); if (bobj != null) {
_bodyman.updateOccupantStatus(bobj, OccupantInfo.ACTIVE);
}
} }
@Override @Override
@@ -63,6 +67,11 @@ public class CrowdSession extends PresentsSession
BodyObject body = _locator.forClient(_clobj); 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 // clear out our location so that anyone listening will know that we've left
clearLocation(body); clearLocation(body);
@@ -71,9 +80,7 @@ public class CrowdSession extends PresentsSession
_bodyman.updateOccupantStatus(body, OccupantInfo.ACTIVE); _bodyman.updateOccupantStatus(body, OccupantInfo.ACTIVE);
// clear our chat history // clear our chat history
if (body != null) { SpeakUtil.clearHistory(body.getVisibleName());
SpeakUtil.clearHistory(body.getVisibleName());
}
} }
/** /**