Revamped PlaceConfig to instantiate the PlaceController directly instead of

looking it up by name which creates PITA when we want to obfuscate and strip
out unused code.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4026 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2006-04-18 01:32:41 +00:00
parent 137cdfa8dd
commit fdf0fa27d3
6 changed files with 75 additions and 78 deletions
@@ -291,24 +291,14 @@ public class LocationDirector extends BasicDirector
// make a note that we're now mostly in the new location // make a note that we're now mostly in the new location
_placeId = placeId; _placeId = placeId;
// check whether we should use a custom class loader // start up a new place controller to manage the new place
ClassLoader loader = getClassLoader(config); _controller = createController(config);
if (loader != null) { if (_controller == null) {
config.setClassLoader(loader); Log.warning("Place config returned null controller " +
} "[config=" + config + "].");
return;
Class cclass = config.getControllerClass();
try {
// start up a new place controller to manage the new place
_controller = (PlaceController)cclass.newInstance();
_controller.init(_ctx, config);
} catch (Exception e) {
Log.warning("Error creating or initializing place controller " +
"[cclass=" + cclass.getName() +
", config=" + config + "].");
Log.logStackTrace(e);
} }
_controller.init(_ctx, config);
// subscribe to our new place object to complete the move // subscribe to our new place object to complete the move
_ctx.getDObjectManager().subscribeToObject(_placeId, this); _ctx.getDObjectManager().subscribeToObject(_placeId, this);
@@ -578,15 +568,14 @@ public class LocationDirector extends BasicDirector
} }
/** /**
* By overriding this method, it is possible to customize the location * Called to create our place controller using the supplied place
* director to cause it to load the classes associated with a * configuration. This lives in a separate method so that derived instances
* particular place via a custom class loader. That loader may enforce * can do funny class loader business if necessary to load the place
* restricted privileges or obtain the classes from some special * controller using a sandboxed class loader.
* source.
*/ */
protected ClassLoader getClassLoader (PlaceConfig config) protected PlaceController createController (PlaceConfig config)
{ {
return null; return config.createController();
} }
/** The context through which we access needed services. */ /** The context through which we access needed services. */
@@ -25,7 +25,7 @@ import com.samskivert.util.StringUtil;
import com.threerings.io.SimpleStreamableObject; import com.threerings.io.SimpleStreamableObject;
import com.threerings.crowd.client.LocationDirector; import com.threerings.crowd.Log;
import com.threerings.crowd.client.PlaceController; import com.threerings.crowd.client.PlaceController;
/** /**
@@ -35,45 +35,61 @@ import com.threerings.crowd.client.PlaceController;
* and place controller are provided with the place config object when the * and place controller are provided with the place config object when the
* place is created. * place is created.
* *
* <p> The place config object is also the mechanism used to instantiate * <p> The place config object is also the mechanism used to instantiate the
* the appropriate place manager and controller. Every place must have an * appropriate place manager and controller. Every place must have an
* associated place config derived class that overrides {@link * associated place config derived class that overrides {@link
* #getControllerClass} and {@link #getManagerClassName}, returning the * #createController} and {@link #getManagerClassName}, returning the
* appropriate place controller and manager class for that place. * appropriate place controller and manager class for that place.
*/ */
public abstract class PlaceConfig extends SimpleStreamableObject public abstract class PlaceConfig extends SimpleStreamableObject
{ {
/**
* Returns the class that should be used to create a controller for this
* place. The controller class must derive from {@link PlaceController}.
*
* @deprecated Override {@link #createController} directly.
*/
public Class getControllerClass ()
{
return null;
}
/** /**
* Returns the class that should be used to create a controller for * Returns the class that should be used to create a controller for
* this place. The controller class must derive from {@link * this place. The controller class must derive from {@link
* PlaceController}. * PlaceController}.
*/ */
public abstract Class getControllerClass (); public PlaceController createController ()
{
Class cclass = getControllerClass();
if (cclass == null) {
throw new RuntimeException(
"PlaceConfig.createController() must be overridden.");
}
Log.warning("Providing backwards compatibility. PlaceConfig." +
"createController() should be overridden directly.");
try {
return (PlaceController)cclass.newInstance();
} catch (Exception e) {
Log.warning("Failed to instantiate controller class '" +
cclass + "'.");
Log.logStackTrace(e);
return null;
}
}
/** /**
* Returns the name of the class that should be used to create a * Returns the name of the class that should be used to create a manager
* manager for this place. The manager class must derive from {@link * for this place. The manager class must derive from {@link
* com.threerings.crowd.server.PlaceManager}. <em>Note:</em> this * com.threerings.crowd.server.PlaceManager}. <em>Note:</em> this method
* method differs from {@link #getControllerClass} because we want to * differs from {@link #createController} because we want to avoid compile
* avoid compile time linkage of the place config object (which is * time linkage of the place config object (which is used on the client) to
* used on the client) to server code. This allows a code optimizer * server code. This allows a code optimizer (DashO Pro, for example) to
* (DashO Pro, for example) to remove the server code from the client, * remove the server code from the client, knowing that it is never used.
* knowing that it is never used.
*/ */
public abstract String getManagerClassName (); public abstract String getManagerClassName ();
/**
* The {@link LocationDirector} may be configured to use a custom
* class loader when loading the classes associated with a certain
* {@link PlaceConfig}, in this case this method will be called prior
* to a call to {@link #getControllerClass} to set {@link #_loader}
* which should then be used for any dynamic class loading.
*/
public void setClassLoader (ClassLoader loader)
{
_loader = loader;
}
// documentation inherited // documentation inherited
protected void toString (StringBuffer buf) protected void toString (StringBuffer buf)
{ {
@@ -81,7 +97,4 @@ public abstract class PlaceConfig extends SimpleStreamableObject
buf.append(", "); buf.append(", ");
super.toString(buf); super.toString(buf);
} }
/** The class loader to use when dynamically loading controller classes. */
protected transient ClassLoader _loader = getClass().getClassLoader();
} }
@@ -27,16 +27,17 @@ import javax.swing.JLabel;
import java.util.Properties; import java.util.Properties;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.threerings.crowd.client.PlaceController;
import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceConfig;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.micasa.util.MiCasaContext; import com.threerings.micasa.util.MiCasaContext;
import com.threerings.parlor.game.data.GameConfig;
public class LobbyConfig extends PlaceConfig public class LobbyConfig extends PlaceConfig
{ {
// documentation inherited // documentation inherited
public Class getControllerClass () public PlaceController createController ()
{ {
return LobbyController.class; return new LobbyController();
} }
// documentation inherited // documentation inherited
@@ -64,7 +65,7 @@ public class LobbyConfig extends PlaceConfig
public GameConfig getGameConfig () public GameConfig getGameConfig ()
throws Exception throws Exception
{ {
return (GameConfig)_loader.loadClass(_gameConfigClass).newInstance(); return (GameConfig)Class.forName(_gameConfigClass).newInstance();
} }
/** /**
@@ -32,20 +32,19 @@ import com.threerings.parlor.game.client.GameConfigurator;
/** /**
* The game config class encapsulates the configuration information for a * The game config class encapsulates the configuration information for a
* particular type of game. The hierarchy of game config objects mimics * particular type of game. The hierarchy of game config objects mimics the
* the hierarchy of game managers and controllers. Both the game manager * hierarchy of game managers and controllers. Both the game manager and game
* and game controller are provided with the game config object when the * controller are provided with the game config object when the game is
* game is created. * created.
* *
* <p> The game config object is also the mechanism used to instantiate * <p> The game config object is also the mechanism used to instantiate the
* the appropriate game manager and controller. Every game must have an * appropriate game manager and controller. Every game must have an associated
* associated game config derived class that overrides {@link * game config derived class that overrides {@link #createController} and
* #getControllerClass} and {@link #getManagerClassName}, returning the * {@link #getManagerClassName}, returning the appropriate game controller and
* appropriate game controller and manager class for that game. Thus the * manager class for that game. Thus the entire chain of events that causes a
* entire chain of events that causes a particular game to be created is * particular game to be created is the construction of the appropriate game
* the construction of the appropriate game config instance which is * config instance which is provided to the server as part of an invitation or
* provided to the server as part of an invitation or via some other * via some other matchmaking mechanism.
* matchmaking mechanism.
*/ */
public abstract class GameConfig extends PlaceConfig implements Cloneable public abstract class GameConfig extends PlaceConfig implements Cloneable
{ {
@@ -3,6 +3,7 @@
package com.threerings.stage.data; package com.threerings.stage.data;
import com.threerings.crowd.client.PlaceController;
import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceConfig;
import com.threerings.stage.client.StageSceneController; import com.threerings.stage.client.StageSceneController;
@@ -13,9 +14,9 @@ import com.threerings.stage.client.StageSceneController;
public class StageSceneConfig extends PlaceConfig public class StageSceneConfig extends PlaceConfig
{ {
// documentation inherited // documentation inherited
public Class getControllerClass () public PlaceController createController ()
{ {
return StageSceneController.class; return new StageSceneController();
} }
// documentation inherited // documentation inherited
@@ -1,5 +1,5 @@
// //
// $Id: DefaultSceneConfig.java,v 1.2 2004/08/27 02:20:42 mdb Exp $ // $Id$
// //
// Narya library - tools for developing networked games // Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved // Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
@@ -36,12 +36,6 @@ import com.threerings.whirled.client.SceneController;
*/ */
public class DefaultSceneConfig extends PlaceConfig public class DefaultSceneConfig extends PlaceConfig
{ {
// documentation inherited
public Class getControllerClass ()
{
return SceneController.class;
}
// documentation inherited // documentation inherited
public String getManagerClassName () public String getManagerClassName ()
{ {