Fiddlesticks. Let's unify these update methods and do away entirely with the
old dangerous way of updating. We will now use only the timeless way. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5574 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -55,6 +55,18 @@ public class OccupantInfo extends SimpleStreamableObject
|
||||
/** Maps status codes to human readable strings. */
|
||||
public static final String[] X_STATUS = { "active", "idle", "discon" };
|
||||
|
||||
/** Used by PlaceManager.updateOccupantInfo. */
|
||||
public static interface Updater<T extends OccupantInfo>
|
||||
{
|
||||
/**
|
||||
* Make whatever changes are desired to your {@link OccupantInfo} here.
|
||||
*
|
||||
* @return true if the record was modified and should be published, false if no
|
||||
* modifications were made (it will not be published).
|
||||
*/
|
||||
public boolean update (T info);
|
||||
}
|
||||
|
||||
/** The body object id of this occupant (and our entry key). */
|
||||
public Integer bodyOid;
|
||||
|
||||
|
||||
@@ -41,18 +41,6 @@ import static com.threerings.crowd.Log.log;
|
||||
public class BodyManager
|
||||
implements BodyProvider
|
||||
{
|
||||
/** Used by {@link BodyManager#updateOccupantInfo}. */
|
||||
public static interface OccupantInfoOp
|
||||
{
|
||||
/**
|
||||
* Updates the supplied occupant info record.
|
||||
*
|
||||
* @return true if changes were made and thus the object should be published anew to the
|
||||
* place object, false if no publish should be done.
|
||||
*/
|
||||
boolean update (OccupantInfo oinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and initializes the body manager.
|
||||
*/
|
||||
@@ -63,27 +51,21 @@ public class BodyManager
|
||||
|
||||
/**
|
||||
* Locates the specified body's occupant info in the specified location, applies the supplied
|
||||
* occuapnt info operation to it and then broadcasts the updated info (assuming the occop
|
||||
* occupant info operation to it and then broadcasts the updated info (assuming the occop
|
||||
* returned true indicating that an update was made).
|
||||
*/
|
||||
public void updateOccupantInfo (BodyObject body, Place location, OccupantInfoOp occop)
|
||||
public <T extends OccupantInfo> boolean updateOccupantInfo (
|
||||
BodyObject body, OccupantInfo.Updater<T> updater)
|
||||
{
|
||||
PlaceManager pmgr = (location == null) ? null : _plreg.getPlaceManager(location.placeOid);
|
||||
if (pmgr == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
OccupantInfo info = pmgr.getOccupantInfo(body.getOid());
|
||||
if (info != null && occop.update(info)) {
|
||||
pmgr.updateOccupantInfo(info);
|
||||
}
|
||||
PlaceManager pmgr = _plreg.getPlaceManager(body.getPlaceOid());
|
||||
return (pmgr == null) ? false : pmgr.updateOccupantInfo(body.getOid(), updater);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the connection status for the given body object's occupant info in the specified
|
||||
* location.
|
||||
*/
|
||||
public void updateOccupantStatus (BodyObject body, Place location, final byte status)
|
||||
public void updateOccupantStatus (BodyObject body, final byte status)
|
||||
{
|
||||
// no need to NOOP
|
||||
if (body.status != status) {
|
||||
@@ -92,14 +74,13 @@ public class BodyManager
|
||||
body.getLocal(BodyLocal.class).statusTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
updateOccupantInfo(body, location, new OccupantInfoOp() {
|
||||
updateOccupantInfo(body, new OccupantInfo.Updater<OccupantInfo>() {
|
||||
public boolean update (OccupantInfo info) {
|
||||
if (info.status != status) {
|
||||
info.status = status;
|
||||
return true;
|
||||
} else {
|
||||
if (info.status == status) {
|
||||
return false;
|
||||
}
|
||||
info.status = status;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -117,7 +98,7 @@ public class BodyManager
|
||||
|
||||
// update their status!
|
||||
log.debug("Setting user idle state [user=" + bobj.username + ", status=" + nstatus + "].");
|
||||
updateOccupantStatus(bobj, bobj.location, nstatus);
|
||||
updateOccupantStatus(bobj, nstatus);
|
||||
}
|
||||
|
||||
/** Provides access to place managers. */
|
||||
|
||||
@@ -42,7 +42,7 @@ public class CrowdSession extends PresentsSession
|
||||
if (_clobj != null) {
|
||||
// note that the user is disconnected
|
||||
BodyObject bobj = (BodyObject)_clobj;
|
||||
_bodyman.updateOccupantStatus(bobj, bobj.location, OccupantInfo.DISCONNECTED);
|
||||
_bodyman.updateOccupantStatus(bobj, OccupantInfo.DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class CrowdSession extends PresentsSession
|
||||
|
||||
// note that the user's active once more
|
||||
BodyObject bobj = (BodyObject)_clobj;
|
||||
_bodyman.updateOccupantStatus(bobj, bobj.location, OccupantInfo.ACTIVE);
|
||||
_bodyman.updateOccupantStatus(bobj, OccupantInfo.ACTIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,7 +68,7 @@ public class CrowdSession extends PresentsSession
|
||||
|
||||
// reset our status in case this object remains around until they start their next session
|
||||
// (which could happen very soon)
|
||||
_bodyman.updateOccupantStatus(body, null, OccupantInfo.ACTIVE);
|
||||
_bodyman.updateOccupantStatus(body, OccupantInfo.ACTIVE);
|
||||
|
||||
// clear our chat history
|
||||
if (body != null) {
|
||||
|
||||
@@ -114,15 +114,6 @@ public class PlaceManager
|
||||
protected Class<? extends PlaceManagerDelegate> _delegateClass;
|
||||
}
|
||||
|
||||
/** Used with {@link #updateOccupantInfo}. */
|
||||
public static interface OccInfoUpdater<T extends OccupantInfo>
|
||||
{
|
||||
/**
|
||||
* Make whatever changes are desired to your {@link OccupantInfo} here.
|
||||
*/
|
||||
public void update (T info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to our place configuration object.
|
||||
*/
|
||||
@@ -147,15 +138,6 @@ public class PlaceManager
|
||||
return _plobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the occupant info record for the user with the specified body oid, if they are an
|
||||
* occupant of this room. Returns null otherwise.
|
||||
*/
|
||||
public OccupantInfo getOccupantInfo (int bodyOid)
|
||||
{
|
||||
return _occInfo.get(bodyOid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the supplied occupant operation to each occupant currently present in this place.
|
||||
*/
|
||||
@@ -168,45 +150,27 @@ public class PlaceManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the occupant info for this room occupant. <em>Note:</em> This must be used rather
|
||||
* than setting the occupant info directly to avoid possible complications due to rapid fire
|
||||
* changes to a user's occupant info. The occupant info record supplied to this method must be
|
||||
* one returned from {@link #getOccupantInfo}. For example:
|
||||
*
|
||||
* <pre>
|
||||
* OccupantInfo info = _plmgr.getOccupantInfo(bodyOid);
|
||||
* // ... modifications made to 'info'
|
||||
* _plmgr.updateOccupantInfo(info);
|
||||
* </pre>
|
||||
*/
|
||||
public void updateOccupantInfo (OccupantInfo occInfo)
|
||||
{
|
||||
// update the canonical copy
|
||||
_occInfo.put(occInfo.getBodyOid(), occInfo);
|
||||
// clone the canonical copy and send an event updating the distributed set with that clone
|
||||
_plobj.updateOccupantInfo((OccupantInfo)occInfo.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the supplied updater on the canonical occupant info record for the specified body
|
||||
* (which must be an occupant of this place) and broadcasts the update to all other occupants.
|
||||
*
|
||||
* @return true if the updater was called and the update sent, false if the body could not be
|
||||
* located (was not an occupant of this place).
|
||||
* located (was not an occupant of this place) or the updater made no modifications.
|
||||
*
|
||||
* @exception ClassCastException thrown if the type of the supplied updater does not match the
|
||||
* type of {@link OccupantInfo} record used for the occupant. Caveat utilitor.
|
||||
*/
|
||||
public <T extends OccupantInfo> boolean updateOccupantInfo (
|
||||
int bodyOid, OccInfoUpdater<T> updater)
|
||||
int bodyOid, OccupantInfo.Updater<T> updater)
|
||||
{
|
||||
@SuppressWarnings("unchecked") T info = (T)getOccupantInfo(bodyOid);
|
||||
if (info == null) {
|
||||
@SuppressWarnings("unchecked") T info = (T)_occInfo.get(bodyOid);
|
||||
if (info == null || !updater.update(info)) {
|
||||
return false;
|
||||
}
|
||||
updater.update(info);
|
||||
updateOccupantInfo(info);
|
||||
// update the canonical copy
|
||||
_occInfo.put(info.getBodyOid(), info);
|
||||
// clone the canonical copy and send an event updating the distributed set with that clone
|
||||
_plobj.updateOccupantInfo((OccupantInfo)info.clone());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user