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
_placeId = placeId;
// check whether we should use a custom class loader
ClassLoader loader = getClassLoader(config);
if (loader != null) {
config.setClassLoader(loader);
}
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);
// start up a new place controller to manage the new place
_controller = createController(config);
if (_controller == null) {
Log.warning("Place config returned null controller " +
"[config=" + config + "].");
return;
}
_controller.init(_ctx, config);
// subscribe to our new place object to complete the move
_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
* director 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.
* Called to create our place controller using the supplied place
* configuration. This lives in a separate method so that derived instances
* can do funny class loader business if necessary to load the place
* controller using a sandboxed class loader.
*/
protected ClassLoader getClassLoader (PlaceConfig config)
protected PlaceController createController (PlaceConfig config)
{
return null;
return config.createController();
}
/** 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.crowd.client.LocationDirector;
import com.threerings.crowd.Log;
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
* place is created.
*
* <p> The place config object is also the mechanism used to instantiate
* the appropriate place manager and controller. Every place must have an
* <p> The place config object is also the mechanism used to instantiate the
* appropriate place manager and controller. Every place must have an
* 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.
*/
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
* this place. The controller class must derive from {@link
* 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
* manager for this place. The manager class must derive from {@link
* com.threerings.crowd.server.PlaceManager}. <em>Note:</em> this
* method differs from {@link #getControllerClass} because we want to
* avoid compile time linkage of the place config object (which is
* used on the client) to server code. This allows a code optimizer
* (DashO Pro, for example) to remove the server code from the client,
* knowing that it is never used.
* Returns the name of the class that should be used to create a manager
* for this place. The manager class must derive from {@link
* com.threerings.crowd.server.PlaceManager}. <em>Note:</em> this method
* differs from {@link #createController} because we want to avoid compile
* time linkage of the place config object (which is used on the client) to
* server code. This allows a code optimizer (DashO Pro, for example) to
* remove the server code from the client, knowing that it is never used.
*/
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
protected void toString (StringBuffer buf)
{
@@ -81,7 +97,4 @@ public abstract class PlaceConfig extends SimpleStreamableObject
buf.append(", ");
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 com.samskivert.util.StringUtil;
import com.threerings.crowd.client.PlaceController;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.parlor.game.data.GameConfig;
import com.threerings.micasa.util.MiCasaContext;
import com.threerings.parlor.game.data.GameConfig;
public class LobbyConfig extends PlaceConfig
{
// documentation inherited
public Class getControllerClass ()
public PlaceController createController ()
{
return LobbyController.class;
return new LobbyController();
}
// documentation inherited
@@ -64,7 +65,7 @@ public class LobbyConfig extends PlaceConfig
public GameConfig getGameConfig ()
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
* particular type of game. The hierarchy of game config objects mimics
* the hierarchy of game managers and controllers. Both the game manager
* and game controller are provided with the game config object when the
* game is created.
* particular type of game. The hierarchy of game config objects mimics the
* hierarchy of game managers and controllers. Both the game manager and game
* controller are provided with the game config object when the game is
* created.
*
* <p> The game config object is also the mechanism used to instantiate
* the appropriate game manager and controller. Every game must have an
* associated game config derived class that overrides {@link
* #getControllerClass} and {@link #getManagerClassName}, returning the
* appropriate game controller and manager class for that game. Thus the
* entire chain of events that causes a particular game to be created is
* the construction of the appropriate game config instance which is
* provided to the server as part of an invitation or via some other
* matchmaking mechanism.
* <p> The game config object is also the mechanism used to instantiate the
* appropriate game manager and controller. Every game must have an associated
* game config derived class that overrides {@link #createController} and
* {@link #getManagerClassName}, returning the appropriate game controller and
* manager class for that game. Thus the entire chain of events that causes a
* particular game to be created is the construction of the appropriate game
* config instance which is provided to the server as part of an invitation or
* via some other matchmaking mechanism.
*/
public abstract class GameConfig extends PlaceConfig implements Cloneable
{
@@ -3,6 +3,7 @@
package com.threerings.stage.data;
import com.threerings.crowd.client.PlaceController;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.stage.client.StageSceneController;
@@ -13,9 +14,9 @@ import com.threerings.stage.client.StageSceneController;
public class StageSceneConfig extends PlaceConfig
{
// documentation inherited
public Class getControllerClass ()
public PlaceController createController ()
{
return StageSceneController.class;
return new StageSceneController();
}
// 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
// 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
{
// documentation inherited
public Class getControllerClass ()
{
return SceneController.class;
}
// documentation inherited
public String getManagerClassName ()
{