diff --git a/build.xml b/build.xml
index a54bfd4af..e77907a04 100644
--- a/build.xml
+++ b/build.xml
@@ -71,7 +71,6 @@
-
diff --git a/src/java/com/threerings/crowd/server/CrowdClient.java b/src/java/com/threerings/crowd/server/CrowdClient.java
index 6785d2011..7b0e26981 100644
--- a/src/java/com/threerings/crowd/server/CrowdClient.java
+++ b/src/java/com/threerings/crowd/server/CrowdClient.java
@@ -84,6 +84,6 @@ public class CrowdClient extends PresentsClient
*/
protected void clearLocation (BodyObject bobj)
{
- CrowdServer.plreg.locprov.leaveOccupiedPlace(bobj);
+ CrowdServer.locman.leaveOccupiedPlace(bobj);
}
}
diff --git a/src/java/com/threerings/crowd/server/CrowdServer.java b/src/java/com/threerings/crowd/server/CrowdServer.java
index 584422075..21d4b66c3 100644
--- a/src/java/com/threerings/crowd/server/CrowdServer.java
+++ b/src/java/com/threerings/crowd/server/CrowdServer.java
@@ -67,6 +67,9 @@ public class CrowdServer extends PresentsServer
/** Our body manager. */
public static BodyManager bodyman;
+ /** Our location manager. */
+ public static LocationManager locman;
+
/**
* Initializes all of the server services and prepares for operation.
*/
@@ -79,6 +82,7 @@ public class CrowdServer extends PresentsServer
plreg = _plreg;
chatprov = _chatprov;
bodyman = _bodyman;
+ locman = _locman;
// configure the client manager to use our bits
clmgr.setClientFactory(new ClientFactory() {
@@ -90,6 +94,9 @@ public class CrowdServer extends PresentsServer
}
});
+ // configure the place registry with the injector
+ _plreg.setInjector(injector);
+
// create our body locator
_lookup = createBodyLocator();
}
@@ -155,6 +162,9 @@ public class CrowdServer extends PresentsServer
/** Handles body-related invocation services. */
@Inject protected BodyManager _bodyman;
+ /** Handles location-related invocation services. */
+ @Inject protected LocationManager _locman;
+
/** Provides chat-related invocation services. */
@Inject protected ChatProvider _chatprov;
diff --git a/src/java/com/threerings/crowd/server/LocationManager.java b/src/java/com/threerings/crowd/server/LocationManager.java
new file mode 100644
index 000000000..78ce16a98
--- /dev/null
+++ b/src/java/com/threerings/crowd/server/LocationManager.java
@@ -0,0 +1,223 @@
+//
+// $Id$
+//
+// Narya library - tools for developing networked games
+// Copyright (C) 2002-2008 Three Rings Design, Inc., All Rights Reserved
+// http://www.threerings.net/code/narya/
+//
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+package com.threerings.crowd.server;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.dobj.RootDObjectManager;
+
+import com.threerings.presents.server.ClientManager;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.InvocationManager;
+import com.threerings.presents.server.InvocationProvider;
+import com.threerings.presents.server.PresentsClient;
+
+import com.threerings.crowd.client.LocationService;
+import com.threerings.crowd.data.BodyObject;
+import com.threerings.crowd.data.CrowdCodes;
+import com.threerings.crowd.data.LocationCodes;
+import com.threerings.crowd.data.Place;
+import com.threerings.crowd.data.PlaceConfig;
+import com.threerings.crowd.data.PlaceObject;
+import com.threerings.crowd.server.CrowdServer;
+
+import static com.threerings.crowd.Log.log;
+
+/**
+ * Handles location-related services.
+ */
+@Singleton
+public class LocationManager
+ implements LocationProvider, LocationCodes
+{
+ @Inject public LocationManager (InvocationManager invmgr)
+ {
+ invmgr.registerDispatcher(new LocationDispatcher(this), CrowdCodes.CROWD_GROUP);
+ }
+
+ // from interface LocationProvider
+ public void moveTo (ClientObject caller, int placeOid, LocationService.MoveListener listener)
+ throws InvocationException
+ {
+ // do the move and send the response
+ listener.moveSucceeded(moveTo((BodyObject)caller, placeOid));
+ }
+
+ // from interface LocationProvider
+ public void leavePlace (ClientObject caller)
+ {
+ leaveOccupiedPlace((BodyObject)caller);
+ }
+
+ /**
+ * Moves the specified body from whatever location they currently occupy to the location
+ * identified by the supplied place oid.
+ *
+ * @return the config object for the new location.
+ *
+ * @exception ServiceFaildException thrown if the move was not successful for some reason
+ * (which will be communicated as an error code in the exception's message data).
+ */
+ public PlaceConfig moveTo (BodyObject source, int placeOid)
+ throws InvocationException
+ {
+ int bodoid = source.getOid();
+
+ // make sure the place in question actually exists
+ PlaceManager pmgr = _plreg.getPlaceManager(placeOid);
+ if (pmgr == null) {
+ log.info("Requested to move to non-existent place [who=" + source.who() +
+ ", placeOid=" + placeOid + "].");
+ throw new InvocationException(NO_SUCH_PLACE);
+ }
+
+ // if they're already in the location they're asking to move to, just give them the config
+ // because we don't need to update anything in distributed object world
+ Place place = pmgr.getLocation();
+ if (place.equals(source.location)) {
+ log.debug("Going along with client request to move to where they already are " +
+ "[source=" + source.who() + ", place=" + place + "].");
+ return pmgr.getConfig();
+ }
+
+ // make sure they have access to the specified place
+ String errmsg;
+ if ((errmsg = pmgr.ratifyBodyEntry(source)) != null) {
+ throw new InvocationException(errmsg);
+ }
+
+ // acquire a lock on the body object to avoid breakage by rapid fire moveTo requests
+ if (!source.acquireLock("moveToLock")) {
+ // if we're still locked, a previous moveTo request hasn't been fully processed
+ throw new InvocationException(MOVE_IN_PROGRESS);
+ }
+
+ // configure the client accordingly if the place uses a custom class loader
+ PresentsClient client = _clmgr.getClient(source.username);
+ if (client != null) {
+ client.setClassLoader(pmgr.getClass().getClassLoader());
+ }
+
+ try {
+ PlaceObject plobj = pmgr.getPlaceObject();
+
+ // the doubly nested try catch is to prevent failure if one or the other of the
+ // transactions fails to start
+ plobj.startTransaction();
+ try {
+ source.startTransaction();
+ try {
+ // remove them from any previous location
+ leaveOccupiedPlace(source);
+
+ // generate a new occinfo record (which will add it to the target location)
+ pmgr.buildOccupantInfo(source);
+
+ // set the body's new location
+ source.willEnterPlace(place, plobj);
+
+ // add the body oid to the place object's occupant list
+ plobj.addToOccupants(bodoid);
+
+ } finally {
+ source.commitTransaction();
+ }
+ } finally {
+ plobj.commitTransaction();
+ }
+
+ } finally {
+ // and finally queue up an event to release the lock once these events are processed
+ source.releaseLock("moveToLock");
+ }
+
+ return pmgr.getConfig();
+ }
+
+ /**
+ * Removes the specified body from the place object they currently occupy. Does nothing if the
+ * body is not currently in a place.
+ */
+ public void leaveOccupiedPlace (BodyObject source)
+ {
+ Place oldloc = source.location;
+ int bodoid = source.getOid();
+
+ // nothing to do if they weren't previously in some location
+ if (oldloc == null) {
+ return;
+ }
+
+ // remove them from the occupant list
+ PlaceObject plobj = null;
+ try {
+ plobj = (PlaceObject)_omgr.getObject(oldloc.placeOid);
+ if (plobj != null) {
+ Integer key = Integer.valueOf(bodoid);
+ plobj.startTransaction();
+ try {
+ // remove their occupant info (which is keyed on oid)
+ plobj.removeFromOccupantInfo(key);
+ // and remove them from the occupant list
+ plobj.removeFromOccupants(bodoid);
+
+ } finally {
+ plobj.commitTransaction();
+ }
+
+ } else {
+ log.info("Body's prior location no longer around? [boid=" + bodoid +
+ ", place=" + oldloc + "].");
+ }
+
+ } catch (ClassCastException cce) {
+ log.warning("Body claims to occupy non-PlaceObject!? [boid=" + bodoid +
+ ", place=" + oldloc + ", error=" + cce + "].");
+ }
+
+ // clear out their location
+ source.didLeavePlace(plobj);
+ }
+
+ /**
+ * Forcibly moves the specified body object to the new place. This is accomplished by first
+ * removing the client from their old location and then sending the client a notification,
+ * instructing it to move to the new location (which it does using the normal moveTo service).
+ * This has the benefit that the client is removed from their old place regardless of whether
+ * or not they are cooperating. If they choose to ignore the forced move request, they will
+ * remain in limbo, unable to do much of anything.
+ */
+ public void moveBody (BodyObject source, Place place)
+ {
+ // first remove them from their old place
+ leaveOccupiedPlace(source);
+
+ // then send a forced move notification
+ LocationSender.forcedMove(source, place.placeOid);
+ }
+
+ @Inject protected RootDObjectManager _omgr;
+ @Inject protected PlaceRegistry _plreg;
+ @Inject protected ClientManager _clmgr;
+}
diff --git a/src/java/com/threerings/crowd/server/LocationProvider.java b/src/java/com/threerings/crowd/server/LocationProvider.java
index e91acd649..ec04bd4fd 100644
--- a/src/java/com/threerings/crowd/server/LocationProvider.java
+++ b/src/java/com/threerings/crowd/server/LocationProvider.java
@@ -2,7 +2,7 @@
// $Id$
//
// Narya library - tools for developing networked games
-// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
+// Copyright (C) 2002-2008 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
@@ -21,218 +21,24 @@
package com.threerings.crowd.server;
-import com.threerings.presents.dobj.RootDObjectManager;
-
-import com.threerings.presents.data.ClientObject;
-
-import com.threerings.presents.server.InvocationException;
-import com.threerings.presents.server.InvocationManager;
-import com.threerings.presents.server.InvocationProvider;
-import com.threerings.presents.server.PresentsClient;
-
import com.threerings.crowd.client.LocationService;
-import com.threerings.crowd.data.BodyObject;
-import com.threerings.crowd.data.LocationCodes;
-import com.threerings.crowd.data.Place;
-import com.threerings.crowd.data.PlaceConfig;
-import com.threerings.crowd.data.PlaceObject;
-import com.threerings.crowd.server.CrowdServer;
-
-import static com.threerings.crowd.Log.log;
+import com.threerings.presents.data.ClientObject;
+import com.threerings.presents.server.InvocationException;
+import com.threerings.presents.server.InvocationProvider;
/**
- * This class provides the server end of the location services.
+ * Defines the server-side of the {@link LocationService}.
*/
-public class LocationProvider
- implements LocationCodes, InvocationProvider
+public interface LocationProvider extends InvocationProvider
{
/**
- * Creates a location provider and prepares it for operation.
+ * Handles a {@link LocationService#leavePlace} request.
*/
- public LocationProvider (InvocationManager invmgr, RootDObjectManager omgr, PlaceRegistry plreg)
- {
- // we'll need these later
- _invmgr = invmgr;
- _omgr = omgr;
- _plreg = plreg;
- }
+ public void leavePlace (ClientObject caller);
/**
- * Requests that this client's body be moved to the specified location.
- *
- * @param caller the client object of the client that invoked this remotely callable method.
- * @param place the oid of the place to which the body should be moved.
- * @param listener the listener that will be informed of success or failure.
+ * Handles a {@link LocationService#moveTo} request.
*/
- public void moveTo (ClientObject caller, int placeOid, LocationService.MoveListener listener)
- throws InvocationException
- {
- // do the move and send the response
- listener.moveSucceeded(moveTo((BodyObject)caller, placeOid));
- }
-
- /**
- * Requests that we leave our current place and move to nowhere land.
- */
- public void leavePlace (ClientObject caller)
- throws InvocationException
- {
- leaveOccupiedPlace((BodyObject)caller);
- }
-
- /**
- * Moves the specified body from whatever location they currently occupy to the location
- * identified by the supplied place oid.
- *
- * @return the config object for the new location.
- *
- * @exception ServiceFaildException thrown if the move was not successful for some reason
- * (which will be communicated as an error code in the exception's message data).
- */
- public PlaceConfig moveTo (BodyObject source, int placeOid)
- throws InvocationException
- {
- int bodoid = source.getOid();
-
- // make sure the place in question actually exists
- PlaceManager pmgr = _plreg.getPlaceManager(placeOid);
- if (pmgr == null) {
- log.info("Requested to move to non-existent place [who=" + source.who() +
- ", placeOid=" + placeOid + "].");
- throw new InvocationException(NO_SUCH_PLACE);
- }
-
- // if they're already in the location they're asking to move to, just give them the config
- // because we don't need to update anything in distributed object world
- Place place = pmgr.getLocation();
- if (place.equals(source.location)) {
- log.debug("Going along with client request to move to where they already are " +
- "[source=" + source.who() + ", place=" + place + "].");
- return pmgr.getConfig();
- }
-
- // make sure they have access to the specified place
- String errmsg;
- if ((errmsg = pmgr.ratifyBodyEntry(source)) != null) {
- throw new InvocationException(errmsg);
- }
-
- // acquire a lock on the body object to avoid breakage by rapid fire moveTo requests
- if (!source.acquireLock("moveToLock")) {
- // if we're still locked, a previous moveTo request hasn't been fully processed
- throw new InvocationException(MOVE_IN_PROGRESS);
- }
-
- // configure the client accordingly if the place uses a custom class loader
- PresentsClient client = CrowdServer.clmgr.getClient(source.username);
- if (client != null) {
- client.setClassLoader(_plreg.getClassLoader(pmgr.getConfig()));
- }
-
- try {
- PlaceObject plobj = pmgr.getPlaceObject();
-
- // the doubly nested try catch is to prevent failure if one or the other of the
- // transactions fails to start
- plobj.startTransaction();
- try {
- source.startTransaction();
- try {
- // remove them from any previous location
- leaveOccupiedPlace(source);
-
- // generate a new occinfo record (which will add it to the target location)
- pmgr.buildOccupantInfo(source);
-
- // set the body's new location
- source.willEnterPlace(place, plobj);
-
- // add the body oid to the place object's occupant list
- plobj.addToOccupants(bodoid);
-
- } finally {
- source.commitTransaction();
- }
- } finally {
- plobj.commitTransaction();
- }
-
- } finally {
- // and finally queue up an event to release the lock once these events are processed
- source.releaseLock("moveToLock");
- }
-
- return pmgr.getConfig();
- }
-
- /**
- * Removes the specified body from the place object they currently occupy. Does nothing if the
- * body is not currently in a place.
- */
- public void leaveOccupiedPlace (BodyObject source)
- {
- Place oldloc = source.location;
- int bodoid = source.getOid();
-
- // nothing to do if they weren't previously in some location
- if (oldloc == null) {
- return;
- }
-
- // remove them from the occupant list
- PlaceObject plobj = null;
- try {
- plobj = (PlaceObject)_omgr.getObject(oldloc.placeOid);
- if (plobj != null) {
- Integer key = Integer.valueOf(bodoid);
- plobj.startTransaction();
- try {
- // remove their occupant info (which is keyed on oid)
- plobj.removeFromOccupantInfo(key);
- // and remove them from the occupant list
- plobj.removeFromOccupants(bodoid);
-
- } finally {
- plobj.commitTransaction();
- }
-
- } else {
- log.info("Body's prior location no longer around? [boid=" + bodoid +
- ", place=" + oldloc + "].");
- }
-
- } catch (ClassCastException cce) {
- log.warning("Body claims to occupy non-PlaceObject!? [boid=" + bodoid +
- ", place=" + oldloc + ", error=" + cce + "].");
- }
-
- // clear out their location
- source.didLeavePlace(plobj);
- }
-
- /**
- * Forcibly moves the specified body object to the new place. This is accomplished by first
- * removing the client from their old location and then sending the client a notification,
- * instructing it to move to the new location (which it does using the normal moveTo service).
- * This has the benefit that the client is removed from their old place regardless of whether
- * or not they are cooperating. If they choose to ignore the forced move request, they will
- * remain in limbo, unable to do much of anything.
- */
- public void moveBody (BodyObject source, Place place)
- {
- // first remove them from their old place
- leaveOccupiedPlace(source);
-
- // then send a forced move notification
- LocationSender.forcedMove(source, place.placeOid);
- }
-
- /** The invocation manager with which we interoperate. */
- protected InvocationManager _invmgr;
-
- /** The distributed object manager with which we interoperate. */
- protected RootDObjectManager _omgr;
-
- /** The place registry with which we interoperate. */
- protected PlaceRegistry _plreg;
+ public void moveTo (ClientObject caller, int arg1, LocationService.MoveListener arg2)
+ throws InvocationException;
}
diff --git a/src/java/com/threerings/crowd/server/PlaceManager.java b/src/java/com/threerings/crowd/server/PlaceManager.java
index 651fcbfdc..b729781b4 100644
--- a/src/java/com/threerings/crowd/server/PlaceManager.java
+++ b/src/java/com/threerings/crowd/server/PlaceManager.java
@@ -36,7 +36,6 @@ import com.samskivert.util.StringUtil;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.dobj.AccessController;
import com.threerings.presents.dobj.DObject;
-import com.threerings.presents.dobj.DObjectManager;
import com.threerings.presents.dobj.DynamicListener;
import com.threerings.presents.dobj.EntryUpdatedEvent;
import com.threerings.presents.dobj.MessageEvent;
@@ -46,9 +45,9 @@ import com.threerings.presents.dobj.ObjectDeathListener;
import com.threerings.presents.dobj.ObjectDestroyedEvent;
import com.threerings.presents.dobj.ObjectRemovedEvent;
import com.threerings.presents.dobj.OidListListener;
+import com.threerings.presents.dobj.RootDObjectManager;
import com.threerings.presents.dobj.SetAdapter;
import com.threerings.presents.server.InvocationManager;
-import com.threerings.presents.server.PresentsDObjectMgr;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.OccupantInfo;
@@ -168,8 +167,7 @@ public class PlaceManager
{
// update the canonical copy
_occInfo.put(occInfo.getBodyOid(), occInfo);
- // clone the canonical copy and send out an event updating the distributed set with that
- // clone
+ // clone the canonical copy and send an event updating the distributed set with that clone
_plobj.updateOccupantInfo((OccupantInfo)occInfo.clone());
}
@@ -177,7 +175,7 @@ public class PlaceManager
* Called by the place registry after creating this place manager.
*/
public void init (PlaceRegistry registry, InvocationManager invmgr,
- DObjectManager omgr, PlaceConfig config)
+ RootDObjectManager omgr, PlaceConfig config)
{
_registry = registry;
_invmgr = invmgr;
@@ -263,7 +261,7 @@ public class PlaceManager
public void shutdown ()
{
// destroy the object and everything will follow from that
- CrowdServer.omgr.destroyObject(_plobj.getOid());
+ _omgr.destroyObject(_plobj.getOid());
// clear out our services
if (_plobj.speakService != null) {
@@ -349,7 +347,7 @@ public class PlaceManager
// the first argument should be the client object of the caller or null if it is
// a server-originated event
int srcoid = event.getSourceOid();
- DObject source = (srcoid <= 0) ? null : CrowdServer.omgr.getObject(srcoid);
+ DObject source = (srcoid <= 0) ? null : _omgr.getObject(srcoid);
Object[] args = event.getArgs(), nargs;
if (args == null) {
nargs = new Object[] { source };
@@ -636,7 +634,7 @@ public class PlaceManager
// queue up a shutdown interval, unless we've already got one.
long idlePeriod = idleUnloadPeriod();
if (idlePeriod > 0L && _shutdownInterval == null) {
- _shutdownInterval = new Interval((PresentsDObjectMgr)_omgr) {
+ _shutdownInterval = new Interval(_omgr) {
public void expired () {
log.debug("Unloading idle place '" + where () + "'.");
shutdown();
@@ -693,7 +691,7 @@ public class PlaceManager
protected InvocationManager _invmgr;
/** A distributed object manager for doing dobj stuff. */
- protected DObjectManager _omgr;
+ protected RootDObjectManager _omgr;
/** A reference to the place object that we manage. */
protected PlaceObject _plobj;
diff --git a/src/java/com/threerings/crowd/server/PlaceRegistry.java b/src/java/com/threerings/crowd/server/PlaceRegistry.java
index c261fa9ff..4eec0f31b 100644
--- a/src/java/com/threerings/crowd/server/PlaceRegistry.java
+++ b/src/java/com/threerings/crowd/server/PlaceRegistry.java
@@ -25,6 +25,7 @@ import java.util.Iterator;
import java.util.List;
import com.google.inject.Inject;
+import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.samskivert.util.IntMap;
@@ -57,39 +58,32 @@ public class PlaceRegistry
public void invoke (PlaceManager plmgr);
}
- /** The location provider used by the place registry to provide location-related invocation
- * services. */
- public LocationProvider locprov;
-
/**
* Creates and initializes the place registry. This is called by the server during its
* initialization phase.
*/
- @Inject public PlaceRegistry (ShutdownManager shutmgr, InvocationManager invmgr,
- RootDObjectManager omgr)
+ @Inject public PlaceRegistry (ShutdownManager shutmgr)
{
shutmgr.registerShutdowner(this);
-
- // create and register our location provider
- locprov = new LocationProvider(invmgr, omgr, this);
- invmgr.registerDispatcher(new LocationDispatcher(locprov), CrowdCodes.CROWD_GROUP);
-
- // we'll need these later
- _omgr = omgr;
- _invmgr = invmgr;
}
/**
- * By overriding this method, it is possible to customize the place registry to cause it to
- * load the classes associated with a particular place via a custom class loader. That loader
- * may enforce restricted privileges or obtain the classes from some special source.
- *
- * @return the class loader to use when instantiating the {@link PlaceManager} associated with
- * the supplied {@link PlaceConfig}. This method must not return null.
+ * Provides the place registry with access to an injector that it can use to create {@link
+ * PlaceManager} instances with all dependencies resolved. This is called by the {@link
+ * CrowdServer} during the server initialization phase.
*/
- public ClassLoader getClassLoader (PlaceConfig config)
+ public void setInjector (Injector injector)
{
- return getClass().getClassLoader();
+ _injector = injector;
+ }
+
+ /**
+ * Returns the place manager associated with the specified place object id or null if no such
+ * place exists.
+ */
+ public PlaceManager getPlaceManager (int placeOid)
+ {
+ return _pmgrs.get(placeOid);
}
/**
@@ -142,15 +136,6 @@ public class PlaceRegistry
return createPlace(config, null, hook);
}
- /**
- * Returns the place manager associated with the specified place object id or null if no such
- * place exists.
- */
- public PlaceManager getPlaceManager (int placeOid)
- {
- return _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 around across event dispatches.
@@ -204,12 +189,10 @@ public class PlaceRegistry
throws InstantiationException, InvocationException
{
PlaceManager pmgr = null;
- ClassLoader loader = getClassLoader(config);
try {
// create a place manager using the class supplied in the place config
- pmgr = (PlaceManager)Class.forName(
- config.getManagerClassName(), true, loader).newInstance();
+ pmgr = createPlaceManager(config);
// if we have delegates, add them
if (delegates != null) {
@@ -226,8 +209,7 @@ public class PlaceRegistry
throw new InstantiationException("Error creating PlaceManager for " + config);
}
- // give the manager an opportunity to abort the whole process if it fails any permissions
- // checks
+ // let the manager abort the whole process if it fails any permissions checks
String errmsg = pmgr.checkPermissions();
if (errmsg != null) {
// give the place manager a chance to clean up after its early initialization process
@@ -256,6 +238,20 @@ public class PlaceRegistry
return pmgr;
}
+ /**
+ * Creates an instance of a {@link PlaceManager} using the information in the supplied place
+ * config. Derived classes may wish to specialize this process for certain places for example
+ * loading user supplied place management code from a special class loader that sandboxes their
+ * code.
+ */
+ protected PlaceManager createPlaceManager (PlaceConfig config)
+ throws Exception
+ {
+ @SuppressWarnings("unchecked") Class extends PlaceManager> clazz =
+ (Class extends PlaceManager>) Class.forName(config.getManagerClassName());
+ return _injector.getInstance(clazz);
+ }
+
/**
* Called by the place manager when it has been shut down.
*/
@@ -273,10 +269,13 @@ public class PlaceRegistry
}
/** The invocation manager with which we operate. */
- protected InvocationManager _invmgr;
+ @Inject protected InvocationManager _invmgr;
/** The distributed object manager with which we operate. */
- protected RootDObjectManager _omgr;
+ @Inject protected RootDObjectManager _omgr;
+
+ /** We use this to inject dependencies into place managers that we create. */
+ protected Injector _injector;
/** A mapping from place object id to place manager. */
protected IntMap _pmgrs = IntMaps.newHashIntMap();
diff --git a/tests/src/java/com/threerings/bureau/server/RegistryTester.java b/tests/src/java/com/threerings/bureau/server/RegistryTester.java
index 884a58918..55bb605ee 100644
--- a/tests/src/java/com/threerings/bureau/server/RegistryTester.java
+++ b/tests/src/java/com/threerings/bureau/server/RegistryTester.java
@@ -30,10 +30,11 @@ import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
-import com.threerings.bureau.data.AgentObject;
-
+import com.threerings.presents.dobj.RootDObjectManager;
import com.threerings.presents.server.ShutdownManager;
+import com.threerings.bureau.data.AgentObject;
+
import static com.threerings.bureau.Log.log;
/**
@@ -173,11 +174,11 @@ public class RegistryTester
}
// create or destroy some agents
- TestServer.omgr.postRunnable(createOrDestroyAgents);
+ _omgr.postRunnable(createOrDestroyAgents);
}
// clean up
- TestServer.omgr.postRunnable(new Runnable() {
+ _omgr.postRunnable(new Runnable() {
public void run () {
for (AgentObject obj : _agents) {
TestServer.breg.destroyAgent(obj);
@@ -217,6 +218,8 @@ public class RegistryTester
return obj;
}
+ @Inject protected RootDObjectManager _omgr;
+
protected TestServer _server;
protected boolean _stop;
protected Random _rng1;