diff --git a/docs/crowd/notes.txt b/docs/crowd/notes.txt new file mode 100644 index 000000000..ab2257325 --- /dev/null +++ b/docs/crowd/notes.txt @@ -0,0 +1,5 @@ +Party Notes -*- outline -*- + +* TODO +Wire up PlaceRegistry code to remove registrations when place objects are +destroyed. diff --git a/src/java/com/threerings/crowd/server/CrowdServer.java b/src/java/com/threerings/crowd/server/CrowdServer.java index 37cb0887f..3c577a674 100644 --- a/src/java/com/threerings/crowd/server/CrowdServer.java +++ b/src/java/com/threerings/crowd/server/CrowdServer.java @@ -1,5 +1,5 @@ // -// $Id: CrowdServer.java,v 1.1 2001/07/23 21:14:27 mdb Exp $ +// $Id: CrowdServer.java,v 1.2 2001/08/01 03:22:54 mdb Exp $ package com.threerings.cocktail.party.server; @@ -19,6 +19,9 @@ public class PartyServer extends CherServer /** The namespace used for server config properties. */ public static final String CONFIG_KEY = "party"; + /** The place registry. */ + public PlaceRegistry plreg; + /** * Initializes all of the server services and prepares for operation. */ @@ -34,6 +37,9 @@ public class PartyServer extends CherServer // configure the client to use the body object clmgr.setClientObjectClass(BodyObject.class); + // create our place registry + plreg = new PlaceRegistry(config); + // register our invocation service providers registerProviders(config.getValue(PROVIDERS_KEY, (String[])null)); diff --git a/src/java/com/threerings/crowd/server/PlaceManager.java b/src/java/com/threerings/crowd/server/PlaceManager.java index 6ff21aa79..33e7de328 100644 --- a/src/java/com/threerings/crowd/server/PlaceManager.java +++ b/src/java/com/threerings/crowd/server/PlaceManager.java @@ -1,8 +1,82 @@ // -// $Id: PlaceManager.java,v 1.2 2001/07/23 21:14:27 mdb Exp $ +// $Id: PlaceManager.java,v 1.3 2001/08/01 03:22:54 mdb Exp $ package com.threerings.cocktail.party.server; -public class PlaceManager +import com.threerings.cocktail.cher.dobj.*; + +import com.threerings.cocktail.party.data.PlaceObject; + +/** + * The place manager is the server-side entity that handles all + * place-related interaction. It subscribes to the place object and reacts + * to message and other events. Behavior specific to a place (or class of + * places) should live in the place manager. An intelligently constructed + * hierarchy of place manager classes working in concert with invocation + * services should provide the majority of the server-side functionality + * of an application built on the Cocktail platform. + * + *

The base place manager class takes care of the necessary + * interactions with the place registry to manage place registration. It + * handles the place-related component of chatting. It also provides the + * basis for place-based access control. + */ +public class PlaceManager implements Subscriber { + /** + * Called by the place manager after the place object has been + * successfully created. + */ + public void init (PlaceObject plobj) + { + // keep track of this + _plobj = plobj; + + // 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 + // thread + plobj.addSubscriber(this); + + // let our derived classes do their thang + didInit(); + } + + protected void didInit () + { + } + + /** + * Returns the place object managed by this place manager. + */ + public PlaceObject getPlaceObject () + { + return _plobj; + } + + public void objectAvailable (DObject object) + { + } + + public void requestFailed (int oid, ObjectAccessException cause) + { + } + + public boolean handleEvent (DEvent event, DObject target) + { + return true; + } + + /** + * Called by the place registry after creating this place manager. + * This is necessary so that the manager can inform the place registry + * when the place goes away. + */ + public void setRegistry (PlaceRegistry registry) + { + _registry = registry; + } + + protected PlaceObject _plobj; + protected PlaceRegistry _registry; } diff --git a/src/java/com/threerings/crowd/server/PlaceRegistry.java b/src/java/com/threerings/crowd/server/PlaceRegistry.java new file mode 100644 index 000000000..9aaab7f44 --- /dev/null +++ b/src/java/com/threerings/crowd/server/PlaceRegistry.java @@ -0,0 +1,144 @@ +// +// $Id: PlaceRegistry.java,v 1.1 2001/08/01 03:22:54 mdb Exp $ + +package com.threerings.cocktail.party.server; + +import java.util.Enumeration; +import com.samskivert.util.Config; +import com.samskivert.util.Queue; + +import com.threerings.cocktail.cher.dobj.*; +import com.threerings.cocktail.cher.util.IntMap; + +import com.threerings.cocktail.party.Log; +import com.threerings.cocktail.party.data.PlaceObject; + +/** + * The place registry keeps track of all of the active places in the + * server. It should be used to create new places and it will take care of + * instantiating and initializing a place manager to manage newly created + * places. + */ +public class PlaceRegistry implements Subscriber +{ + /** + * Creates and initializes the place registry; called by the server + * during its initialization phase. + */ + public PlaceRegistry (Config config) + { + } + + /** + * Creates and registers a new place along with a manager to manage + * that place. The registry takes care of tracking the creation of the + * object and informing the manager when it is created. + * + * @param pobjClass the PlaceObject derived class that + * should be instantiated to create the place object. + * @param pmgrClass the PlaceManager derived class that + * should be instantiated to manage the place. + */ + public void createPlace (Class pobjClass, Class pmgrClass) + { + // create a place manager for this place + try { + PlaceManager pmgr = (PlaceManager)pmgrClass.newInstance(); + // stick the manager on the creation queue because we know + // we'll get our calls to objectAvailable()/requestFailed() in + // the order that we call createObject() + _createq.append(pmgr); + // and request to create the place object + PartyServer.omgr.createObject(pobjClass, this, false); + + } catch (Exception e) { + Log.warning("Error creating place " + + "[pobjc=" + pobjClass.getName() + + ", pmgrc=" + pmgrClass.getName() + + ", error=" + e + "]."); + } + } + + /** + * Returns an enumeration of all of the registered place objects. This + * should only be accessed on the dobjmgr thread and shouldn't be kept + * around across event dispatches. + */ + public Enumeration getPlaces () + { + final Enumeration enum = _pmgrs.elements(); + return new Enumeration() { + public boolean hasMoreElements () + { + return enum.hasMoreElements(); + } + + public Object nextElement () + { + PlaceManager plmgr = (PlaceManager)enum.nextElement(); + return (plmgr == null) ? null : plmgr.getPlaceObject(); + } + }; + } + + /** + * Unregisters the place from the registry. Called by the place + * manager when a place object that it was managing is destroyed. + */ + public void placeWasDestroyed (int oid) + { + // remove the place manager from the table + _pmgrs.remove(oid); + } + + public void objectAvailable (DObject object) + { + // pop the next place manager off of the queue and let it know + // that everything went swimmingly + PlaceManager pmgr = (PlaceManager)_createq.getNonBlocking(); + if (pmgr == null) { + Log.warning("Place created but no manager queued up to hear " + + "about it!? [pobj=" + object + "]."); + return; + } + + // make sure it's the right kind of object + if (!(object instanceof PlaceObject)) { + Log.warning("Place registry notified of the creation of " + + "non-place object!? [obj=" + object + "]."); + return; + } + + // initialize the place manager with the newly created place + // object + pmgr.init((PlaceObject)object); + + // stick the manager into our table + _pmgrs.put(object.getOid(), pmgr); + } + + public void requestFailed (int oid, ObjectAccessException cause) + { + // pop a place manager off the queue since it is queued up to + // manage the failed place object + PlaceManager pmgr = (PlaceManager)_createq.getNonBlocking(); + if (pmgr == null) { + Log.warning("Place creation failed but no manager queued " + + "up to hear about it!? [cause=" + cause + "]."); + return; + } + + Log.warning("Failed to create place object [mgr=" + pmgr + + ", cause=" + cause + "]."); + } + + public boolean handleEvent (DEvent event, DObject target) + { + // this shouldn't be called because we don't subscribe to + // anything, we just want to hear about object creation + return false; + } + + protected Queue _createq = new Queue(); + protected IntMap _pmgrs = new IntMap(); +}