diff --git a/src/java/com/threerings/crowd/data/OccupantInfo.java b/src/java/com/threerings/crowd/data/OccupantInfo.java
new file mode 100644
index 000000000..1545030d6
--- /dev/null
+++ b/src/java/com/threerings/crowd/data/OccupantInfo.java
@@ -0,0 +1,72 @@
+//
+// $Id: OccupantInfo.java,v 1.1 2001/08/16 04:28:36 mdb Exp $
+
+package com.threerings.cocktail.party.data;
+
+import java.io.IOException;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+
+import com.threerings.cocktail.cher.dobj.DSet;
+
+/**
+ * The occupant info object contains all of the information about an
+ * occupant of a place that should be shared with other occupants of the
+ * place. These objects are stored in the place object itself and are
+ * updated when bodies enter and exit a place. A system that builds upon
+ * the Party framework can extend this class to include extra information
+ * about their occupants. They will need to be sure to return the proper
+ * class from {@link
+ * com.threerings.cocktail.party.server.PlaceManager#getOccupantInfoClass}
+ * and populate their occupant info in {@link
+ * com.threerings.cocktail.party.server.PlaceManager#populateOccupantInfo}.
+ */
+public class OccupantInfo implements DSet.Element
+{
+ /** The username of this occupant. */
+ public String username;
+
+ // documentation inherited
+ public Object getKey ()
+ {
+ return username;
+ }
+
+ // documentation inherited
+ public void writeTo (DataOutputStream out)
+ throws IOException
+ {
+ out.writeUTF(username);
+ }
+
+ // documentation inherited
+ public void readFrom (DataInputStream in)
+ throws IOException
+ {
+ username = in.readUTF();
+ }
+
+ /**
+ * Called to generate a string representation of this occupant info
+ * object. This calls the overridable {@link #toString(StringBuffer)}
+ * to generate that representation in a derived class friendly manner.
+ */
+ public String toString ()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append("[");
+ toString(buf);
+ buf.append("]");
+ return buf.toString();
+ }
+
+ /**
+ * Derived classes should override this and append their extra
+ * occupant info to the buffer. They should of course not to forget to
+ * call super.
+ */
+ protected void toString (StringBuffer buf)
+ {
+ buf.append("username=").append(username);
+ }
+}
diff --git a/src/java/com/threerings/crowd/data/PlaceObject.dobj b/src/java/com/threerings/crowd/data/PlaceObject.dobj
index 8bb7a59ed..2e27a316d 100644
--- a/src/java/com/threerings/crowd/data/PlaceObject.dobj
+++ b/src/java/com/threerings/crowd/data/PlaceObject.dobj
@@ -1,5 +1,5 @@
//
-// $Id: PlaceObject.dobj,v 1.4 2001/08/02 06:01:13 mdb Exp $
+// $Id: PlaceObject.dobj,v 1.5 2001/08/16 04:28:36 mdb Exp $
package com.threerings.cocktail.party.data;
@@ -10,12 +10,22 @@ public class PlaceObject extends DObject
/** The field name of the occupants field. */
public static final String OCCUPANTS = "occupants";
+ /** The field name of the occupantInfo field. */
+ public static final String OCCUPANT_INFO = "occupantInfo";
+
/**
* Tracks the oid of the body objects of all of the occupants of this
* place.
*/
public OidList occupants = new OidList();
+ /**
+ * Contains an info record (of type {@link OccupantInfo} for each
+ * occupant that contains information about that occupant that needs
+ * to be known by everyone in the place.
+ */
+ public DSet occupantInfo = new DSet();
+
/**
* Requests that the specified oid be added to the
* occupants oid list.
@@ -34,9 +44,37 @@ public class PlaceObject extends DObject
requestOidRemove(OCCUPANTS, oid);
}
+ /**
+ * Requests that the specified element be added to the
+ * occupantInfo set.
+ */
+ public void addToOccupantInfo (DSet.Element elem)
+ {
+ requestElementAdd(OCCUPANT_INFO, elem);
+ }
+
+ /**
+ * Requests that the element matching the supplied key be removed from
+ * the occupantInfo set.
+ */
+ public void removeFromOccupantInfo (Object key)
+ {
+ requestElementRemove(OCCUPANT_INFO, key);
+ }
+
+ /**
+ * Requests that the specified element be updated in the
+ * occupantInfo set.
+ */
+ public void updateOccupantInfo (DSet.Element elem)
+ {
+ requestElementUpdate(OCCUPANT_INFO, elem);
+ }
+
protected void toString (StringBuffer buf)
{
super.toString(buf);
buf.append(", occupants=").append(occupants);
+ buf.append(", occupantInfo=").append(occupantInfo);
}
}
diff --git a/src/java/com/threerings/crowd/server/LocationProvider.java b/src/java/com/threerings/crowd/server/LocationProvider.java
index c8b87c613..d8da440f4 100644
--- a/src/java/com/threerings/crowd/server/LocationProvider.java
+++ b/src/java/com/threerings/crowd/server/LocationProvider.java
@@ -1,15 +1,15 @@
//
-// $Id: LocationProvider.java,v 1.5 2001/08/11 02:07:20 mdb Exp $
+// $Id: LocationProvider.java,v 1.6 2001/08/16 04:28:36 mdb Exp $
package com.threerings.cocktail.party.server;
import com.threerings.cocktail.cher.dobj.DObject;
-import com.threerings.cocktail.cher.server.CherServer;
import com.threerings.cocktail.cher.server.InvocationProvider;
import com.threerings.cocktail.cher.util.Codes;
import com.threerings.cocktail.party.Log;
import com.threerings.cocktail.party.data.*;
+import com.threerings.cocktail.party.server.PartyServer;
/**
* This class provides the server end of the location services.
@@ -43,8 +43,8 @@ public class LocationProvider extends InvocationProvider
public static String moveTo (BodyObject source, int placeId)
{
// make sure the place in question actually exists
- DObject pobj = CherServer.omgr.getObject(placeId);
- if (pobj == null || !(pobj instanceof PlaceObject)) {
+ PlaceManager pmgr = PartyServer.plreg.getPlaceManager(placeId);
+ if (pmgr == null) {
Log.info("Requested to move to non-existent place " +
"[source=" + source + ", place=" + placeId + "].");
return "m.no_such_place";
@@ -69,8 +69,18 @@ public class LocationProvider extends InvocationProvider
// remove them from the occupant list of the previous location
try {
PlaceObject pold = (PlaceObject)
- CherServer.omgr.getObject(source.location);
- pold.removeFromOccupants(source.getOid());
+ PartyServer.omgr.getObject(source.location);
+ if (pold != null) {
+ pold.removeFromOccupants(source.getOid());
+ // also remove their occupant info (which is keyed on
+ // username)
+ pold.removeFromOccupantInfo(source.username);
+
+ } else {
+ Log.info("Body's prior location no longer around? " +
+ "[boid=" + source.getOid() +
+ ", poid=" + source.location + "].");
+ }
} catch (ClassCastException cce) {
Log.warning("Body claims to be at location which " +
@@ -80,13 +90,20 @@ public class LocationProvider extends InvocationProvider
}
}
- // add the body object id to the place object's occupant list
- PlaceObject place = (PlaceObject)pobj;
- place.addToOccupants(source.getOid());
-
- // set their new location
+ // set the body's new location
+ PlaceObject place = pmgr.getPlaceObject();
source.setLocation(place.getOid());
+ // generate a new occupant info record and add it to the target
+ // location
+ OccupantInfo info = pmgr.buildOccupantInfo(source);
+ if (info != null) {
+ place.addToOccupantInfo(info);
+ }
+
+ // add the body object id to the place object's occupant list
+ place.addToOccupants(source.getOid());
+
// and finally queue up a lock release event to release the lock
// once all these events are processed
source.releaseLock("moveToLock");
diff --git a/src/java/com/threerings/crowd/server/PlaceManager.java b/src/java/com/threerings/crowd/server/PlaceManager.java
index a8ab30d27..0134de4dd 100644
--- a/src/java/com/threerings/crowd/server/PlaceManager.java
+++ b/src/java/com/threerings/crowd/server/PlaceManager.java
@@ -1,5 +1,5 @@
//
-// $Id: PlaceManager.java,v 1.7 2001/08/04 01:13:36 mdb Exp $
+// $Id: PlaceManager.java,v 1.8 2001/08/16 04:28:36 mdb Exp $
package com.threerings.cocktail.party.server;
@@ -9,7 +9,7 @@ import java.util.Properties;
import com.threerings.cocktail.cher.dobj.*;
import com.threerings.cocktail.party.Log;
-import com.threerings.cocktail.party.data.PlaceObject;
+import com.threerings.cocktail.party.data.*;
/**
* The place manager is the server-side entity that handles all
@@ -58,6 +58,9 @@ public class PlaceManager implements Subscriber
// keep track of this
_plobj = plobj;
+ // configure the occupant info set
+ plobj.occupantInfo.setElementType(getOccupantInfoClass());
+
// we'll want to be included among the place object's subscribers;
// we know that we can call addSubscriber() directly because the
// place manager is doing all of our initialization on the dobjmgr
@@ -78,6 +81,54 @@ public class PlaceManager implements Subscriber
{
}
+ /**
+ * When the manager starts up, it configures its place object occupant
+ * info set by setting the type of occupant info objects it will
+ * contain. Managers that wish to use derived occupant info classes
+ * should override this function and return a reference to their
+ * derived class.
+ */
+ protected Class getOccupantInfoClass ()
+ {
+ return OccupantInfo.class;
+ }
+
+ /**
+ * Builds an occupant info record for the specified body object. This
+ * is called by the location services when a body enters a place. It
+ * should not be overridden by derived classes, they should override
+ * {@link #populateOccupantInfo}, which is set up for that sort of
+ * thing.
+ */
+ public OccupantInfo buildOccupantInfo (BodyObject body)
+ {
+ // create a new occupant info instance
+ try {
+ OccupantInfo info = (OccupantInfo)
+ getOccupantInfoClass().newInstance();
+ populateOccupantInfo(info, body);
+ return info;
+
+ } catch (Exception e) {
+ Log.warning("Failure building occupant info " +
+ "[body=" + body + "].");
+ Log.logStackTrace(e);
+ return null;
+ }
+ }
+
+ /**
+ * Derived classes should override this method if they are making use
+ * of a derived occupant info class. They should call the super
+ * implementation and then populate the occupant info fields in their
+ * extended object.
+ */
+ protected void populateOccupantInfo (OccupantInfo info, BodyObject body)
+ {
+ // the base occupant info is only their username
+ info.username = body.username;
+ }
+
/**
* Called when a body object enters this place.
*/
diff --git a/src/java/com/threerings/crowd/server/PlaceRegistry.java b/src/java/com/threerings/crowd/server/PlaceRegistry.java
index 57f69c257..952f7aafc 100644
--- a/src/java/com/threerings/crowd/server/PlaceRegistry.java
+++ b/src/java/com/threerings/crowd/server/PlaceRegistry.java
@@ -1,5 +1,5 @@
//
-// $Id: PlaceRegistry.java,v 1.6 2001/08/11 04:03:25 mdb Exp $
+// $Id: PlaceRegistry.java,v 1.7 2001/08/16 04:28:36 mdb Exp $
package com.threerings.cocktail.party.server;
@@ -114,6 +114,15 @@ public class PlaceRegistry implements Subscriber
}
}
+ /**
+ * Returns the place manager associated with the specified place
+ * object id or null if no such place exists.
+ */
+ public PlaceManager getPlaceManager (int placeOid)
+ {
+ return (PlaceManager)_pmgrs.get(placeOid);
+ }
+
/**
* Returns an enumeration of all of the registered place objects. This
* should only be accessed on the dobjmgr thread and shouldn't be kept