From 2f7f1062714695a939175232497bb922b3a44ccb Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 16 Aug 2001 04:28:36 +0000 Subject: [PATCH] Server side of occupant management stuff. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@269 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/crowd/data/OccupantInfo.java | 72 +++++++++++++++++++ .../threerings/crowd/data/PlaceObject.dobj | 40 ++++++++++- .../crowd/server/LocationProvider.java | 39 +++++++--- .../threerings/crowd/server/PlaceManager.java | 55 +++++++++++++- .../crowd/server/PlaceRegistry.java | 11 ++- 5 files changed, 202 insertions(+), 15 deletions(-) create mode 100644 src/java/com/threerings/crowd/data/OccupantInfo.java 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