The amazing refactor forteen hundred billion: eliminated "locations",
portals will by dynamically created, combined display/runtime/editable scenes into one, enhanced support for modifying scenes and distributing updates to the clients, various other small stuff that should not be sweated. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2274 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
//
|
||||
// $Id: DefaultDisplaySceneFactory.java,v 1.1 2001/11/18 04:09:23 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* The default display scene factory creates {@link DisplaySceneImpl}
|
||||
* instances.
|
||||
*/
|
||||
public class DefaultDisplaySceneFactory implements DisplaySceneFactory
|
||||
{
|
||||
// documentation inherited
|
||||
public DisplayScene createScene (SceneModel model, PlaceConfig config)
|
||||
{
|
||||
return new DisplaySceneImpl(model, config);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
//
|
||||
// $Id: DisplayScene.java,v 1.2 2001/12/12 19:06:15 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
/**
|
||||
* This interface makes available the scene information that is needed by
|
||||
* a client to display a scene. At this basic level, not much information
|
||||
* is available, but extensions to this interface begin to create a more
|
||||
* comprehensive picture of a scene in a system built from the Whirled
|
||||
* services.
|
||||
*
|
||||
* <p> Additionally, at this basic level, the <code>DisplayScene</code>
|
||||
* does not differ greatly (or at all) from the {@link
|
||||
* com.threerings.whirled.server.RuntimeScene} interface, but the
|
||||
* distinction provides a mechanism for handling the more substantial
|
||||
* differences that appear in more sophisticated extensions to the base
|
||||
* scene services.
|
||||
*/
|
||||
public interface DisplayScene
|
||||
{
|
||||
/**
|
||||
* Returns the unique identifier for this scene.
|
||||
*/
|
||||
public int getId ();
|
||||
|
||||
/**
|
||||
* Returns the name of this scene.
|
||||
*/
|
||||
public String getName ();
|
||||
|
||||
/**
|
||||
* Returns the version number of this scene.
|
||||
*/
|
||||
public int getVersion ();
|
||||
|
||||
/**
|
||||
* Returns the list of scene ids of this scene's neighbors.
|
||||
*/
|
||||
public int[] getNeighborIds ();
|
||||
|
||||
/**
|
||||
* Returns the place config that can be used to determine which place
|
||||
* controller instance should be used to display this scene as well as
|
||||
* to obtain runtime configuration information.
|
||||
*/
|
||||
public PlaceConfig getPlaceConfig ();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// $Id: DisplaySceneFactory.java,v 1.1 2001/11/12 20:56:55 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* When resolving a scene, the scene director loads a scene model from the
|
||||
* scene repository, but it needs an external entity to convert that scene
|
||||
* model into the appropriate implementation of {@link DisplayScene}. The
|
||||
* display scene factory interface provides the mechanism by which users
|
||||
* of the Whirled system can create the appropriate instances.
|
||||
*/
|
||||
public interface DisplaySceneFactory
|
||||
{
|
||||
/**
|
||||
* This is called by the scene director after it has loaded the scene
|
||||
* model from the scene repository and obtained the place config from
|
||||
* a successful <code>moveTo</code> request.
|
||||
*/
|
||||
public DisplayScene createScene (SceneModel model, PlaceConfig config);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
//
|
||||
// $Id: DisplaySceneImpl.java,v 1.2 2001/12/12 19:06:15 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* A basic implementation of the {@link DisplayScene} interface which is
|
||||
* used by default if no extended implementation is desired.
|
||||
*/
|
||||
public class DisplaySceneImpl implements DisplayScene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and place config.
|
||||
*/
|
||||
public DisplaySceneImpl (SceneModel model, PlaceConfig config)
|
||||
{
|
||||
_model = model;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getId ()
|
||||
{
|
||||
return _model.sceneId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getName ()
|
||||
{
|
||||
return _model.sceneName;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getVersion ()
|
||||
{
|
||||
return _model.version;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int[] getNeighborIds ()
|
||||
{
|
||||
return _model.neighborIds;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public PlaceConfig getPlaceConfig ()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
/** A reference to our scene model. */
|
||||
protected SceneModel _model;
|
||||
|
||||
/** A reference to our place configuration. */
|
||||
protected PlaceConfig _config;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneDirector.java,v 1.23 2002/12/09 04:44:33 shaper Exp $
|
||||
// $Id: SceneDirector.java,v 1.24 2003/02/12 07:23:30 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
@@ -19,10 +19,13 @@ import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.client.persist.SceneRepository;
|
||||
import com.threerings.whirled.data.Scene;
|
||||
import com.threerings.whirled.data.SceneCodes;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.util.NoSuchSceneException;
|
||||
import com.threerings.whirled.util.SceneFactory;
|
||||
import com.threerings.whirled.util.WhirledContext;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
|
||||
/**
|
||||
* The scene director is the client's interface to all things scene
|
||||
@@ -49,10 +52,10 @@ public class SceneDirector extends BasicDirector
|
||||
* @param screp the entity from which the scene director will load
|
||||
* scene data from the local client scene storage.
|
||||
* @param dsfact the factory that knows which derivation of {@link
|
||||
* DisplayScene} to create for the current system.
|
||||
* Scene} to create for the current system.
|
||||
*/
|
||||
public SceneDirector (WhirledContext ctx, LocationDirector locdir,
|
||||
SceneRepository screp, DisplaySceneFactory dsfact)
|
||||
SceneRepository screp, SceneFactory fact)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
@@ -60,7 +63,7 @@ public class SceneDirector extends BasicDirector
|
||||
_ctx = ctx;
|
||||
_locdir = locdir;
|
||||
_screp = screp;
|
||||
_dsfact = dsfact;
|
||||
_fact = fact;
|
||||
|
||||
// set ourselves up as a failure handler with the location
|
||||
// director because we need to do special processing
|
||||
@@ -75,7 +78,7 @@ public class SceneDirector extends BasicDirector
|
||||
* Returns the display scene object associated with the scene we
|
||||
* currently occupy or null if we currently occupy no scene.
|
||||
*/
|
||||
public DisplayScene getScene ()
|
||||
public Scene getScene ()
|
||||
{
|
||||
return _scene;
|
||||
}
|
||||
@@ -202,25 +205,84 @@ public class SceneDirector extends BasicDirector
|
||||
if (_model == null) {
|
||||
Log.warning("Aiya! Unable to load scene [sid=" + _sceneId +
|
||||
", plid=" + placeId + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// and finally create a display scene instance with the model and
|
||||
// the place config
|
||||
_scene = _dsfact.createScene(_model, config);
|
||||
_scene = _fact.createScene(_model, config);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceededPlusUpdate (
|
||||
public void moveSucceededWithUpdates (
|
||||
int placeId, PlaceConfig config, SceneUpdate[] updates)
|
||||
{
|
||||
// apply the updates to our cached scene
|
||||
SceneModel model = loadSceneModel(_pendingSceneId);
|
||||
boolean failure = false;
|
||||
for (int ii = 0; ii < updates.length; ii++) {
|
||||
try {
|
||||
updates[ii].validate(model);
|
||||
} catch (IllegalStateException ise) {
|
||||
Log.warning("Scene update failed validation [model=" + model +
|
||||
", update=" + updates[ii] +
|
||||
", error=" + ise.getMessage() + "].");
|
||||
failure = true;
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
updates[ii].apply(model);
|
||||
} catch (Exception e) {
|
||||
Log.warning("Failure applying scene update [model=" + model +
|
||||
", update=" + updates[ii] + "].");
|
||||
Log.logStackTrace(e);
|
||||
failure = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (failure) {
|
||||
// delete the now half-booched scene model from the repository
|
||||
try {
|
||||
_screp.deleteSceneModel(_pendingSceneId);
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failure removing booched scene model " +
|
||||
"[sceneId=" + _pendingSceneId + "].");
|
||||
Log.logStackTrace(ioe);
|
||||
}
|
||||
|
||||
// act as if the scene move failed, though we'll be in a funny
|
||||
// state because the server thinks we've changed scenes, but
|
||||
// the client can try again without its booched scene model
|
||||
requestFailed(INTERNAL_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// store the updated scene in the repository
|
||||
try {
|
||||
_screp.storeSceneModel(model);
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Failed to update repository with updated scene " +
|
||||
"[sceneId=" + model.sceneId + "].");
|
||||
Log.logStackTrace(ioe);
|
||||
}
|
||||
|
||||
// finally pass through to the normal success handler
|
||||
moveSucceeded(placeId, config);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceededWithScene (
|
||||
int placeId, PlaceConfig config, SceneModel model)
|
||||
{
|
||||
// update the model in the repository
|
||||
try {
|
||||
_screp.updateSceneModel(model);
|
||||
_screp.storeSceneModel(model);
|
||||
} catch (IOException ioe) {
|
||||
Log.warning("Danger Will Robinson! We were unable to update " +
|
||||
"our scene cache with a new version of a scene " +
|
||||
"provided by the server " +
|
||||
"[newVersion=" + model.version + "].");
|
||||
Log.warning("Failed to update repository with new version " +
|
||||
"[sceneId=" + model.sceneId +
|
||||
", nvers=" + model.version + "].");
|
||||
Log.logStackTrace(ioe);
|
||||
}
|
||||
|
||||
@@ -376,14 +438,14 @@ public class SceneDirector extends BasicDirector
|
||||
/** The entity via which we load scene data. */
|
||||
protected SceneRepository _screp;
|
||||
|
||||
/** The entity we use to create display scenes from scene models. */
|
||||
protected DisplaySceneFactory _dsfact;
|
||||
/** The entity we use to create scenes from scene models. */
|
||||
protected SceneFactory _fact;
|
||||
|
||||
/** A cache of scene model information. */
|
||||
protected HashIntMap _scache = new HashIntMap();
|
||||
|
||||
/** The display scene object for the scene we currently occupy. */
|
||||
protected DisplayScene _scene;
|
||||
protected Scene _scene;
|
||||
|
||||
/** The scene model for the scene we currently occupy. */
|
||||
protected SceneModel _model;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneService.java,v 1.9 2002/08/14 19:07:57 mdb Exp $
|
||||
// $Id: SceneService.java,v 1.10 2003/02/12 07:23:30 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
@@ -7,7 +7,9 @@ import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
|
||||
/**
|
||||
* The scene service class provides the client interface to the scene
|
||||
@@ -34,11 +36,23 @@ public interface SceneService extends InvocationService
|
||||
*
|
||||
* @param placeId the place object id of the newly occupied scene.
|
||||
* @param config metadata related to the newly occupied scene.
|
||||
* @param model the most recent scene data for the newly occupied
|
||||
* scene.
|
||||
* @param updates updates that must be applied to the client's
|
||||
* copy of a scene model to bring it up to date.
|
||||
*/
|
||||
public void moveSucceededPlusUpdate (
|
||||
int placeId, PlaceConfig config, SceneModel model);
|
||||
public void moveSucceededWithUpdates (int placeId, PlaceConfig config,
|
||||
SceneUpdate[] updates);
|
||||
|
||||
/**
|
||||
* Indicates that a move succeeded and that the client's cached
|
||||
* scene information should be updated with the supplied data.
|
||||
*
|
||||
* @param placeId the place object id of the newly occupied scene.
|
||||
* @param config metadata related to the newly occupied scene.
|
||||
* @param model a fresh copy of the most recent scene data for the
|
||||
* newly occupied scene.
|
||||
*/
|
||||
public void moveSucceededWithScene (int placeId, PlaceConfig config,
|
||||
SceneModel model);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,9 +60,9 @@ public interface SceneService extends InvocationService
|
||||
* scene.
|
||||
*
|
||||
* @param sceneId the scene id to which we want to move.
|
||||
* @param sceneVers the version number of the scene object that we
|
||||
* have in our local repository.
|
||||
* @param version the version number of the scene object that we have
|
||||
* in our local repository.
|
||||
*/
|
||||
public void moveTo (Client client, int sceneId,
|
||||
int sceneVers, SceneMoveListener listener);
|
||||
public void moveTo (Client client, int sceneId, int version,
|
||||
SceneMoveListener listener);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneRepository.java,v 1.3 2001/11/12 20:56:55 mdb Exp $
|
||||
// $Id: SceneRepository.java,v 1.4 2003/02/12 07:23:30 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client.persist;
|
||||
|
||||
@@ -10,17 +10,14 @@ import com.threerings.whirled.util.NoSuchSceneException;
|
||||
|
||||
/**
|
||||
* The scene repository provides access to a persistent repository of
|
||||
* scene information. The scene models in the repository can be updated
|
||||
* with scene data fetched from the server as well as with new scene
|
||||
* bundles that are periodically distributed to bring all clients into
|
||||
* sync with the latest snapshot of the scene database.
|
||||
* scene information.
|
||||
*
|
||||
* @see SceneModel
|
||||
*/
|
||||
public interface SceneRepository
|
||||
{
|
||||
/**
|
||||
* Fetches the mode for the scene with the specified scene id.
|
||||
* Fetches the model for the scene with the specified id.
|
||||
*
|
||||
* @exception IOException thrown if an error occurs attempting to load
|
||||
* the scene data.
|
||||
@@ -31,13 +28,20 @@ public interface SceneRepository
|
||||
throws IOException, NoSuchSceneException;
|
||||
|
||||
/**
|
||||
* Updates this scene model in the repository. This is generally only
|
||||
* called when the server has provided us with a newer version of a
|
||||
* scene than we previously had in our local repository.
|
||||
* Updates or inserts this scene model as appropriate.
|
||||
*
|
||||
* @exception IOException thrown if an error occurs attempting to
|
||||
* update the scene data.
|
||||
* access the repository.
|
||||
*/
|
||||
public void updateSceneModel (SceneModel model)
|
||||
public void storeSceneModel (SceneModel model)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Deletes the specified scene model from the repository.
|
||||
*
|
||||
* @exception IOException thrown if an error occurs attempting to
|
||||
* access the repository.
|
||||
*/
|
||||
public void deleteSceneModel (int sceneId)
|
||||
throws IOException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// $Id: AuxModel.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.data;
|
||||
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
/**
|
||||
* An interface that must be implemented by auxiliary scene models.
|
||||
*/
|
||||
public interface AuxModel extends Streamable, Cloneable
|
||||
{
|
||||
/**
|
||||
* Creates a clone of this auxiliary model.
|
||||
*/
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// $Id: Scene.java,v 1.8 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.data;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
/**
|
||||
* This interface makes available basic scene information. At this basic
|
||||
* level, not much information is available, but extensions to this
|
||||
* interface begin to create a more comprehensive picture of a scene in a
|
||||
* system built from the Whirled services.
|
||||
*/
|
||||
public interface Scene
|
||||
{
|
||||
/**
|
||||
* Returns the unique identifier for this scene.
|
||||
*/
|
||||
public int getId ();
|
||||
|
||||
/**
|
||||
* Returns the human readable name of this scene.
|
||||
*/
|
||||
public String getName ();
|
||||
|
||||
/**
|
||||
* Returns the version number of this scene.
|
||||
*/
|
||||
public int getVersion ();
|
||||
|
||||
/**
|
||||
* Returns the place config that can be used to determine which place
|
||||
* controller instance should be used to display this scene as well as
|
||||
* to obtain runtime configuration information.
|
||||
*/
|
||||
public PlaceConfig getPlaceConfig ();
|
||||
|
||||
/**
|
||||
* Sets this scene's unique identifier.
|
||||
*/
|
||||
public void setId (int sceneId);
|
||||
|
||||
/**
|
||||
* Sets the human readable name of this scene.
|
||||
*/
|
||||
public void setName (String name);
|
||||
|
||||
/**
|
||||
* Sets this scene's version number.
|
||||
*/
|
||||
public void setVersion (int version);
|
||||
|
||||
/**
|
||||
* Returns the scene model from which this scene was created.
|
||||
*/
|
||||
public SceneModel getSceneModel ();
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// $Id: SceneImpl.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.data;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link Scene} interface.
|
||||
*/
|
||||
public class SceneImpl implements Scene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and place config.
|
||||
*/
|
||||
public SceneImpl (SceneModel model, PlaceConfig config)
|
||||
{
|
||||
_model = model;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a blank scene implementation. No place config will be
|
||||
* associated with this scene.
|
||||
*/
|
||||
public SceneImpl ()
|
||||
{
|
||||
_model = SceneModel.blankSceneModel();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getId ()
|
||||
{
|
||||
return _model.sceneId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getName ()
|
||||
{
|
||||
return _model.name;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getVersion ()
|
||||
{
|
||||
return _model.version;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public PlaceConfig getPlaceConfig ()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setId (int sceneId)
|
||||
{
|
||||
_model.sceneId = sceneId;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setName (String name)
|
||||
{
|
||||
_model.name = name;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setVersion (int version)
|
||||
{
|
||||
_model.version = version;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public SceneModel getSceneModel ()
|
||||
{
|
||||
return _model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
return "[model=" + _model + ", config=" + _config + "]";
|
||||
}
|
||||
|
||||
/** A reference to our scene model. */
|
||||
protected SceneModel _model;
|
||||
|
||||
/** A reference to our place configuration. */
|
||||
protected PlaceConfig _config;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneMarshaller.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
// $Id: SceneMarshaller.java,v 1.3 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.data;
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
import com.threerings.whirled.client.SceneService;
|
||||
import com.threerings.whirled.client.SceneService.SceneMoveListener;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link SceneService} interface
|
||||
@@ -17,10 +18,6 @@ import com.threerings.whirled.data.SceneModel;
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*
|
||||
* <p> Generated from <code>
|
||||
* $Id: SceneMarshaller.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
* </code>
|
||||
*/
|
||||
public class SceneMarshaller extends InvocationMarshaller
|
||||
implements SceneService
|
||||
@@ -41,15 +38,27 @@ public class SceneMarshaller extends InvocationMarshaller
|
||||
new Object[] { new Integer(arg1), arg2 }));
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #moveSucceededPlusUpdate}
|
||||
/** The method id used to dispatch {@link #moveSucceededWithUpdates}
|
||||
* responses. */
|
||||
public static final int MOVE_SUCCEEDED_PLUS_UPDATE = 2;
|
||||
public static final int MOVE_SUCCEEDED_WITH_UPDATES = 2;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceededPlusUpdate (int arg1, PlaceConfig arg2, SceneModel arg3)
|
||||
public void moveSucceededWithUpdates (int arg1, PlaceConfig arg2, SceneUpdate[] arg3)
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, MOVE_SUCCEEDED_PLUS_UPDATE,
|
||||
callerOid, requestId, MOVE_SUCCEEDED_WITH_UPDATES,
|
||||
new Object[] { new Integer(arg1), arg2, arg3 }));
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #moveSucceededWithScene}
|
||||
* responses. */
|
||||
public static final int MOVE_SUCCEEDED_WITH_SCENE = 3;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceededWithScene (int arg1, PlaceConfig arg2, SceneModel arg3)
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, MOVE_SUCCEEDED_WITH_SCENE,
|
||||
new Object[] { new Integer(arg1), arg2, arg3 }));
|
||||
}
|
||||
|
||||
@@ -62,8 +71,13 @@ public class SceneMarshaller extends InvocationMarshaller
|
||||
((Integer)args[0]).intValue(), (PlaceConfig)args[1]);
|
||||
return;
|
||||
|
||||
case MOVE_SUCCEEDED_PLUS_UPDATE:
|
||||
((SceneMoveListener)listener).moveSucceededPlusUpdate(
|
||||
case MOVE_SUCCEEDED_WITH_UPDATES:
|
||||
((SceneMoveListener)listener).moveSucceededWithUpdates(
|
||||
((Integer)args[0]).intValue(), (PlaceConfig)args[1], (SceneUpdate[])args[2]);
|
||||
return;
|
||||
|
||||
case MOVE_SUCCEEDED_WITH_SCENE:
|
||||
((SceneMoveListener)listener).moveSucceededWithScene(
|
||||
((Integer)args[0]).intValue(), (PlaceConfig)args[1], (SceneModel)args[2]);
|
||||
return;
|
||||
|
||||
@@ -86,5 +100,5 @@ public class SceneMarshaller extends InvocationMarshaller
|
||||
});
|
||||
}
|
||||
|
||||
// Class file generated on 12:33:06 08/20/02.
|
||||
// Generated on 14:44:07 02/08/03.
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
//
|
||||
// $Id: SceneModel.java,v 1.8 2002/07/23 05:54:52 mdb Exp $
|
||||
// $Id: SceneModel.java,v 1.9 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.data;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
|
||||
/**
|
||||
* The scene model is the bare bones representation of the data for a
|
||||
* scene in the Whirled system. From the scene model, one would create an
|
||||
* instance of {@link com.threerings.whirled.server.RuntimeScene}, {@link
|
||||
* com.threerings.whirled.client.DisplayScene} or {@link
|
||||
* com.threerings.whirled.tools.EditableScene}.
|
||||
* instance of {@link Scene}.
|
||||
*
|
||||
* <p> The scene model is what is loaded from the scene repositories and
|
||||
* what is transmitted over the wire when communicating scenes from the
|
||||
@@ -25,7 +23,7 @@ public class SceneModel extends SimpleStreamableObject
|
||||
public int sceneId;
|
||||
|
||||
/** The human readable name of this scene. */
|
||||
public String sceneName;
|
||||
public String name;
|
||||
|
||||
/** The version number of this scene. Versions are incremented
|
||||
* whenever modifications are made to a scene so that clients can
|
||||
@@ -33,18 +31,15 @@ public class SceneModel extends SimpleStreamableObject
|
||||
* scene. */
|
||||
public int version;
|
||||
|
||||
/** The scene ids of the scenes that neighbor this scene. A neighbor
|
||||
* is a scene that can be entered from this scene. */
|
||||
public int[] neighborIds;
|
||||
/** Auxiliary scene model information. */
|
||||
public AuxModel[] auxModels = new AuxModel[0];
|
||||
|
||||
/**
|
||||
* Generates a string representation of this scene model.
|
||||
* Adds the specified auxiliary model to this scene model.
|
||||
*/
|
||||
public String toString ()
|
||||
public void addAuxModel (AuxModel auxModel)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("[");
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
auxModels = (AuxModel[])ArrayUtil.append(auxModels, auxModel);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -52,22 +47,13 @@ public class SceneModel extends SimpleStreamableObject
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
SceneModel model = (SceneModel)super.clone();
|
||||
model.neighborIds = (int[])neighborIds.clone();
|
||||
model.auxModels = new AuxModel[auxModels.length];
|
||||
for (int ii = 0; ii < auxModels.length; ii++) {
|
||||
model.auxModels[ii] = (AuxModel)auxModels[ii].clone();
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes override this to tack their <code>toString</code>
|
||||
* data on to the string buffer.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("sceneId=").append(sceneId);
|
||||
buf.append(", name=").append(sceneName);
|
||||
buf.append(", version=").append(version);
|
||||
buf.append(", neighborIds=").append(StringUtil.toString(neighborIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a blank scene model.
|
||||
*/
|
||||
@@ -84,8 +70,7 @@ public class SceneModel extends SimpleStreamableObject
|
||||
protected static void populateBlankSceneModel (SceneModel model)
|
||||
{
|
||||
model.sceneId = -1;
|
||||
model.sceneName = "<blank>";
|
||||
model.name = "<blank>";
|
||||
model.version = 0;
|
||||
model.neighborIds = new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
//
|
||||
// $Id: SceneUpdate.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.data;
|
||||
|
||||
import com.threerings.io.Streamable;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
|
||||
/**
|
||||
* Used to encapsulate updates to scenes in such a manner that updates can
|
||||
* be stored persistently and sent to clients to update their own local
|
||||
* copies of scenes.
|
||||
*/
|
||||
public abstract class SceneUpdate
|
||||
implements Streamable, Cloneable
|
||||
{
|
||||
/**
|
||||
* Creates a scene update that will operate on a scene with the
|
||||
* specified target scene and version number.
|
||||
*
|
||||
* @param targetId the id of the scene on which we are to operate.
|
||||
* @param targetVersion the version of the scene on which we are to
|
||||
* operate.
|
||||
*/
|
||||
public SceneUpdate (int targetId, int targetVersion)
|
||||
{
|
||||
_targetId = targetId;
|
||||
_targetVersion = targetVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scene id for which this update is appropriate.
|
||||
*/
|
||||
public int getSceneId ()
|
||||
{
|
||||
return _targetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scene version for which this update is appropriate.
|
||||
*/
|
||||
public int getSceneVersion ()
|
||||
{
|
||||
return _targetVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to ensure that the scene is in the appropriate state prior
|
||||
* to applying the update.
|
||||
*
|
||||
* @exception IllegalStateException thrown if the update cannot be
|
||||
* applied to the scene because it is not in a valid state
|
||||
* (appropriate previous updates were not applied, it's the wrong kind
|
||||
* of scene, etc.).
|
||||
*/
|
||||
public void validate (SceneModel model)
|
||||
throws IllegalStateException
|
||||
{
|
||||
if (model.sceneId != _targetId) {
|
||||
String errmsg = "Wrong target scene, expected id " +
|
||||
_targetId + " got id " + model.sceneId;
|
||||
throw new IllegalStateException(errmsg);
|
||||
}
|
||||
if (model.version != _targetVersion) {
|
||||
String errmsg = "Target scene not proper version, expected " +
|
||||
_targetVersion + " got " + model.version;
|
||||
throw new IllegalStateException(errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies this update to the specified scene model. Derived classes
|
||||
* will want to override this method and apply updates of their own,
|
||||
* being sure to call <code>super.applyToScene</code>.
|
||||
*/
|
||||
public void apply (SceneModel model)
|
||||
{
|
||||
// increment the version; disallowing integer overflow
|
||||
model.version = Math.max(_targetVersion + 1, model.version);
|
||||
|
||||
// sanity check for the amazing two billion updates
|
||||
if (model.version == _targetVersion) {
|
||||
Log.warning("Egads! This scene has been updated two billion " +
|
||||
"times [model=" + model + ", update=" + this + "].");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this instance.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("[");
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An extensible mechanism for generating a string representation of
|
||||
* this instance.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("sceneId=").append(_targetId);
|
||||
buf.append(", version=").append(_targetVersion);
|
||||
}
|
||||
|
||||
/** The version number of the scene on which we operate. */
|
||||
protected int _targetId;
|
||||
|
||||
/** The version number of the scene on which we operate. */
|
||||
protected int _targetVersion;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// $Id: DefaultRuntimeSceneFactory.java,v 1.1 2001/11/12 20:56:56 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
import com.threerings.whirled.data.DefaultSceneConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* The default runtime scene factory creates {@link RuntimeSceneImpl}
|
||||
* instances with {@link DefaultSceneConfig} instances (which create the
|
||||
* default scene manager and controller).
|
||||
*/
|
||||
public class DefaultRuntimeSceneFactory implements RuntimeSceneFactory
|
||||
{
|
||||
// documentation inherited
|
||||
public RuntimeScene createScene (SceneModel model)
|
||||
{
|
||||
return new RuntimeSceneImpl(model, new DefaultSceneConfig());
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
//
|
||||
// $Id: RuntimeScene.java,v 1.3 2003/02/04 17:25:09 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
/**
|
||||
* This interface makes available the scene information that is needed by
|
||||
* the server to manage a scene. At this basic level, not much information
|
||||
* is available, but extensions to this interface begin to create a more
|
||||
* comprehensive picture of a scene in a system built from the Whirled
|
||||
* services.
|
||||
*
|
||||
* <p> Additionally, at this basic level, the <code>RuntimeScene</code>
|
||||
* does not differ greatly (or at all) from the {@link
|
||||
* com.threerings.whirled.client.DisplayScene} interface, but the
|
||||
* distinction provides a mechanism for handling the more substantial
|
||||
* differences that appear in more sophisticated extensions to the base
|
||||
* scene services.
|
||||
*/
|
||||
public interface RuntimeScene
|
||||
{
|
||||
/**
|
||||
* Returns the unique identifier for this scene.
|
||||
*/
|
||||
public int getId ();
|
||||
|
||||
/**
|
||||
* Returns the human readable name of this scene.
|
||||
*/
|
||||
public String getName ();
|
||||
|
||||
/**
|
||||
* Returns the version number of this scene.
|
||||
*/
|
||||
public int getVersion ();
|
||||
|
||||
/**
|
||||
* Updates the version number of this scene and immediately updates
|
||||
* our associated scene model.
|
||||
*/
|
||||
public void setVersion (int version);
|
||||
|
||||
/**
|
||||
* Returns the list of scene ids of this scene's neighbors.
|
||||
*/
|
||||
public int[] getNeighborIds ();
|
||||
|
||||
/**
|
||||
* Returns the place config that can be used to determine which place
|
||||
* controller instance should be used to display this scene as well as
|
||||
* to obtain runtime configuration information.
|
||||
*/
|
||||
public PlaceConfig getPlaceConfig ();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
//
|
||||
// $Id: RuntimeSceneFactory.java,v 1.1 2001/11/12 20:56:56 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* When resolving a scene, the scene registry loads scene models from the
|
||||
* scene repository, but it needs an external entity to convert those
|
||||
* scene models into the appropriate implementation of {@link
|
||||
* RuntimeScene}. The runtime scene factory interface provides the
|
||||
* mechanism by which users of the Whirled system can create the
|
||||
* appropriate instances.
|
||||
*/
|
||||
public interface RuntimeSceneFactory
|
||||
{
|
||||
/**
|
||||
* This is called by the scene registry after it has loaded the scene
|
||||
* model from the scene repository. The factory implementation is
|
||||
* required to know what derivation of {@link
|
||||
* com.threerings.crowd.data.PlaceConfig} should go along with the
|
||||
* supplied scene model in order to create a {@link RuntimeScene}
|
||||
* implementation. The expectation is that such information is either
|
||||
* static or can be obtained from the scene model provided to this
|
||||
* method.
|
||||
*/
|
||||
public RuntimeScene createScene (SceneModel model);
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
//
|
||||
// $Id: RuntimeSceneImpl.java,v 1.3 2003/02/04 17:25:09 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* A basic implementation of the {@link RuntimeScene} interface which is
|
||||
* used by default if no extended implementation is desired.
|
||||
*/
|
||||
public class RuntimeSceneImpl implements RuntimeScene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and place config.
|
||||
*/
|
||||
public RuntimeSceneImpl (SceneModel model, PlaceConfig config)
|
||||
{
|
||||
_model = model;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getId ()
|
||||
{
|
||||
return _model.sceneId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getName ()
|
||||
{
|
||||
return _model.sceneName;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getVersion ()
|
||||
{
|
||||
return _model.version;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setVersion (int version)
|
||||
{
|
||||
_model.version = version;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int[] getNeighborIds ()
|
||||
{
|
||||
return _model.neighborIds;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public PlaceConfig getPlaceConfig ()
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
/** A reference to our scene model. */
|
||||
protected SceneModel _model;
|
||||
|
||||
/** A reference to our place configuration. */
|
||||
protected PlaceConfig _config;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneDispatcher.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
// $Id: SceneDispatcher.java,v 1.3 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
@@ -13,13 +13,10 @@ import com.threerings.whirled.client.SceneService;
|
||||
import com.threerings.whirled.client.SceneService.SceneMoveListener;
|
||||
import com.threerings.whirled.data.SceneMarshaller;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link SceneProvider}.
|
||||
*
|
||||
* <p> Generated from <code>
|
||||
* $Id: SceneDispatcher.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
* </code>
|
||||
*/
|
||||
public class SceneDispatcher extends InvocationDispatcher
|
||||
{
|
||||
@@ -55,4 +52,6 @@ public class SceneDispatcher extends InvocationDispatcher
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
}
|
||||
}
|
||||
|
||||
// Generated on 14:44:07 02/08/03.
|
||||
}
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
//
|
||||
// $Id: SceneManager.java,v 1.11 2003/02/05 00:23:52 mdb Exp $
|
||||
// $Id: SceneManager.java,v 1.12 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
import com.samskivert.io.PersistenceException;
|
||||
|
||||
import com.threerings.crowd.server.PlaceManager;
|
||||
import com.threerings.presents.util.Invoker;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.data.Scene;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
import com.threerings.whirled.server.WhirledServer;
|
||||
import com.threerings.whirled.util.UpdateList;
|
||||
|
||||
/**
|
||||
* The scene manager extends the place manager and takes care of basic
|
||||
@@ -15,37 +24,36 @@ import com.threerings.whirled.data.SceneModel;
|
||||
public class SceneManager extends PlaceManager
|
||||
{
|
||||
/**
|
||||
* Returns the runtime scene object (not the scene distributed object)
|
||||
* being managed by this scene manager.
|
||||
* Returns the scene object (not the scene distributed object) being
|
||||
* managed by this scene manager.
|
||||
*/
|
||||
public RuntimeScene getScene ()
|
||||
public Scene getScene ()
|
||||
{
|
||||
return _scene;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the scene model from which we created our
|
||||
* runtime scene object. This model must reflect any modifications
|
||||
* this manager may have made to it in the course of managing the
|
||||
* scene as it will be provided to the client as the definitive
|
||||
* version of the scene. (The scene manager is responsible for writing
|
||||
* changes made to the scene model back to the scene repository.)
|
||||
*/
|
||||
public SceneModel getSceneModel ()
|
||||
{
|
||||
return _model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the scene registry once the scene manager has been
|
||||
* created (and initialized), but before it is started up.
|
||||
*/
|
||||
protected void setSceneData (
|
||||
RuntimeScene scene, SceneModel model, SceneRegistry screg)
|
||||
protected void setSceneData (Scene scene, UpdateList updates,
|
||||
SceneRegistry screg)
|
||||
{
|
||||
// make sure the list and our version of the scene are in
|
||||
// accordance
|
||||
if (!updates.validate(scene.getVersion())) {
|
||||
Log.warning("Provided with invalid updates; flushing " +
|
||||
"[where=" + where() +
|
||||
", sceneId=" + scene.getId() + "].");
|
||||
// clear out the update list as it will not allow us to bring
|
||||
// clients up to date with our current scene version; instead
|
||||
// they'll have to download the whole thing
|
||||
updates = new UpdateList();
|
||||
}
|
||||
|
||||
_scene = scene;
|
||||
_model = model;
|
||||
_screg = screg;
|
||||
_updates = updates;
|
||||
|
||||
// let derived classes react to the receipt of scene data
|
||||
gotSceneData();
|
||||
@@ -85,10 +93,45 @@ public class SceneManager extends PlaceManager
|
||||
_screg.unmapSceneManager(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* When a modification is made to a scene, the scene manager should
|
||||
* update its internal structures, update the {@link Scene} object,
|
||||
* update the repository (either by storing the updated scene
|
||||
* wholesale or more efficiently updating only what has changed), and
|
||||
* then it should create a {@link SceneUpdate} record that can be
|
||||
* delivered to clients to effect the update to the clients's cached
|
||||
* copy of the scene model. This update will be stored persistently
|
||||
* and provided (along with any other accumulated updates) to clients
|
||||
* that later request to enter the scene with an old version of the
|
||||
* scene data. Updates are not stored forever, but a sizable number of
|
||||
* recent updates are stored so that moderately current clients can
|
||||
* apply incremental patches to their scenes rather than redownloading
|
||||
* the entire scenes when they change.
|
||||
*/
|
||||
protected void recordUpdate (final SceneUpdate update)
|
||||
{
|
||||
// add it to our in memory update list
|
||||
_updates.addUpdate(update);
|
||||
|
||||
// and store it in the repository
|
||||
WhirledServer.invoker.postUnit(new Invoker.Unit() {
|
||||
public boolean invoke () {
|
||||
try {
|
||||
_screg.getSceneRepository().addUpdate(update);
|
||||
} catch (PersistenceException pe) {
|
||||
Log.warning("Failed to store scene update " +
|
||||
"[update=" + update + ", error=" + pe + "].");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String where ()
|
||||
{
|
||||
return _scene.getName() + " (" + super.where() + ")";
|
||||
return _scene.getName() + " (" + super.where() + ":" +
|
||||
_scene.getId() + ")";
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -98,15 +141,14 @@ public class SceneManager extends PlaceManager
|
||||
buf.append(", scene=").append(_scene);
|
||||
}
|
||||
|
||||
/** A reference to our runtime scene implementation which provides a
|
||||
/** A reference to our scene implementation which provides a
|
||||
* meaningful interpretation of the data in the scene model. */
|
||||
protected RuntimeScene _scene;
|
||||
protected Scene _scene;
|
||||
|
||||
/** A reference to the scene model which we keep around because we may
|
||||
* have to send it to clients that need updated versions of the model
|
||||
* or to update the scene model in the repository if we modify the
|
||||
* scene for some reason. */
|
||||
protected SceneModel _model;
|
||||
/** A list of the updates tracked for this scene. These will be used
|
||||
* to attempt to bring clients up to date efficiently if they request
|
||||
* to enter our scene with old scene model data. */
|
||||
protected UpdateList _updates;
|
||||
|
||||
/** A reference to the scene registry so that we can call back to it
|
||||
* when we're fully initialized. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneProvider.java,v 1.14 2002/12/14 01:51:00 mdb Exp $
|
||||
// $Id: SceneProvider.java,v 1.15 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
@@ -104,9 +104,9 @@ public class SceneProvider
|
||||
((ScenedBodyObject)source).setSceneId(scmgr.getScene().getId());
|
||||
|
||||
// check to see if they need a newer version of the scene data
|
||||
SceneModel model = scmgr.getSceneModel();
|
||||
SceneModel model = scmgr.getScene().getSceneModel();
|
||||
if (sceneVersion < model.version) {
|
||||
listener.moveSucceededPlusUpdate(ploid, config, model);
|
||||
listener.moveSucceededWithScene(ploid, config, model);
|
||||
} else {
|
||||
listener.moveSucceeded(ploid, config);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneRegistry.java,v 1.17 2002/10/06 00:44:58 mdb Exp $
|
||||
// $Id: SceneRegistry.java,v 1.18 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
@@ -11,19 +11,23 @@ import com.threerings.presents.util.Invoker;
|
||||
|
||||
import com.threerings.presents.server.InvocationManager;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.crowd.server.CrowdServer;
|
||||
import com.threerings.crowd.server.PlaceManager;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.data.Scene;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneObject;
|
||||
import com.threerings.whirled.server.persist.SceneRepository;
|
||||
import com.threerings.whirled.util.SceneFactory;
|
||||
import com.threerings.whirled.util.UpdateList;
|
||||
|
||||
/**
|
||||
* The scene registry is responsible for the management of all runtime
|
||||
* scenes. It handles interaction with the scene repository and ensures
|
||||
* that scenes are loaded into memory when needed and flushed from memory
|
||||
* when not needed.
|
||||
* The scene registry is responsible for the management of all scenes. It
|
||||
* handles interaction with the scene repository and ensures that scenes
|
||||
* are loaded into memory when needed and flushed from memory when not
|
||||
* needed.
|
||||
*
|
||||
* <p> The scene repository also takes care of bridging from the blocking,
|
||||
* synchronous world of the scene repository to the non-blocking
|
||||
@@ -37,6 +41,18 @@ import com.threerings.whirled.server.persist.SceneRepository;
|
||||
*/
|
||||
public class SceneRegistry
|
||||
{
|
||||
/**
|
||||
* Used to create {@link PlaceConfig} instances for scenes.
|
||||
*/
|
||||
public static interface ConfigFactory
|
||||
{
|
||||
/**
|
||||
* Creates the place config instance appropriate to the specified
|
||||
* scene.
|
||||
*/
|
||||
PlaceConfig createPlaceConfig (SceneModel model);
|
||||
}
|
||||
|
||||
/** Used to provide scene-related server-side services. */
|
||||
public SceneProvider sceneprov;
|
||||
|
||||
@@ -44,28 +60,18 @@ public class SceneRegistry
|
||||
* Constructs a scene registry, instructing it to load and store
|
||||
* scenes using the supplied scene repository.
|
||||
*/
|
||||
public SceneRegistry (InvocationManager invmgr, SceneRepository screp)
|
||||
public SceneRegistry (InvocationManager invmgr, SceneRepository screp,
|
||||
SceneFactory scfact, ConfigFactory confact)
|
||||
{
|
||||
_screp = screp;
|
||||
|
||||
// use a default runtime scene factory for now; assume that
|
||||
// containing systems will call setRuntimeSceneFactory() later
|
||||
_scfact = new DefaultRuntimeSceneFactory();
|
||||
_scfact = scfact;
|
||||
_confact = confact;
|
||||
|
||||
// create/register a scene provider with the invocation services
|
||||
sceneprov = new SceneProvider(CrowdServer.plreg.locprov, this);
|
||||
invmgr.registerDispatcher(new SceneDispatcher(sceneprov), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the scene registry to use the supplied factory to create
|
||||
* runtime scene instances from scene models.
|
||||
*/
|
||||
public void setRuntimeSceneFactory (RuntimeSceneFactory factory)
|
||||
{
|
||||
_scfact = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the scene manager assosciated with the specified scene.
|
||||
*
|
||||
@@ -77,6 +83,15 @@ public class SceneRegistry
|
||||
return (SceneManager)_scenemgrs.get(sceneId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the scene repository in use by this
|
||||
* registry.
|
||||
*/
|
||||
public SceneRepository getSceneRepository ()
|
||||
{
|
||||
return _screp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Because scenes must be loaded from the scene repository and this
|
||||
* must not be done on the dobjmgr thread, the interface for resolving
|
||||
@@ -155,6 +170,7 @@ public class SceneRegistry
|
||||
{
|
||||
try {
|
||||
_model = _screp.loadSceneModel(fsceneId);
|
||||
_updates = _screp.loadUpdates(fsceneId);
|
||||
} catch (Exception e) {
|
||||
_cause = e;
|
||||
}
|
||||
@@ -165,7 +181,7 @@ public class SceneRegistry
|
||||
public void handleResult ()
|
||||
{
|
||||
if (_model != null) {
|
||||
processSuccessfulResolution(_model);
|
||||
processSuccessfulResolution(_model, _updates);
|
||||
} else if (_cause != null) {
|
||||
processFailedResolution(fsceneId, _cause);
|
||||
} else {
|
||||
@@ -176,6 +192,7 @@ public class SceneRegistry
|
||||
}
|
||||
|
||||
protected SceneModel _model;
|
||||
protected UpdateList _updates;
|
||||
protected Exception _cause;
|
||||
});
|
||||
}
|
||||
@@ -184,7 +201,8 @@ public class SceneRegistry
|
||||
/**
|
||||
* Called when the scene resolution has completed successfully.
|
||||
*/
|
||||
protected void processSuccessfulResolution (SceneModel model)
|
||||
protected void processSuccessfulResolution (
|
||||
SceneModel model, UpdateList updates)
|
||||
{
|
||||
// now that the scene is loaded, we can create a scene manager for
|
||||
// it. that will be initialized by the place registry and when
|
||||
@@ -192,18 +210,14 @@ public class SceneRegistry
|
||||
// what's up
|
||||
|
||||
try {
|
||||
// first create our runtime scene instance
|
||||
RuntimeScene scene = _scfact.createScene(model);
|
||||
// first create our scene instance
|
||||
Scene scene = _scfact.createScene(
|
||||
model, _confact.createPlaceConfig(model));
|
||||
|
||||
// now create our scene manager
|
||||
SceneManager scmgr = (SceneManager)
|
||||
CrowdServer.plreg.createPlace(scene.getPlaceConfig(), null);
|
||||
|
||||
// configure the scene manager with references to useful
|
||||
// stuff; we'll somehow need to convey configuration
|
||||
// information for the scene to the scene manager, but for now
|
||||
// let's punt
|
||||
scmgr.setSceneData(scene, model, this);
|
||||
scmgr.setSceneData(scene, updates, this);
|
||||
|
||||
// when the scene manager completes its startup procedings, it
|
||||
// will call back to the scene registry and let us know that
|
||||
@@ -282,9 +296,12 @@ public class SceneRegistry
|
||||
/** The entity from which we load scene models. */
|
||||
protected SceneRepository _screp;
|
||||
|
||||
/** The entity via which we create runtime scene instances from scene
|
||||
/** Used to generate place configs for our scenes. */
|
||||
protected ConfigFactory _confact;
|
||||
|
||||
/** The entity via which we create scene instances from scene
|
||||
* models. */
|
||||
protected RuntimeSceneFactory _scfact;
|
||||
protected SceneFactory _scfact;
|
||||
|
||||
/** A mapping from scene ids to scene managers. */
|
||||
protected HashIntMap _scenemgrs = new HashIntMap();
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
//
|
||||
// $Id: WhirledServer.java,v 1.15 2002/10/21 20:56:21 mdb Exp $
|
||||
// $Id: WhirledServer.java,v 1.16 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server;
|
||||
|
||||
import com.threerings.crowd.server.CrowdServer;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.server.persist.SceneRepository;
|
||||
import com.threerings.whirled.server.persist.DummySceneRepository;
|
||||
import com.threerings.whirled.server.persist.SceneRepository;
|
||||
import com.threerings.whirled.util.SceneFactory;
|
||||
|
||||
/**
|
||||
* The whirled server extends the {@link CrowdServer} and provides access
|
||||
* to managers and the like that are needed by the Whirled serviecs.
|
||||
*/
|
||||
public class WhirledServer extends CrowdServer
|
||||
public abstract class WhirledServer extends CrowdServer
|
||||
{
|
||||
/** The scene registry. */
|
||||
public static SceneRegistry screg;
|
||||
@@ -34,25 +35,39 @@ public class WhirledServer extends CrowdServer
|
||||
_screp = createSceneRepository();
|
||||
|
||||
// create our scene registry
|
||||
screg = new SceneRegistry(invmgr, _screp);
|
||||
screg = new SceneRegistry(invmgr, _screp, createSceneFactory(),
|
||||
createConfigFactory());
|
||||
|
||||
Log.info("Whirled server initialized.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the scene repository that will be used by this server. If a
|
||||
* derived class wishes to use a particular kind of scene repository
|
||||
* (which they most likely will), they should override this method and
|
||||
* instantiate the scene repository of their choosing.
|
||||
* Creates the scene repository that will be used by this server.
|
||||
*
|
||||
* @exception Exception thrown if any error occurs while instantiating
|
||||
* or initializing the scene repository.
|
||||
*/
|
||||
protected SceneRepository createSceneRepository ()
|
||||
throws Exception
|
||||
{
|
||||
return new DummySceneRepository();
|
||||
}
|
||||
protected abstract SceneRepository createSceneRepository ()
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* Creates the scene factory that will be used by our scene registry.
|
||||
*
|
||||
* @exception Exception thrown if any error occurs while instantiating
|
||||
* or initializing the scene repository.
|
||||
*/
|
||||
protected abstract SceneFactory createSceneFactory ()
|
||||
throws Exception;
|
||||
|
||||
/**
|
||||
* Creates the place config factory that will be used our scene
|
||||
* registry.
|
||||
*
|
||||
* @exception Exception thrown if any error occurs while instantiating
|
||||
* or initializing the scene repository.
|
||||
*/
|
||||
protected abstract SceneRegistry.ConfigFactory createConfigFactory ()
|
||||
throws Exception;
|
||||
|
||||
/** The scene repository in use by this server. */
|
||||
protected SceneRepository _screp;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: DummySceneRepository.java,v 1.7 2001/11/12 20:56:56 mdb Exp $
|
||||
// $Id: DummySceneRepository.java,v 1.8 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server.persist;
|
||||
|
||||
@@ -7,7 +7,9 @@ import com.samskivert.io.PersistenceException;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
import com.threerings.whirled.util.NoSuchSceneException;
|
||||
import com.threerings.whirled.util.UpdateList;
|
||||
|
||||
/**
|
||||
* The dummy scene repository just pretends to load and store scenes, but
|
||||
@@ -21,18 +23,18 @@ public class DummySceneRepository implements SceneRepository
|
||||
throws PersistenceException, NoSuchSceneException
|
||||
{
|
||||
Log.info("Creating dummy scene [id=" + sceneId + "].");
|
||||
|
||||
// create a blank scene model
|
||||
SceneModel model = new SceneModel();
|
||||
model.sceneId = sceneId;
|
||||
model.version = 1;
|
||||
model.neighborIds = new int[0];
|
||||
|
||||
return model;
|
||||
return SceneModel.blankSceneModel();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void updateSceneModel (SceneModel model)
|
||||
// documentation inherited from interface
|
||||
public UpdateList loadUpdates (int sceneId)
|
||||
throws PersistenceException, NoSuchSceneException
|
||||
{
|
||||
return new UpdateList();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void addUpdate (SceneUpdate update)
|
||||
throws PersistenceException
|
||||
{
|
||||
// nothing doing
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
//
|
||||
// $Id: SceneRepository.java,v 1.5 2001/11/12 20:56:56 mdb Exp $
|
||||
// $Id: SceneRepository.java,v 1.6 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.server.persist;
|
||||
|
||||
import com.samskivert.io.PersistenceException;
|
||||
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
import com.threerings.whirled.util.NoSuchSceneException;
|
||||
import com.threerings.whirled.util.UpdateList;
|
||||
|
||||
/**
|
||||
* The scene repository provides the basic interface for loading and
|
||||
@@ -29,11 +31,23 @@ public interface SceneRepository
|
||||
throws PersistenceException, NoSuchSceneException;
|
||||
|
||||
/**
|
||||
* Updates the specified scene model in the repository.
|
||||
* Fetches the set of updates associated with the specified scene.
|
||||
*
|
||||
* @exception PersistenceException thrown if an error occurs
|
||||
* attempting to update the scene data.
|
||||
* attempting to load the scene updates.
|
||||
* @exception NoSuchSceneException thrown if no scene exists with the
|
||||
* specified scene id.
|
||||
*/
|
||||
public void updateSceneModel (SceneModel scene)
|
||||
public UpdateList loadUpdates (int sceneId)
|
||||
throws PersistenceException, NoSuchSceneException;
|
||||
|
||||
/**
|
||||
* Adds the supplied scene update to the list of updates for its
|
||||
* associated scene.
|
||||
*
|
||||
* @exception PersistenceException thrown if an error occurs
|
||||
* attempting to store the scene update.
|
||||
*/
|
||||
public void addUpdate (SceneUpdate update)
|
||||
throws PersistenceException;
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
//
|
||||
// $Id: DisplaySpotScene.java,v 1.4 2001/12/16 21:22:30 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.threerings.whirled.client.DisplayScene;
|
||||
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
|
||||
/**
|
||||
* Makes available the spot scene information that the client needs to
|
||||
* display a spot scene, to make requests to the server to move from
|
||||
* location to location and to neighboring scenes and to display the same.
|
||||
*/
|
||||
public interface DisplaySpotScene extends DisplayScene
|
||||
{
|
||||
/**
|
||||
* Returns the location id of the default entrance to this scene.
|
||||
*/
|
||||
public int getDefaultEntranceId ();
|
||||
|
||||
/**
|
||||
* Returns a list of the locations in this scene (including portals
|
||||
* which will be instances of {@link Portal}).
|
||||
*/
|
||||
public List getLocations ();
|
||||
|
||||
/**
|
||||
* Convenience function for obtaining a location's index in the
|
||||
* location list given its id.
|
||||
*
|
||||
* @return the location's index or -1 if a location with the specified
|
||||
* id is not in this scene's location list.
|
||||
*/
|
||||
public int getLocationIndex (int locationId);
|
||||
|
||||
/**
|
||||
* Convenience funtion for looking up a location by id.
|
||||
*/
|
||||
public Location getLocation (int locationId);
|
||||
|
||||
/**
|
||||
* Returns a list of the portals in this scene.
|
||||
*/
|
||||
public List getPortals ();
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
//
|
||||
// $Id: DisplaySpotSceneImpl.java,v 1.5 2001/12/16 21:22:30 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.client.DisplaySceneImpl;
|
||||
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
/**
|
||||
* A basic implementation of the {@link DisplaySpotScene} interface which
|
||||
* is used by default if no extended implementation is desired.
|
||||
*/
|
||||
public class DisplaySpotSceneImpl extends DisplaySceneImpl
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and place config.
|
||||
*/
|
||||
public DisplaySpotSceneImpl (SpotSceneModel model, PlaceConfig config)
|
||||
{
|
||||
super(model, config);
|
||||
|
||||
// keep a casted reference to our model around
|
||||
_model = model;
|
||||
|
||||
// sort out our locations and portals
|
||||
int lcount = model.locationIds.length;
|
||||
int pcount = model.portalIds.length;
|
||||
_portals = new ArrayList(pcount);
|
||||
_locations = new ArrayList(lcount - pcount);
|
||||
|
||||
// because the portals ids are in the same order as the location
|
||||
// ids, we can parse them in one pass
|
||||
int pidx = 0;
|
||||
for (int i = 0; i < lcount; i++) {
|
||||
Location loc;
|
||||
// stop checking for portals once we've parsed them all
|
||||
int pid = (pidx < pcount) ? model.portalIds[pidx] : -1;
|
||||
|
||||
if (model.locationIds[i] == pid) {
|
||||
// add this portal to the portals array
|
||||
Portal port = new Portal();
|
||||
populatePortal(model, port, i, pidx);
|
||||
_portals.add(port);;
|
||||
loc = port;
|
||||
pidx++;
|
||||
|
||||
} else {
|
||||
loc = new Location();
|
||||
populateLocation(model, loc, i);
|
||||
}
|
||||
|
||||
// everything goes into the locations array
|
||||
_locations.add(loc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a location instance with the specified index, using
|
||||
* information from the model.
|
||||
*
|
||||
* @param model the scene model.
|
||||
* @param loc the location instance to populate.
|
||||
* @param lidx the location index in the model arrays.
|
||||
*/
|
||||
protected void populateLocation (
|
||||
SpotSceneModel model, Location loc, int lidx)
|
||||
{
|
||||
loc.locationId = model.locationIds[lidx];
|
||||
loc.x = model.locationX[lidx];
|
||||
loc.y = model.locationY[lidx];
|
||||
loc.orientation = model.locationOrients[lidx];
|
||||
loc.clusterIndex = model.locationClusters[lidx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a portal instance with the specified index, using
|
||||
* information from the model.
|
||||
*
|
||||
* @param model the scene model.
|
||||
* @param port the portal to populate.
|
||||
* @param lidx the location index in the model arrays.
|
||||
* @param pidx the portal index in the model arrays.
|
||||
*/
|
||||
protected void populatePortal (
|
||||
SpotSceneModel model, Portal port, int lidx, int pidx)
|
||||
{
|
||||
// populate the location fields
|
||||
populateLocation(model, port, lidx);
|
||||
|
||||
// populate the portal-specific fields
|
||||
port.targetSceneId = model.neighborIds[pidx];
|
||||
port.targetLocId = model.targetLocIds[pidx];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getDefaultEntranceId ()
|
||||
{
|
||||
return _model.defaultEntranceId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public List getLocations ()
|
||||
{
|
||||
return _locations;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getLocationIndex (int locationId)
|
||||
{
|
||||
int lsize = _locations.size();
|
||||
for (int i = 0; i < lsize; i++) {
|
||||
Location loc = (Location)_locations.get(i);
|
||||
if (loc.locationId == locationId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Location getLocation (int locationId)
|
||||
{
|
||||
int lsize = _locations.size();
|
||||
for (int i = 0; i < lsize; i++) {
|
||||
Location loc = (Location)_locations.get(i);
|
||||
if (loc.locationId == locationId) {
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public List getPortals ()
|
||||
{
|
||||
return _portals;
|
||||
}
|
||||
|
||||
/** The data that makes up our scene. */
|
||||
protected SpotSceneModel _model;
|
||||
|
||||
/** A list of the locations (and portals) in this scene. */
|
||||
protected ArrayList _locations;
|
||||
|
||||
/** A list of just the portals in this scene. */
|
||||
protected ArrayList _portals;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SpotSceneDirector.java,v 1.20 2003/01/03 23:07:00 shaper Exp $
|
||||
// $Id: SpotSceneDirector.java,v 1.21 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.client;
|
||||
|
||||
@@ -9,6 +9,8 @@ import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.client.BasicDirector;
|
||||
import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.dobj.AttributeChangeListener;
|
||||
import com.threerings.presents.dobj.AttributeChangedEvent;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.DObjectManager;
|
||||
@@ -26,16 +28,19 @@ import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.util.WhirledContext;
|
||||
|
||||
import com.threerings.whirled.spot.Log;
|
||||
import com.threerings.whirled.spot.data.ClusteredBodyObject;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SpotCodes;
|
||||
import com.threerings.whirled.spot.data.SpotScene;
|
||||
|
||||
/**
|
||||
* Extends the standard scene director with facilities to move between
|
||||
* locations within a scene.
|
||||
*/
|
||||
public class SpotSceneDirector extends BasicDirector
|
||||
implements SpotCodes, Subscriber, SpotService.ChangeLocListener
|
||||
implements SpotCodes, Subscriber, SpotService.ChangeLocListener,
|
||||
AttributeChangeListener
|
||||
{
|
||||
/**
|
||||
* This is used to communicate back to the caller of {@link
|
||||
@@ -46,13 +51,13 @@ public class SpotSceneDirector extends BasicDirector
|
||||
/**
|
||||
* Indicates that the requested location change succeeded.
|
||||
*/
|
||||
public void locationChangeSucceeded (int locationId);
|
||||
public void locationChangeSucceeded (Location loc);
|
||||
|
||||
/**
|
||||
* Indicates that the requested location change failed and
|
||||
* provides a reason code explaining the failure.
|
||||
*/
|
||||
public void locationChangeFailed (int locationId, String reason);
|
||||
public void locationChangeFailed (Location loc, String reason);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +118,7 @@ public class SpotSceneDirector extends BasicDirector
|
||||
public boolean traversePortal (int portalId, ResultListener rl)
|
||||
{
|
||||
// look up the destination scene and location
|
||||
DisplaySpotScene scene = (DisplaySpotScene)_scdir.getScene();
|
||||
SpotScene scene = (SpotScene)_scdir.getScene();
|
||||
if (scene == null) {
|
||||
Log.warning("Requested to traverse portal when we have " +
|
||||
"no scene [portalId=" + portalId + "].");
|
||||
@@ -121,26 +126,16 @@ public class SpotSceneDirector extends BasicDirector
|
||||
}
|
||||
|
||||
// find the portal they're talking about
|
||||
int targetSceneId = -1, targetLocId = -1;
|
||||
Iterator portals = scene.getPortals().iterator();
|
||||
while (portals.hasNext()) {
|
||||
Portal portal = (Portal)portals.next();
|
||||
if (portal.locationId == portalId) {
|
||||
targetSceneId = portal.targetSceneId;
|
||||
targetLocId = portal.targetLocId;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we found the portal
|
||||
if (targetSceneId == -1) {
|
||||
portals = scene.getPortals().iterator();
|
||||
Portal dest = scene.getPortal(portalId);
|
||||
if (dest == null) {
|
||||
Log.warning("Requested to traverse non-existent portal " +
|
||||
"[portalId=" + portalId +
|
||||
", portals=" + StringUtil.toString(portals) + "].");
|
||||
"[portalId=" + portalId + ", portals=" +
|
||||
StringUtil.toString(scene.getPortals()) + "].");
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare to move to this scene (sets up pending data)
|
||||
if (!_scdir.prepareMoveTo(targetSceneId, rl)) {
|
||||
if (!_scdir.prepareMoveTo(dest.targetSceneId, rl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -154,53 +149,52 @@ public class SpotSceneDirector extends BasicDirector
|
||||
}
|
||||
|
||||
// issue a traversePortal request
|
||||
_sservice.traversePortal(
|
||||
_ctx.getClient(), scene.getId(), portalId, sceneVer, _scdir);
|
||||
_sservice.traversePortal(_ctx.getClient(), portalId, sceneVer, _scdir);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a request to change our location within the scene to the
|
||||
* location identified by the specified id. Most client entities find
|
||||
* out about location changes via changes to the occupant info data,
|
||||
* but the initiator of a location change request can be notified of
|
||||
* its success or failure, primarily so that it can act in
|
||||
* anticipation of a successful location change (like by starting a
|
||||
* sprite moving toward the new location), but backtrack if it finds
|
||||
* out that the location change failed.
|
||||
* specified location. Depending on the value of <code>cluster</code>
|
||||
* the client will be made to create a new cluster, join and existing
|
||||
* cluster or join no cluster at all.
|
||||
*
|
||||
* @param loc the new location to which to move.
|
||||
* @param cluster if zero, a new cluster will be created and assigned
|
||||
* to the calling user; if -1, the calling user will be removed from
|
||||
* any cluster they currently occupy and not made to occupy a new
|
||||
* cluster; if the bodyOid of another user, the calling user will be
|
||||
* made to join the target user's cluster.
|
||||
* @param obs will be notified of success or failure. Most client
|
||||
* entities find out about location changes via changes to the
|
||||
* occupant info data, but the initiator of a location change request
|
||||
* can be notified of its success or failure, primarily so that it can
|
||||
* act in anticipation of a successful location change (like by
|
||||
* starting a sprite moving toward the new location), but backtrack if
|
||||
* it finds out that the location change failed.
|
||||
*/
|
||||
public void changeLocation (int locationId, ChangeObserver obs)
|
||||
public void changeLocation (Location loc, int cluster, ChangeObserver obs)
|
||||
{
|
||||
// refuse if there's a pending location change or if we're already
|
||||
// at the specified location
|
||||
if ((locationId == _locationId) || (_pendingLocId != -1)) {
|
||||
if (loc.equals(_location) || (_pendingLoc != null)) {
|
||||
Log.info("Not going to " + loc + "; we're at " + _location +
|
||||
" and we're headed to " + _pendingLoc + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure we're currently in a scene
|
||||
DisplaySpotScene scene = (DisplaySpotScene)_scdir.getScene();
|
||||
SpotScene scene = (SpotScene)_scdir.getScene();
|
||||
if (scene == null) {
|
||||
Log.warning("Requested to change locations, but we're not " +
|
||||
"currently in any scene [locId=" + locationId + "].");
|
||||
"currently in any scene [loc=" + loc + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure the specified location is in the current scene
|
||||
Location loc = scene.getLocation(locationId);
|
||||
if (loc == null) {
|
||||
Log.warning("Requested to change to a location that's not " +
|
||||
"in the current scene [locs=" + StringUtil.toString(
|
||||
scene.getLocations().iterator()) +
|
||||
", locId=" + locationId + "].");
|
||||
return;
|
||||
}
|
||||
Log.info("Changing location [loc=" + loc + ", clus=" + cluster + "].");
|
||||
|
||||
// make a note that we're changing to this location
|
||||
_pendingLocId = locationId;
|
||||
_pendingLoc = (Location)loc.clone();
|
||||
_changeObserver = obs;
|
||||
|
||||
// and send the location change request
|
||||
_sservice.changeLoc(_ctx.getClient(), scene.getId(), locationId, this);
|
||||
_sservice.changeLoc(_ctx.getClient(), loc, cluster, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,80 +219,37 @@ public class SpotSceneDirector extends BasicDirector
|
||||
public boolean requestClusterSpeak (String message, byte mode)
|
||||
{
|
||||
// make sure we're currently in a scene
|
||||
DisplaySpotScene scene = (DisplaySpotScene)_scdir.getScene();
|
||||
SpotScene scene = (SpotScene)_scdir.getScene();
|
||||
if (scene == null) {
|
||||
Log.warning("Requested to speak to cluster, but we're not " +
|
||||
"currently in any scene [message=" + message + "].");
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure we're in a location
|
||||
Location loc = scene.getLocation(_locationId);
|
||||
if (loc == null) {
|
||||
Log.info("Ignoring cluster speak as we're not in a valid " +
|
||||
"location [locId=" + _locationId + "].");
|
||||
// make sure we're part of a cluster
|
||||
if (_self.getClusterOid() <= 0) {
|
||||
Log.info("Ignoring cluster speak as we're not in a cluster " +
|
||||
"[cloid=" + _self.getClusterOid() + "].");
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure the location has an associated cluster
|
||||
if (loc.clusterIndex == -1) {
|
||||
Log.info("Ignoring cluster speak as our location has no " +
|
||||
"cluster [loc=" + loc + "].");
|
||||
return false;
|
||||
}
|
||||
|
||||
// we're all clear to go
|
||||
_sservice.clusterSpeak(_ctx.getClient(), scene.getId(), _locationId,
|
||||
message, mode);
|
||||
_sservice.clusterSpeak(_ctx.getClient(), message, mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void fetchServices (Client client)
|
||||
{
|
||||
_sservice = (SpotService)client.requireService(SpotService.class);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogoff (Client client)
|
||||
{
|
||||
super.clientDidLogoff(client);
|
||||
|
||||
// clear out our business
|
||||
_locationId = -1;
|
||||
_pendingLocId = -1;
|
||||
_changeObserver = null;
|
||||
_clobj = null;
|
||||
_sservice = null;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void changeLocSucceeded (int clusterOid)
|
||||
public void changeLocSucceeded ()
|
||||
{
|
||||
ChangeObserver obs = _changeObserver;
|
||||
_locationId = _pendingLocId;
|
||||
_location = _pendingLoc;
|
||||
|
||||
// clear out our pending location info
|
||||
_pendingLocId = -1;
|
||||
_pendingLoc = null;
|
||||
_changeObserver = null;
|
||||
|
||||
// determine if our cluster oid changed (which we only care about
|
||||
// if we're doing cluster chat)
|
||||
if (_chatdir != null) {
|
||||
int oldOid = (_clobj == null) ? -1 : _clobj.getOid();
|
||||
if (clusterOid != oldOid) {
|
||||
DObjectManager omgr = _ctx.getDObjectManager();
|
||||
// remove our old subscription if necessary
|
||||
clearCluster();
|
||||
// create a new subscription (we'll wire it up to the chat
|
||||
// director when the subscription completes)
|
||||
omgr.subscribeToObject(clusterOid, this);
|
||||
}
|
||||
}
|
||||
|
||||
// if we had an observer, let them know things went well
|
||||
if (obs != null) {
|
||||
obs.locationChangeSucceeded(_locationId);
|
||||
obs.locationChangeSucceeded(_location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,15 +257,15 @@ public class SpotSceneDirector extends BasicDirector
|
||||
public void requestFailed (String reason)
|
||||
{
|
||||
ChangeObserver obs = _changeObserver;
|
||||
int locId = _pendingLocId;
|
||||
Location loc = _pendingLoc;
|
||||
|
||||
// clear out our pending location info
|
||||
_pendingLocId = -1;
|
||||
_pendingLoc = null;
|
||||
_changeObserver = null;
|
||||
|
||||
// if we had an observer, let them know things went well
|
||||
if (obs != null) {
|
||||
obs.locationChangeFailed(locId, reason);
|
||||
obs.locationChangeFailed(loc, reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,13 +291,73 @@ public class SpotSceneDirector extends BasicDirector
|
||||
"[oid=" + oid + ", cause=" + cause + "].");
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void attributeChanged (AttributeChangedEvent event)
|
||||
{
|
||||
// if our cluster oid changes from the one we're currently
|
||||
// subscribed to, give it the boot
|
||||
if (_clobj != null && _self.getClusterOid() != _clobj.getOid()) {
|
||||
clearCluster();
|
||||
}
|
||||
|
||||
// if there's a new cluster object, subscribe to it
|
||||
if (_chatdir != null && _self.getClusterOid() > 0) {
|
||||
DObjectManager omgr = _ctx.getDObjectManager();
|
||||
// we'll wire up to the chat director when this completes
|
||||
omgr.subscribeToObject(_self.getClusterOid(), this);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientDidLogon (Client client)
|
||||
{
|
||||
super.clientDidLogon(client);
|
||||
|
||||
// listen to the client object
|
||||
client.getClientObject().addListener(this);
|
||||
_self = (ClusteredBodyObject)client.getClientObject();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clientObjectDidChange (Client client)
|
||||
{
|
||||
super.clientObjectDidChange(client);
|
||||
|
||||
// listen to the client object
|
||||
client.getClientObject().addListener(this);
|
||||
_self = (ClusteredBodyObject)client.getClientObject();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void clientDidLogoff (Client client)
|
||||
{
|
||||
super.clientDidLogoff(client);
|
||||
|
||||
// clear out our business
|
||||
_location = null;
|
||||
_pendingLoc = null;
|
||||
_changeObserver = null;
|
||||
_sservice = null;
|
||||
clearCluster();
|
||||
|
||||
// stop listening to the client object
|
||||
client.getClientObject().removeListener(this);
|
||||
_self = null;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void fetchServices (Client client)
|
||||
{
|
||||
_sservice = (SpotService)client.requireService(SpotService.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up after a few things when we depart from a scene.
|
||||
*/
|
||||
protected void handleDeparture ()
|
||||
{
|
||||
// clear out our last known location id
|
||||
_locationId = -1;
|
||||
_location = null;
|
||||
|
||||
// unwire and clear out our cluster chat object if we've got one
|
||||
clearCluster();
|
||||
@@ -377,15 +388,18 @@ public class SpotSceneDirector extends BasicDirector
|
||||
/** The scene director with which we are cooperating. */
|
||||
protected SceneDirector _scdir;
|
||||
|
||||
/** A casted reference to our clustered body object. */
|
||||
protected ClusteredBodyObject _self;
|
||||
|
||||
/** A reference to the chat director with which we coordinate. */
|
||||
protected ChatDirector _chatdir;
|
||||
|
||||
/** The location id of the location we currently occupy. */
|
||||
protected int _locationId = -1;
|
||||
/** The location we currently occupy. */
|
||||
protected Location _location;
|
||||
|
||||
/** The location id on which we have an outstanding change location
|
||||
/** The location to which we have an outstanding change location
|
||||
* request. */
|
||||
protected int _pendingLocId = -1;
|
||||
protected Location _pendingLoc;
|
||||
|
||||
/** The cluster chat object for the cluster we currently occupy. */
|
||||
protected DObject _clobj;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SpotService.java,v 1.11 2002/08/14 19:07:57 mdb Exp $
|
||||
// $Id: SpotService.java,v 1.12 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.client;
|
||||
|
||||
@@ -7,20 +7,25 @@ import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.whirled.client.SceneService.SceneMoveListener;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
|
||||
/**
|
||||
* Defines the mechanism by which the client can request to move between
|
||||
* locations within a scene and between scenes (taking exit and entry
|
||||
* locations into account). These services should not be used directly,
|
||||
* but instead should be accessed via the {@link SpotSceneDirector}.
|
||||
* Defines the mechanism by which the client can request to move around
|
||||
* within a scene and between scenes (taking exit and entry locations into
|
||||
* account). These services should not be used directly, but instead
|
||||
* should be accessed via the {@link SpotSceneDirector}.
|
||||
*/
|
||||
public interface SpotService extends InvocationService
|
||||
{
|
||||
/**
|
||||
* Requests to traverse the specified portal.
|
||||
*
|
||||
* @param portalId the portal to be traversed.
|
||||
* @param descSceneVer the version of the destination scene data that
|
||||
* the client has in its local repository.
|
||||
*/
|
||||
public void traversePortal (
|
||||
Client client, int sceneId, int portalId, int sceneVer,
|
||||
Client client, int portalId, int destSceneVer,
|
||||
SceneMoveListener listener);
|
||||
|
||||
/**
|
||||
@@ -29,25 +34,32 @@ public interface SpotService extends InvocationService
|
||||
public static interface ChangeLocListener extends InvocationListener
|
||||
{
|
||||
/**
|
||||
* Called when the change location request succeeded.
|
||||
*
|
||||
* @param clusterOid the object id of the cluster object
|
||||
* associated with the new location.
|
||||
* Called when the change location request succeeds.
|
||||
*/
|
||||
public void changeLocSucceeded (int clusterOid);
|
||||
public void changeLocSucceeded ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that this client's body be made to occupy the specified
|
||||
* Requests that this client's body be made to move to the specified
|
||||
* location.
|
||||
*
|
||||
* @param loc the location to which to move.
|
||||
* @param cluster if zero, a new cluster will be created and assigned
|
||||
* to the calling user; if -1, the calling user will be removed from
|
||||
* any cluster they currently occupy and not made to occupy a new
|
||||
* cluster; if the bodyOid of another user, the calling user will be
|
||||
* made to join the target user's cluster.
|
||||
*/
|
||||
public void changeLoc (Client client, int sceneId, int locationId,
|
||||
public void changeLoc (Client client, Location loc, int cluster,
|
||||
ChangeLocListener listener);
|
||||
|
||||
/**
|
||||
* Requests that the supplied message be delivered to listeners in the
|
||||
* cluster to which the specified location belongs.
|
||||
*
|
||||
* @param message the text of the message to be spoken.
|
||||
* @param mode an associated mode constant that can be used to
|
||||
* identify different kinds of "speech" (emote, thought bubble, etc.).
|
||||
*/
|
||||
public void clusterSpeak (Client client, int sceneId, int locationId,
|
||||
String message, byte mode);
|
||||
public void clusterSpeak (Client client, String message, byte mode);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
//
|
||||
// $Id: ClusterObject.dobj,v 1.1 2002/11/04 22:33:39 mdb Exp $
|
||||
// $Id: ClusterObject.dobj,v 1.2 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.OidList;
|
||||
|
||||
/**
|
||||
* Used to dispatch chat in clusters. Contains no other information at the
|
||||
* moment.
|
||||
* Used to dispatch chat in clusters.
|
||||
*/
|
||||
public class ClusterObject extends DObject
|
||||
{
|
||||
/**
|
||||
* Tracks the oid of the body objects that occupy this cluster.
|
||||
*/
|
||||
public OidList occupants = new OidList();
|
||||
}
|
||||
|
||||
@@ -1,14 +1,41 @@
|
||||
//
|
||||
// $Id: ClusterObject.java,v 1.1 2002/11/04 22:33:39 mdb Exp $
|
||||
// $Id: ClusterObject.java,v 1.2 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
import com.threerings.presents.dobj.OidList;
|
||||
|
||||
/**
|
||||
* Used to dispatch chat in clusters. Contains no other information at the
|
||||
* moment.
|
||||
* Used to dispatch chat in clusters.
|
||||
*/
|
||||
public class ClusterObject extends DObject
|
||||
{
|
||||
/** The field name of the <code>occupants</code> field. */
|
||||
public static final String OCCUPANTS = "occupants";
|
||||
|
||||
/**
|
||||
* Tracks the oid of the body objects that occupy this cluster.
|
||||
*/
|
||||
public OidList occupants = new OidList();
|
||||
|
||||
/**
|
||||
* Requests that the specified oid be added to the
|
||||
* <code>occupants</code> oid list. The list will not change until the
|
||||
* event is actually propagated through the system.
|
||||
*/
|
||||
public void addToOccupants (int oid)
|
||||
{
|
||||
requestOidAdd(OCCUPANTS, oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified oid be removed from the
|
||||
* <code>occupants</code> oid list. The list will not change until the
|
||||
* event is actually propagated through the system.
|
||||
*/
|
||||
public void removeFromOccupants (int oid)
|
||||
{
|
||||
requestOidRemove(OCCUPANTS, oid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// $Id: ClusteredBodyObject.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.crowd.data.BodyObject;
|
||||
import com.threerings.whirled.data.ScenedBodyObject;
|
||||
|
||||
/**
|
||||
* Defines some required methods for a {@link BodyObject} that is to
|
||||
* participate in the Whirled Spot system.
|
||||
*/
|
||||
public interface ClusteredBodyObject extends ScenedBodyObject
|
||||
{
|
||||
/**
|
||||
* Returns the oid of the cluster to which this user currently
|
||||
* belongs.
|
||||
*/
|
||||
public int getClusterOid ();
|
||||
|
||||
/**
|
||||
* Sets the oid of the cluster to which this user currently belongs.
|
||||
*/
|
||||
public void setClusterOid (int clusterOid);
|
||||
}
|
||||
@@ -1,43 +1,75 @@
|
||||
//
|
||||
// $Id: Location.java,v 1.5 2001/12/05 09:14:29 mdb Exp $
|
||||
// $Id: Location.java,v 1.6 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
/**
|
||||
* A location represents a place to stand in a scene. More specifically,
|
||||
* it is a geometric location in a scene with an orientation that would be
|
||||
* assumed by any body sprite standing in that location. Locations may
|
||||
* optionally belong to a cluster, which associates them with a group of
|
||||
* locations for speaking purposes (bodies in the same cluster can "hear"
|
||||
* one another speak).
|
||||
*/
|
||||
public class Location
|
||||
{
|
||||
/** This location's unique identifier. */
|
||||
public int locationId;
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
import com.threerings.util.DirectionCodes;
|
||||
import com.threerings.util.DirectionUtil;
|
||||
|
||||
/** This location's x coordinate (interpreted by the display system). */
|
||||
/**
|
||||
* Contains information on a scene occupant's position and orientation.
|
||||
*/
|
||||
public class Location extends SimpleStreamableObject
|
||||
implements Cloneable
|
||||
{
|
||||
/** The user's x position (interpreted by the display system). */
|
||||
public int x;
|
||||
|
||||
/** This location's y coordinate (interpreted by the display system). */
|
||||
/** The user's y position (interpreted by the display system). */
|
||||
public int y;
|
||||
|
||||
/** This location's y orientation (interpreted by the display system). */
|
||||
public int orientation;
|
||||
/** The user's orientation (defined by {@link DirectionCodes}). */
|
||||
public byte orient;
|
||||
|
||||
/** The cluster to which this location belongs or -1 if it belongs to
|
||||
* no cluster. */
|
||||
public int clusterIndex;
|
||||
/** {@link #toString} helper function. */
|
||||
public String orientToString ()
|
||||
{
|
||||
return DirectionUtil.toShortString(orient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Location equality is determined by location id.
|
||||
* A zero-argument constructor used when unserializing instances.
|
||||
*/
|
||||
public Location ()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a location with the specified coordinates and
|
||||
* orientation.
|
||||
*/
|
||||
public Location (int x, int y, byte orient)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.orient = orient;
|
||||
|
||||
if (orient == -1) {
|
||||
Thread.dumpStack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clone of this instance.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
try {
|
||||
return (Location)super.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new RuntimeException("Location.clone() failed " + cnse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Location equality is determined by coordinates.
|
||||
*/
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other instanceof Location) {
|
||||
Location oloc = (Location)other;
|
||||
return locationId == oloc.locationId;
|
||||
|
||||
return (x == oloc.x) && (y == oloc.y);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -48,29 +80,6 @@ public class Location
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
return locationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a string representation of this location instance.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("[");
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* An efficient, extensible mechanism for generating a string
|
||||
* representation of locations and derived classes.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append("id=").append(locationId);
|
||||
buf.append(", x=").append(x);
|
||||
buf.append(", y=").append(y);
|
||||
buf.append(", orient=").append(orientation);
|
||||
buf.append(", cluster=").append(clusterIndex);
|
||||
return x ^ y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,110 @@
|
||||
//
|
||||
// $Id: Portal.java,v 1.4 2001/12/05 03:38:09 mdb Exp $
|
||||
// $Id: Portal.java,v 1.5 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
import com.threerings.util.DirectionUtil;
|
||||
|
||||
/**
|
||||
* A portal is a location, but one that represents an exit to another
|
||||
* scene rather than a place to stand in the current scene. A body sprite
|
||||
* would walk over to a portal's coordinates and then either proceed off
|
||||
* of the edge of the display, or open a door and walk through it, or
|
||||
* fizzle away in a Star Trekkian transporter style or whatever is
|
||||
* appropriate for the game in question. It contains information on the
|
||||
* scene to which the body exits when using this portal and the location
|
||||
* at which the body sprite should appear in that target scene.
|
||||
*
|
||||
* <p> Though portals extend locations, they generally would not occupy a
|
||||
* cluster (because that wouldn't make much sense) and as such should
|
||||
* always have a {@link #clusterIndex} of -1.
|
||||
* Represents an exit to another scene. A body sprite would walk over to a
|
||||
* portal's coordinates and then either proceed off of the edge of the
|
||||
* display, or open a door and walk through it, or fizzle away in a Star
|
||||
* Trekkian transporter style or whatever is appropriate for the game in
|
||||
* question. It contains information on the scene to which the body exits
|
||||
* when using this portal and the location at which the body sprite should
|
||||
* appear in that target scene.
|
||||
*/
|
||||
public class Portal extends Location
|
||||
public class Portal extends SimpleStreamableObject
|
||||
implements Cloneable
|
||||
{
|
||||
/** This portal's unique identifier. */
|
||||
public short portalId;
|
||||
|
||||
/** This portal's x coordinate (interpreted by the display system). */
|
||||
public int x;
|
||||
|
||||
/** This portal's y coordinate (interpreted by the display system). */
|
||||
public int y;
|
||||
|
||||
/** This portal's y orientation (interpreted by the display system). */
|
||||
public byte orient;
|
||||
|
||||
/** The scene identifier of the scene to which a body will exit when
|
||||
* they "use" this portal. */
|
||||
public int targetSceneId;
|
||||
|
||||
/** The location identifier of the location at which a body will enter
|
||||
/** The portal identifier of the portal at which a body will enter
|
||||
* the target scene when they "use" this portal. */
|
||||
public int targetLocId;
|
||||
public short targetPortalId;
|
||||
|
||||
// documentation inherited
|
||||
protected void toString (StringBuffer buf)
|
||||
/**
|
||||
* Returns a location instance configured with the location and
|
||||
* orientation of this portal.
|
||||
*/
|
||||
public Location getLocation ()
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", targetScene=").append(targetSceneId);
|
||||
buf.append(", targetLoc=").append(targetLocId);
|
||||
return new Location(x, y, orient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a location instance configured with the location and
|
||||
* opposite orientation of this portal. This is useful for when a body
|
||||
* is entering a scene at a portal and we want them to face the
|
||||
* opposite direction (as they are entering via the portal rather than
|
||||
* leaving, which is the natural "orientation" of a portal).
|
||||
*/
|
||||
public Location getOppLocation ()
|
||||
{
|
||||
return new Location(x, y, (byte)DirectionUtil.getOpposite(orient));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the portal has a potentially valid target scene and
|
||||
* portal id (they are not guaranteed to exist, but they are at least
|
||||
* potentially valid values rather than -1 or 0).
|
||||
*/
|
||||
public boolean isValid ()
|
||||
{
|
||||
return (targetSceneId > 0) && (targetPortalId > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a clone of this instance.
|
||||
*/
|
||||
public Object clone ()
|
||||
{
|
||||
try {
|
||||
return (Portal)super.clone();
|
||||
} catch (CloneNotSupportedException cnse) {
|
||||
throw new RuntimeException("Portal.clone() failed " + cnse);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Portal equality is determined by portal id.
|
||||
*/
|
||||
public boolean equals (Object other)
|
||||
{
|
||||
if (other instanceof Portal) {
|
||||
Portal oport = (Portal)other;
|
||||
return portalId == oport.portalId;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@link #toString} helper function. */
|
||||
public String orientToString ()
|
||||
{
|
||||
return DirectionUtil.toShortString(orient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a reasonable hashcode for portal instances.
|
||||
*/
|
||||
public int hashCode ()
|
||||
{
|
||||
return portalId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// $Id: SceneLocation.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
|
||||
/**
|
||||
* Extends {@link Location} with the data and functionality needed to
|
||||
* represent a particular user's location in a scene.
|
||||
*/
|
||||
public class SceneLocation extends Location
|
||||
implements DSet.Entry
|
||||
{
|
||||
/** The oid of the body that occupies this location. */
|
||||
public int bodyOid;
|
||||
|
||||
/**
|
||||
* Creates a scene location with the specified information.
|
||||
*/
|
||||
public SceneLocation (int x, int y, byte orient, int bodyOid)
|
||||
{
|
||||
super(x, y, orient);
|
||||
this.bodyOid = bodyOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a scene location with the specified information.
|
||||
*/
|
||||
public SceneLocation (Location loc, int bodyOid)
|
||||
{
|
||||
super(loc.x, loc.y, loc.orient);
|
||||
this.bodyOid = bodyOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a blank instance suitable for unserialization.
|
||||
*/
|
||||
public SceneLocation ()
|
||||
{
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Comparable getKey ()
|
||||
{
|
||||
if (_key == null) {
|
||||
_key = new Integer(bodyOid);
|
||||
}
|
||||
return _key;
|
||||
}
|
||||
|
||||
/** Used for {@link #geyKey}. */
|
||||
protected transient Integer _key;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SpotMarshaller.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
// $Id: SpotMarshaller.java,v 1.3 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.threerings.whirled.client.SceneService.SceneMoveListener;
|
||||
import com.threerings.whirled.data.SceneMarshaller.SceneMoveMarshaller;
|
||||
import com.threerings.whirled.spot.client.SpotService;
|
||||
import com.threerings.whirled.spot.client.SpotService.ChangeLocListener;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
|
||||
/**
|
||||
* Provides the implementation of the {@link SpotService} interface
|
||||
@@ -17,10 +18,6 @@ import com.threerings.whirled.spot.client.SpotService.ChangeLocListener;
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*
|
||||
* <p> Generated from <code>
|
||||
* $Id: SpotMarshaller.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
* </code>
|
||||
*/
|
||||
public class SpotMarshaller extends InvocationMarshaller
|
||||
implements SpotService
|
||||
@@ -34,11 +31,11 @@ public class SpotMarshaller extends InvocationMarshaller
|
||||
public static final int CHANGE_LOC_SUCCEEDED = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void changeLocSucceeded (int arg1)
|
||||
public void changeLocSucceeded ()
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, CHANGE_LOC_SUCCEEDED,
|
||||
new Object[] { new Integer(arg1) }));
|
||||
new Object[] { }));
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -47,7 +44,7 @@ public class SpotMarshaller extends InvocationMarshaller
|
||||
switch (methodId) {
|
||||
case CHANGE_LOC_SUCCEEDED:
|
||||
((ChangeLocListener)listener).changeLocSucceeded(
|
||||
((Integer)args[0]).intValue());
|
||||
);
|
||||
return;
|
||||
|
||||
default:
|
||||
@@ -60,12 +57,12 @@ public class SpotMarshaller extends InvocationMarshaller
|
||||
public static final int TRAVERSE_PORTAL = 1;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void traversePortal (Client arg1, int arg2, int arg3, int arg4, SceneMoveListener arg5)
|
||||
public void traversePortal (Client arg1, int arg2, int arg3, SceneMoveListener arg4)
|
||||
{
|
||||
SceneMoveMarshaller listener5 = new SceneMoveMarshaller();
|
||||
listener5.listener = arg5;
|
||||
SceneMoveMarshaller listener4 = new SceneMoveMarshaller();
|
||||
listener4.listener = arg4;
|
||||
sendRequest(arg1, TRAVERSE_PORTAL, new Object[] {
|
||||
new Integer(arg2), new Integer(arg3), new Integer(arg4), listener5
|
||||
new Integer(arg2), new Integer(arg3), listener4
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,12 +70,12 @@ public class SpotMarshaller extends InvocationMarshaller
|
||||
public static final int CHANGE_LOC = 2;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void changeLoc (Client arg1, int arg2, int arg3, ChangeLocListener arg4)
|
||||
public void changeLoc (Client arg1, Location arg2, int arg3, ChangeLocListener arg4)
|
||||
{
|
||||
ChangeLocMarshaller listener4 = new ChangeLocMarshaller();
|
||||
listener4.listener = arg4;
|
||||
sendRequest(arg1, CHANGE_LOC, new Object[] {
|
||||
new Integer(arg2), new Integer(arg3), listener4
|
||||
arg2, new Integer(arg3), listener4
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,12 +83,12 @@ public class SpotMarshaller extends InvocationMarshaller
|
||||
public static final int CLUSTER_SPEAK = 3;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void clusterSpeak (Client arg1, int arg2, int arg3, String arg4, byte arg5)
|
||||
public void clusterSpeak (Client arg1, String arg2, byte arg3)
|
||||
{
|
||||
sendRequest(arg1, CLUSTER_SPEAK, new Object[] {
|
||||
new Integer(arg2), new Integer(arg3), arg4, new Byte(arg5)
|
||||
arg2, new Byte(arg3)
|
||||
});
|
||||
}
|
||||
|
||||
// Class file generated on 12:33:05 08/20/02.
|
||||
// Generated on 10:09:04 02/05/03.
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// $Id: SpotOccupantInfo.java,v 1.3 2002/06/20 22:13:20 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.samskivert.util.StringUtil.Formatter;
|
||||
|
||||
import com.threerings.crowd.data.OccupantInfo;
|
||||
|
||||
/**
|
||||
* The spot services extend the basic occupant info with information on
|
||||
* which location within the scene a user occupies.
|
||||
*/
|
||||
public class SpotOccupantInfo extends OccupantInfo
|
||||
{
|
||||
/** The id of the location occupied by this user or -1 if they occupy
|
||||
* no location. */
|
||||
public int locationId;
|
||||
|
||||
/** Used to log just the user oids and location ids of users in the
|
||||
* <code>occupantInfo</code> set when debugging. */
|
||||
public static final Formatter OIDS_AND_LOCS = new Formatter() {
|
||||
public String toString (Object object) {
|
||||
SpotOccupantInfo soi = (SpotOccupantInfo)object;
|
||||
return "[" + soi.getBodyOid() + ", " + soi.locationId + "]";
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// $Id: SpotScene.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Makes available the spot scene information that the server needs to do
|
||||
* its business.
|
||||
*/
|
||||
public interface SpotScene
|
||||
{
|
||||
/**
|
||||
* Returns a {@link Portal} object for the portal with the specified
|
||||
* id or null if no portal exists with that id.
|
||||
*/
|
||||
public Portal getPortal (int portalId);
|
||||
|
||||
/**
|
||||
* Returns the number of portals in this scene.
|
||||
*/
|
||||
public int getPortalCount ();
|
||||
|
||||
/**
|
||||
* Returns an iterator over the portals in this scene.
|
||||
*/
|
||||
public Iterator getPortals ();
|
||||
|
||||
/**
|
||||
* Returns the portal that represents the default entrance to this
|
||||
* scene. If a body enters the scene at logon time rather than
|
||||
* entering from some other scene, this is the portal at which they
|
||||
* would appear.
|
||||
*/
|
||||
public Portal getDefaultEntrance ();
|
||||
|
||||
/**
|
||||
* Adds a portal to this scene, immediately making the requisite
|
||||
* modifications to the underlying scene model. A portal id will be
|
||||
* assigned to the portal by this method.
|
||||
*/
|
||||
public void addPortal (Portal portal);
|
||||
|
||||
/**
|
||||
* Removes the specified portal from the scene.
|
||||
*/
|
||||
public void removePortal (Portal portal);
|
||||
|
||||
/**
|
||||
* Sets the default entrance in this scene, immediately making the
|
||||
* requisite modifications to the underlying scene model.
|
||||
*/
|
||||
public void setDefaultEntrance (Portal portal);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// $Id: SpotSceneImpl.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.ListUtil;
|
||||
|
||||
import com.threerings.whirled.spot.Log;
|
||||
|
||||
/**
|
||||
* An implementation of the {@link SpotScene} interface.
|
||||
*/
|
||||
public class SpotSceneImpl
|
||||
implements SpotScene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied spot
|
||||
* scene model.
|
||||
*/
|
||||
public SpotSceneImpl (SpotSceneModel smodel)
|
||||
{
|
||||
_smodel = smodel;
|
||||
|
||||
for (int ii = 0, ll = _smodel.portals.length; ii < ll; ii++) {
|
||||
Portal port = _smodel.portals[ii];
|
||||
_portals.put(port.portalId, port);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a blank scene implementation.
|
||||
*/
|
||||
public SpotSceneImpl ()
|
||||
{
|
||||
_smodel = new SpotSceneModel();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Portal getPortal (int portalId)
|
||||
{
|
||||
return (Portal)_portals.get(portalId);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int getPortalCount ()
|
||||
{
|
||||
return _portals.size();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Iterator getPortals ()
|
||||
{
|
||||
return _portals.values().iterator();
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public Portal getDefaultEntrance ()
|
||||
{
|
||||
return getPortal(_smodel.defaultEntranceId);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void addPortal (Portal portal)
|
||||
{
|
||||
// compute a new portal id for our friend the portal
|
||||
portal.portalId = 0;
|
||||
for (short ii = 1; ii < MAX_PORTAL_ID; ii++) {
|
||||
if (!_portals.containsKey(ii)) {
|
||||
portal.portalId = ii;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (portal.portalId == 0) {
|
||||
Log.warning("Unable to assign id to new portal " +
|
||||
"[scene=" + this + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// add this beyotch to our model
|
||||
_smodel.addPortal(portal);
|
||||
|
||||
// and slap it into our table
|
||||
_portals.put(portal.portalId, portal);
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void removePortal (Portal portal)
|
||||
{
|
||||
// remove the portal from our mapping
|
||||
_portals.remove(portal.portalId);
|
||||
|
||||
// remove it from the model
|
||||
_smodel.removePortal(portal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when we're being parsed from an XML scene model.
|
||||
*/
|
||||
public void setDefaultEntranceId (int defaultEntranceId)
|
||||
{
|
||||
_smodel.defaultEntranceId = defaultEntranceId;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public void setDefaultEntrance (Portal portal)
|
||||
{
|
||||
_smodel.defaultEntranceId = (portal == null) ? -1 : portal.portalId;
|
||||
}
|
||||
|
||||
/** A casted reference to our scene model. */
|
||||
protected SpotSceneModel _smodel;
|
||||
|
||||
/** A mapping from portal id to portal. */
|
||||
protected HashIntMap _portals = new HashIntMap();
|
||||
|
||||
/** We don't allow more than ~32k portals in a scene. Things would
|
||||
* slow down *way* before we got there. */
|
||||
protected static final int MAX_PORTAL_ID = Short.MAX_VALUE;
|
||||
}
|
||||
@@ -1,119 +1,79 @@
|
||||
//
|
||||
// $Id: SpotSceneModel.java,v 1.8 2002/07/23 05:54:52 mdb Exp $
|
||||
// $Id: SpotSceneModel.java,v 1.9 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.ListUtil;
|
||||
|
||||
import com.threerings.io.SimpleStreamableObject;
|
||||
import com.threerings.util.DirectionUtil;
|
||||
|
||||
import com.threerings.whirled.data.AuxModel;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* The spot scene model extends the standard scene model with information
|
||||
* on locations, clusters and portals. Locations (and by extension,
|
||||
* portals) are referenced by an identifier, unique within the scene and
|
||||
* unchanging, so that portals can stably reference the target location in
|
||||
* the scene to which they connect. Clusters are tracked by index rather
|
||||
* than unique identifier, but only exist as an attribute of locations (a
|
||||
* location belongs to zero or one clusters).
|
||||
* on portals. Portals are referenced by an identifier, unique within the
|
||||
* scene and unchanging, so that portals can stably reference the target
|
||||
* portal in the scene to which they connect.
|
||||
*/
|
||||
public class SpotSceneModel extends SceneModel
|
||||
public class SpotSceneModel extends SimpleStreamableObject
|
||||
implements AuxModel
|
||||
{
|
||||
/** The unique (within the scope of this scene) identifier of each
|
||||
* location in this scene (including portals). */
|
||||
public int[] locationIds;
|
||||
/** An array containing all portals in this scene. */
|
||||
public Portal[] portals = new Portal[0];
|
||||
|
||||
/** The x coordinates of the locations in this scene (including
|
||||
* portals). */
|
||||
public int[] locationX;
|
||||
|
||||
/** The y coordinates of the locations in this scene (including
|
||||
* portals). */
|
||||
public int[] locationY;
|
||||
|
||||
/** The orientations associated with the locations in this scene
|
||||
* (including portals). */
|
||||
public int[] locationOrients;
|
||||
|
||||
/** The cluster index of each location in this scene, which can be 0
|
||||
* to indicate that the location is not a member of any cluster
|
||||
* (including portals, which should always be 0). */
|
||||
public int[] locationClusters;
|
||||
|
||||
/** The location id of the default entrance to this scene. If a body
|
||||
/** The portal id of the default entrance to this scene. If a body
|
||||
* enters the scene without coming from another scene, this is the
|
||||
* location at which they would appear. */
|
||||
public int defaultEntranceId;
|
||||
* portal at which they would appear. */
|
||||
public int defaultEntranceId = -1;
|
||||
|
||||
/** The location id of each portal in this scene. These must map, in
|
||||
* order, to the neighboring scene ids specified in {@link
|
||||
* #neighborIds}. The neighbor ids being the scene ids of the scenes
|
||||
* to which these portals take a body when "used". Additionally, these
|
||||
* must occur in the same order that the location ids appear in the
|
||||
* above array. */
|
||||
public int[] portalIds;
|
||||
/**
|
||||
* Adds a portal to this scene model.
|
||||
*/
|
||||
public void addPortal (Portal portal)
|
||||
{
|
||||
portals = (Portal[])ArrayUtil.append(portals, portal);
|
||||
}
|
||||
|
||||
/** Contains the location ids of the entry location in the target
|
||||
* scene to which this scene's portals connect. Portals in this scene
|
||||
* connect to locations in other scenes as dictated by these
|
||||
* values. */
|
||||
public int[] targetLocIds;
|
||||
/**
|
||||
* Removes a portal from this model.
|
||||
*/
|
||||
public void removePortal (Portal portal)
|
||||
{
|
||||
int pidx = ListUtil.indexOfEqual(portals, portal);
|
||||
if (pidx != -1) {
|
||||
portals = (Portal[])ArrayUtil.splice(portals, pidx, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
SpotSceneModel model = (SpotSceneModel)super.clone();
|
||||
model.locationIds = (int[])locationIds.clone();
|
||||
model.locationX = (int[])locationX.clone();
|
||||
model.locationY = (int[])locationY.clone();
|
||||
model.locationOrients = (int[])locationOrients.clone();
|
||||
model.locationClusters = (int[])locationClusters.clone();
|
||||
model.portalIds = (int[])portalIds.clone();
|
||||
model.targetLocIds = (int[])targetLocIds.clone();
|
||||
// clone our portals individually
|
||||
model.portals = new Portal[portals.length];
|
||||
for (int ii = 0, ll = portals.length; ii < ll; ii++) {
|
||||
model.portals[ii] = (Portal)portals[ii].clone();
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a blank scene model.
|
||||
* Locates and returns the {@link SpotSceneModel} among the auxiliary
|
||||
* scene models associated with the supplied scene
|
||||
* model. <code>null</code> is returned if no spot scene model could
|
||||
* be found.
|
||||
*/
|
||||
public static SpotSceneModel blankSpotSceneModel ()
|
||||
public static SpotSceneModel getSceneModel (SceneModel model)
|
||||
{
|
||||
SpotSceneModel model = new SpotSceneModel();
|
||||
populateBlankSpotSceneModel(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a blank scene model with blank values.
|
||||
*/
|
||||
protected static void populateBlankSpotSceneModel (SpotSceneModel model)
|
||||
{
|
||||
// populate our superclass fields
|
||||
populateBlankSceneModel(model);
|
||||
|
||||
// now populate our fields
|
||||
model.locationIds = new int[0];
|
||||
model.locationX = new int[0];
|
||||
model.locationY = new int[0];
|
||||
model.locationOrients = new int[0];
|
||||
model.locationClusters = new int[0];
|
||||
model.defaultEntranceId = -1;
|
||||
model.portalIds = new int[0];
|
||||
model.targetLocIds = new int[0];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", locationIds=").append(StringUtil.toString(locationIds));
|
||||
buf.append(", locationX=").append(StringUtil.toString(locationX ));
|
||||
buf.append(", locationY=").append(StringUtil.toString(locationY));
|
||||
buf.append(", locationOrients=").
|
||||
append(StringUtil.toString(locationOrients));
|
||||
buf.append(", locationClusters=").
|
||||
append(StringUtil.toString(locationClusters));
|
||||
buf.append(", defaultEntranceId=").append(defaultEntranceId);
|
||||
buf.append(", portalIds=").append(StringUtil.toString(portalIds));
|
||||
buf.append(", targetLocIds=").append(StringUtil.toString(targetLocIds));
|
||||
for (int ii = 0; ii < model.auxModels.length; ii++) {
|
||||
if (model.auxModels[ii] instanceof SpotSceneModel) {
|
||||
return (SpotSceneModel)model.auxModels[ii];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// $Id: SpotSceneObject.dobj,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.whirled.data.SceneObject;
|
||||
|
||||
/**
|
||||
* Extends the {@link SceneObject} with information specific to spots.
|
||||
*/
|
||||
public class SpotSceneObject extends SceneObject
|
||||
{
|
||||
/** A distributed set containing {@link SceneLocation} records for all
|
||||
* occupants of this scene. */
|
||||
public DSet occupantLocs = new DSet();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// $Id: SpotSceneObject.java,v 1.1 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.data;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.whirled.data.SceneObject;
|
||||
|
||||
/**
|
||||
* Extends the {@link SceneObject} with information specific to spots.
|
||||
*/
|
||||
public class SpotSceneObject extends SceneObject
|
||||
{
|
||||
/** The field name of the <code>occupantLocs</code> field. */
|
||||
public static final String OCCUPANT_LOCS = "occupantLocs";
|
||||
|
||||
/** A distributed set containing {@link SceneLocation} records for all
|
||||
* occupants of this scene. */
|
||||
public DSet occupantLocs = new DSet();
|
||||
|
||||
/**
|
||||
* Requests that the specified entry be added to the
|
||||
* <code>occupantLocs</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void addToOccupantLocs (DSet.Entry elem)
|
||||
{
|
||||
requestEntryAdd(OCCUPANT_LOCS, elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the entry matching the supplied key be removed from
|
||||
* the <code>occupantLocs</code> set. The set will not change until the
|
||||
* event is actually propagated through the system.
|
||||
*/
|
||||
public void removeFromOccupantLocs (Object key)
|
||||
{
|
||||
requestEntryRemove(OCCUPANT_LOCS, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the specified entry be updated in the
|
||||
* <code>occupantLocs</code> set. The set will not change until the event is
|
||||
* actually propagated through the system.
|
||||
*/
|
||||
public void updateOccupantLocs (DSet.Entry elem)
|
||||
{
|
||||
requestEntryUpdate(OCCUPANT_LOCS, elem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that the <code>occupantLocs</code> field be set to the
|
||||
* specified value. Generally one only adds, updates and removes
|
||||
* entries of a distributed set, but certain situations call for a
|
||||
* complete replacement of the set value. The local value will be
|
||||
* updated immediately and an event will be propagated through the
|
||||
* system to notify all listeners that the attribute did
|
||||
* change. Proxied copies of this object (on clients) will apply the
|
||||
* value change when they received the attribute changed notification.
|
||||
*/
|
||||
public void setOccupantLocs (DSet occupantLocs)
|
||||
{
|
||||
this.occupantLocs = occupantLocs;
|
||||
requestAttributeChange(OCCUPANT_LOCS, occupantLocs);
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
//
|
||||
// $Id: RuntimeSpotScene.java,v 1.5 2003/02/04 03:12:07 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.server;
|
||||
|
||||
import com.threerings.whirled.server.RuntimeScene;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
/**
|
||||
* Makes available the spot scene information that the server needs to
|
||||
* manage requests to move from location to location, to enter and exit a
|
||||
* scene at a location and to manage speaking among bodies that occupy the
|
||||
* same clusters.
|
||||
*/
|
||||
public interface RuntimeSpotScene extends RuntimeScene
|
||||
{
|
||||
/**
|
||||
* Returns the number of locations (and portals) in this scene.
|
||||
*/
|
||||
public int getLocationCount ();
|
||||
|
||||
/**
|
||||
* Returns the location id of the location at the specified index.
|
||||
*/
|
||||
public int getLocationId (int locidx);
|
||||
|
||||
/**
|
||||
* Returns the index of the specified location id.
|
||||
*/
|
||||
public int getLocationIndex (int locationId);
|
||||
|
||||
/**
|
||||
* Returns the total number of clusters in this scene.
|
||||
*/
|
||||
public int getClusterCount ();
|
||||
|
||||
/**
|
||||
* Returns the cluster index associated with the specified location
|
||||
* index or -1 if the location at that index is not associated with a
|
||||
* cluster.
|
||||
*/
|
||||
public int getClusterIndex (int locationIdx);
|
||||
|
||||
/**
|
||||
* Returns the location id of the default entrance to this scene. If a
|
||||
* body enters the scene at logon time rather than entering from some
|
||||
* other scene, this is the location at which they would appear.
|
||||
*/
|
||||
public int getDefaultEntranceId ();
|
||||
|
||||
/**
|
||||
* Returns the target scene id associated with the specified portal
|
||||
* (identified by its location id) or -1 if the location id specified
|
||||
* is not a portal.
|
||||
*/
|
||||
public int getTargetSceneId (int locationId);
|
||||
|
||||
/**
|
||||
* Returns the target location id associated with the specified portal
|
||||
* (identified by its location id) or -1 if the location id specified
|
||||
* is not a portal.
|
||||
*/
|
||||
public int getTargetLocationId (int locationId);
|
||||
|
||||
/**
|
||||
* Adds a portal to this runtime scene, immediately making the
|
||||
* requisite modifications to the underlying scene model.
|
||||
*
|
||||
* @return the location id assigned to the newly created portal.
|
||||
*/
|
||||
public int addPortal (int locX, int locY, int orient,
|
||||
int targetSceneId, int targetLocId);
|
||||
|
||||
/**
|
||||
* Returns a reference to the underlying model.
|
||||
*/
|
||||
public SpotSceneModel getModel ();
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
//
|
||||
// $Id: RuntimeSpotSceneImpl.java,v 1.7 2003/02/06 18:58:30 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.server;
|
||||
|
||||
import com.samskivert.util.ArrayUtil;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.server.RuntimeSceneImpl;
|
||||
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
/**
|
||||
* A basic implementation of the {@link RuntimeSpotScene} interface which
|
||||
* is used by default if no extended implementation is desired.
|
||||
*/
|
||||
public class RuntimeSpotSceneImpl extends RuntimeSceneImpl
|
||||
implements RuntimeSpotScene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and place config.
|
||||
*/
|
||||
public RuntimeSpotSceneImpl (SpotSceneModel model, PlaceConfig config)
|
||||
{
|
||||
super(model, config);
|
||||
|
||||
// keep a casted reference to our scene model around
|
||||
_model = model;
|
||||
|
||||
// determine the highest cluster index
|
||||
int lcount = _model.locationIds.length;
|
||||
for (int i = 0; i < lcount; i++) {
|
||||
int cidx = _model.locationClusters[i];
|
||||
if (cidx > _clusterCount) {
|
||||
_clusterCount = cidx;
|
||||
}
|
||||
}
|
||||
// now increment by one to get the count rather than the highest
|
||||
// cluster index
|
||||
_clusterCount++;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getLocationCount ()
|
||||
{
|
||||
return _model.locationIds.length;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getLocationId (int locidx)
|
||||
{
|
||||
return _model.locationIds[locidx];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getLocationIndex (int locationId)
|
||||
{
|
||||
return IntListUtil.indexOf(_model.locationIds, locationId);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getClusterCount ()
|
||||
{
|
||||
return _clusterCount;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getClusterIndex (int locationIdx)
|
||||
{
|
||||
return _model.locationClusters[locationIdx];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getDefaultEntranceId ()
|
||||
{
|
||||
return _model.defaultEntranceId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getTargetSceneId (int locationId)
|
||||
{
|
||||
int pidx = getPortalIndex(locationId);
|
||||
return (pidx == -1) ? -1 : _model.neighborIds[pidx];
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getTargetLocationId (int locationId)
|
||||
{
|
||||
int pidx = getPortalIndex(locationId);
|
||||
return (pidx == -1) ? -1 : _model.targetLocIds[pidx];
|
||||
}
|
||||
|
||||
// make or may not make it into the public interface
|
||||
public int addLocation (int locX, int locY, int orient, int cluster)
|
||||
{
|
||||
// compute the highest location id already used in the scene and
|
||||
// add one to it for our new location id
|
||||
int nlocid = Math.max(
|
||||
IntListUtil.getMaxValue(_model.locationIds), 0) + 1;
|
||||
|
||||
// expand the necessary arrays
|
||||
_model.locationIds = ArrayUtil.append(_model.locationIds, nlocid);
|
||||
_model.locationX = ArrayUtil.append(_model.locationX, locX);
|
||||
_model.locationY = ArrayUtil.append(_model.locationY, locY);
|
||||
_model.locationOrients =
|
||||
ArrayUtil.append(_model.locationOrients, orient);
|
||||
_model.locationClusters =
|
||||
ArrayUtil.append(_model.locationOrients, cluster);
|
||||
|
||||
return nlocid;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public int addPortal (int locX, int locY, int orient,
|
||||
int targetSceneId, int targetLocId)
|
||||
{
|
||||
// add the location information for this portal
|
||||
int nlocid = addLocation(locX, locY, orient, 0);
|
||||
|
||||
// expand the necessary portal arrays
|
||||
_model.neighborIds =
|
||||
ArrayUtil.append(_model.neighborIds, targetSceneId);
|
||||
_model.portalIds = ArrayUtil.append(_model.portalIds, nlocid);
|
||||
_model.targetLocIds =
|
||||
ArrayUtil.append(_model.targetLocIds, targetLocId);
|
||||
|
||||
return nlocid;
|
||||
}
|
||||
|
||||
// documentation inherited from interface
|
||||
public SpotSceneModel getModel ()
|
||||
{
|
||||
return _model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the specified portal in the model's internal
|
||||
* portal arrays.
|
||||
*/
|
||||
protected int getPortalIndex (int portalId)
|
||||
{
|
||||
int pcount = _model.portalIds.length;
|
||||
for (int i = 0; i < pcount; i++) {
|
||||
if (_model.portalIds[i] == portalId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** A casted reference to our scene model. */
|
||||
protected SpotSceneModel _model;
|
||||
|
||||
/** The total number of clusters in this scene. */
|
||||
protected int _clusterCount = -1;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SpotDispatcher.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
// $Id: SpotDispatcher.java,v 1.3 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.server;
|
||||
|
||||
@@ -12,14 +12,11 @@ import com.threerings.whirled.client.SceneService.SceneMoveListener;
|
||||
import com.threerings.whirled.data.SceneMarshaller.SceneMoveMarshaller;
|
||||
import com.threerings.whirled.spot.client.SpotService;
|
||||
import com.threerings.whirled.spot.client.SpotService.ChangeLocListener;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.SpotMarshaller;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link SpotProvider}.
|
||||
*
|
||||
* <p> Generated from <code>
|
||||
* $Id: SpotDispatcher.java,v 1.2 2002/08/20 19:38:15 mdb Exp $
|
||||
* </code>
|
||||
*/
|
||||
public class SpotDispatcher extends InvocationDispatcher
|
||||
{
|
||||
@@ -47,21 +44,21 @@ public class SpotDispatcher extends InvocationDispatcher
|
||||
case SpotMarshaller.TRAVERSE_PORTAL:
|
||||
((SpotProvider)provider).traversePortal(
|
||||
source,
|
||||
((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), ((Integer)args[2]).intValue(), (SceneMoveListener)args[3]
|
||||
((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (SceneMoveListener)args[2]
|
||||
);
|
||||
return;
|
||||
|
||||
case SpotMarshaller.CHANGE_LOC:
|
||||
((SpotProvider)provider).changeLoc(
|
||||
source,
|
||||
((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (ChangeLocListener)args[2]
|
||||
(Location)args[0], ((Integer)args[1]).intValue(), (ChangeLocListener)args[2]
|
||||
);
|
||||
return;
|
||||
|
||||
case SpotMarshaller.CLUSTER_SPEAK:
|
||||
((SpotProvider)provider).clusterSpeak(
|
||||
source,
|
||||
((Integer)args[0]).intValue(), ((Integer)args[1]).intValue(), (String)args[2], ((Byte)args[3]).byteValue()
|
||||
(String)args[0], ((Byte)args[1]).byteValue()
|
||||
);
|
||||
return;
|
||||
|
||||
@@ -69,4 +66,6 @@ public class SpotDispatcher extends InvocationDispatcher
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
}
|
||||
}
|
||||
|
||||
// Generated on 10:09:04 02/05/03.
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
//
|
||||
// $Id: SpotProvider.java,v 1.14 2002/12/14 01:51:00 mdb Exp $
|
||||
// $Id: SpotProvider.java,v 1.15 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.server;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.data.ClientObject;
|
||||
import com.threerings.presents.dobj.RootDObjectManager;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
@@ -16,13 +18,16 @@ import com.threerings.crowd.server.PlaceRegistry;
|
||||
|
||||
import com.threerings.whirled.client.SceneService.SceneMoveListener;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.ScenedBodyObject;
|
||||
import com.threerings.whirled.server.SceneManager;
|
||||
import com.threerings.whirled.server.SceneRegistry;
|
||||
|
||||
import com.threerings.whirled.spot.Log;
|
||||
import com.threerings.whirled.spot.client.SpotService.ChangeLocListener;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SpotCodes;
|
||||
import com.threerings.whirled.spot.data.SpotOccupantInfo;
|
||||
import com.threerings.whirled.spot.data.SpotScene;
|
||||
|
||||
/**
|
||||
* Provides the server-side implementation of the spot services.
|
||||
@@ -44,24 +49,18 @@ public class SpotProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from a client to traverse a portal.
|
||||
*
|
||||
* @param source the body object of the client making the request.
|
||||
* @param sceneId the source scene id.
|
||||
* @param portalId the portal in the source scene that is being
|
||||
* traversed.
|
||||
* @param sceneVer the version of the destination scene data that the
|
||||
* client has cached.
|
||||
* @param listener the entity to which we communicate our response.
|
||||
* Processes a {@link SpotService#traversePortal} request.
|
||||
*/
|
||||
public void traversePortal (ClientObject caller, int sceneId, int portalId,
|
||||
int sceneVer, SceneMoveListener listener)
|
||||
public void traversePortal (ClientObject caller, int portalId,
|
||||
int destSceneVer, SceneMoveListener listener)
|
||||
throws InvocationException
|
||||
{
|
||||
int sceneId = getCallerSceneId(caller);
|
||||
|
||||
// avoid cluttering up the method declaration with final keywords
|
||||
final BodyObject fsource = (BodyObject)caller;
|
||||
final int fportalId = portalId;
|
||||
final int fsceneVer = sceneVer;
|
||||
final int fsceneVer = destSceneVer;
|
||||
final SceneMoveListener flistener = listener;
|
||||
|
||||
// obtain the source scene
|
||||
@@ -75,28 +74,26 @@ public class SpotProvider
|
||||
}
|
||||
|
||||
// obtain the destination scene and location id
|
||||
RuntimeSpotScene rss = (RuntimeSpotScene)smgr.getScene();
|
||||
int destSceneId = rss.getTargetSceneId(portalId);
|
||||
final int destLocId = rss.getTargetLocationId(portalId);
|
||||
SpotScene rss = (SpotScene)smgr.getScene();
|
||||
final Portal fdest = rss.getPortal(portalId);
|
||||
|
||||
// make sure this portal has valid info
|
||||
if (destSceneId == -1) {
|
||||
Log.warning("Traverse portal provided with invalid portal " +
|
||||
"[user=" + fsource.who() + ", sceneId=" + sceneId +
|
||||
", portalId=" + portalId +
|
||||
", destSceneId=" + destSceneId + "].");
|
||||
if (fdest == null || !fdest.isValid()) {
|
||||
Log.warning("Traverse portal with invalid portal " +
|
||||
"[user=" + fsource.who() + ", scene=" + smgr.where() +
|
||||
", pid=" + portalId + ", portal=" + fdest +
|
||||
", portals=" + StringUtil.toString(rss.getPortals()) +
|
||||
"].");
|
||||
throw new InvocationException(NO_SUCH_PORTAL);
|
||||
}
|
||||
|
||||
// create a callback object that will handle the resolution or
|
||||
// failed resolution of the scene
|
||||
// resolve their destination scene
|
||||
SceneRegistry.ResolutionListener rl =
|
||||
new SceneRegistry.ResolutionListener() {
|
||||
public void sceneWasResolved (SceneManager scmgr) {
|
||||
SpotSceneManager sscmgr = (SpotSceneManager)scmgr;
|
||||
finishTraversePortalRequest(
|
||||
fsource, sscmgr, fsceneVer, fportalId, destLocId,
|
||||
flistener);
|
||||
fsource, sscmgr, fsceneVer, fdest, flistener);
|
||||
}
|
||||
|
||||
public void sceneFailedToResolve (
|
||||
@@ -108,10 +105,7 @@ public class SpotProvider
|
||||
flistener.requestFailed(NO_SUCH_PLACE);
|
||||
}
|
||||
};
|
||||
|
||||
// make sure the scene they are headed to is actually loaded into
|
||||
// the server
|
||||
_screg.resolveScene(destSceneId, rl);
|
||||
_screg.resolveScene(fdest.targetSceneId, rl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,11 +114,10 @@ public class SpotProvider
|
||||
*/
|
||||
protected void finishTraversePortalRequest (
|
||||
BodyObject source, SpotSceneManager scmgr, int sceneVer,
|
||||
int exitPortalId, int destLocId, SceneMoveListener listener)
|
||||
Portal dest, SceneMoveListener listener)
|
||||
{
|
||||
// let the destination scene manager know that we're coming in
|
||||
int bodyOid = source.getOid();
|
||||
scmgr.mapEnteringBody(bodyOid, destLocId);
|
||||
scmgr.mapEnteringBody(source, dest.targetPortalId);
|
||||
|
||||
try {
|
||||
// move to the place object associated with this scene
|
||||
@@ -133,17 +126,18 @@ public class SpotProvider
|
||||
listener.requestFailed(sfe.getMessage());
|
||||
// and let the destination scene manager know that we're no
|
||||
// longer coming in
|
||||
scmgr.clearEnteringBody(bodyOid);
|
||||
scmgr.clearEnteringBody(source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a request from a client to move to a new location.
|
||||
* Processes a {@link SpotService#changeLog} request.
|
||||
*/
|
||||
public void changeLoc (ClientObject caller, int sceneId, int locationId,
|
||||
public void changeLoc (ClientObject caller, Location loc, int cluster,
|
||||
ChangeLocListener listener)
|
||||
throws InvocationException
|
||||
{
|
||||
int sceneId = getCallerSceneId(caller);
|
||||
BodyObject source = (BodyObject)caller;
|
||||
|
||||
// look up the scene manager for the specified scene
|
||||
@@ -152,23 +146,25 @@ public class SpotProvider
|
||||
if (smgr == null) {
|
||||
Log.warning("User requested to change location in " +
|
||||
"non-existent scene [user=" + source.who() +
|
||||
", sceneId=" + sceneId +
|
||||
", locId=" + locationId + "].");
|
||||
", sceneId=" + sceneId + ", loc=" + loc +"].");
|
||||
throw new InvocationException(INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
int locOid = smgr.handleChangeLocRequest(source, locationId);
|
||||
listener.changeLocSucceeded(locOid);
|
||||
// pass the buck to yon scene manager
|
||||
smgr.handleChangeLocRequest(source, loc, cluster);
|
||||
|
||||
// if that method finished, we're good to go
|
||||
listener.changeLocSucceeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles request to generate a speak message in the specified cluster.
|
||||
*/
|
||||
public void clusterSpeak (ClientObject caller, int sceneId, int locationId,
|
||||
String message, byte mode)
|
||||
public void clusterSpeak (ClientObject caller, String message, byte mode)
|
||||
throws InvocationException
|
||||
{
|
||||
BodyObject source = (BodyObject)caller;
|
||||
sendClusterChatMessage(sceneId, locationId, source.getOid(),
|
||||
sendClusterChatMessage(getCallerSceneId(caller), source.getOid(),
|
||||
source.username, null, message, mode);
|
||||
}
|
||||
|
||||
@@ -181,7 +177,6 @@ public class SpotProvider
|
||||
* message text) and with the supplied message content.
|
||||
*
|
||||
* @param sceneId the scene id in which to deliver the chat message.
|
||||
* @param locId the location whose cluster will be spoken to.
|
||||
* @param speakerOid the body object id of the speaker (used to verify
|
||||
* that they are in the cluster in question).
|
||||
* @param speaker the username of the user that generated the message
|
||||
@@ -192,24 +187,39 @@ public class SpotProvider
|
||||
* @param message the text of the chat message.
|
||||
*/
|
||||
public void sendClusterChatMessage (
|
||||
int sceneId, int locId, int speakerOid, String speaker,
|
||||
int sceneId, int speakerOid, String speaker,
|
||||
String bundle, String message, byte mode)
|
||||
{
|
||||
// look up the scene manager for the specified scene
|
||||
SpotSceneManager smgr = (SpotSceneManager)
|
||||
_screg.getSceneManager(sceneId);
|
||||
if (smgr == null) {
|
||||
Log.warning("User requested cluster chat in " +
|
||||
"non-existent scene [user=" + speaker +
|
||||
", sceneId=" + sceneId + ", locId=" + locId +
|
||||
Log.warning("User requested cluster chat in non-existent scene " +
|
||||
"[user=" + speaker + ", sceneId=" + sceneId +
|
||||
", message=" + message + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// pass this request on to the spot scene manager
|
||||
smgr.handleClusterSpeakRequest(
|
||||
speakerOid, speaker, bundle, message, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the scene id occupied by the supplied caller.
|
||||
*
|
||||
* @exception InvocationException thrown if the caller does not
|
||||
* implement {@link ScenedBodyObject}.
|
||||
*/
|
||||
protected static int getCallerSceneId (ClientObject caller)
|
||||
throws InvocationException
|
||||
{
|
||||
if (caller instanceof ScenedBodyObject) {
|
||||
return ((ScenedBodyObject)caller).getSceneId();
|
||||
} else {
|
||||
// pass this request on to the spot scene manager as it will
|
||||
// need to check that the location exists and that the speaker
|
||||
// occupies it and so on
|
||||
smgr.handleClusterSpeakRequest(
|
||||
speakerOid, speaker, locId, bundle, message, mode);
|
||||
Log.warning("Can't get scene from non-scened caller " +
|
||||
caller.who() + ".");
|
||||
throw new InvocationException(INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
//
|
||||
// $Id: SpotSceneManager.java,v 1.24 2003/01/31 23:10:46 mdb Exp $
|
||||
// $Id: SpotSceneManager.java,v 1.25 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.spot.server;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.ArrayIntSet;
|
||||
import com.samskivert.util.HashIntMap;
|
||||
import com.samskivert.util.IntIntMap;
|
||||
import com.samskivert.util.IntListUtil;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.presents.dobj.DObject;
|
||||
@@ -20,10 +23,14 @@ import com.threerings.whirled.server.SceneManager;
|
||||
|
||||
import com.threerings.whirled.spot.Log;
|
||||
import com.threerings.whirled.spot.data.ClusterObject;
|
||||
import com.threerings.whirled.spot.data.ClusteredBodyObject;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SceneLocation;
|
||||
import com.threerings.whirled.spot.data.SpotCodes;
|
||||
import com.threerings.whirled.spot.data.SpotOccupantInfo;
|
||||
import com.threerings.whirled.spot.data.SpotScene;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
import com.threerings.whirled.spot.util.SpotSceneUtil;
|
||||
import com.threerings.whirled.spot.data.SpotSceneObject;
|
||||
|
||||
/**
|
||||
* Handles the movement of bodies between locations in the scene and
|
||||
@@ -41,202 +48,207 @@ public class SpotSceneManager extends SceneManager
|
||||
SpotSceneManager mgr = (SpotSceneManager)
|
||||
CrowdServer.plreg.getPlaceManager(body.location);
|
||||
if (mgr != null) {
|
||||
RuntimeSpotScene scene = (RuntimeSpotScene)mgr.getScene();
|
||||
SpotScene scene = (SpotScene)mgr.getScene();
|
||||
try {
|
||||
mgr.handleChangeLocRequest(body, scene.getDefaultEntranceId());
|
||||
Location eloc = scene.getDefaultEntrance().getLocation();
|
||||
mgr.handleChangeLocRequest(body, eloc, -1);
|
||||
} catch (InvocationException ie) {
|
||||
Log.warning("Could not walk user to default portal " +
|
||||
"[error=" + ie + "].");
|
||||
Log.warning("Could not move user to default portal " +
|
||||
"[where=" + mgr.where() + ", who=" + body.who() +
|
||||
", error=" + ie + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a mapping for an entering body, indicating that they will
|
||||
* be entering at the specified location id. When the time comes to
|
||||
* prepare that body's occupant info, we will use the supplied
|
||||
* location id as their starting location.
|
||||
* Assigns a starting location for an entering body. This will happen
|
||||
* before the body is made to "occupy" the scene (defined by their
|
||||
* having an occupant info record). So when they do finally occupy the
|
||||
* scene, the client will know where to render them.
|
||||
*/
|
||||
public void mapEnteringBody (int bodyOid, int locationId)
|
||||
public void mapEnteringBody (BodyObject body, int portalId)
|
||||
{
|
||||
_entering.put(bodyOid, locationId);
|
||||
_enterers.put(body.getOid(), portalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* If scene entry fails, this can be called to undo a scene entry
|
||||
* mapping.
|
||||
* Called if a body failed to enter our scene after we assigned them
|
||||
* an entering position.
|
||||
*/
|
||||
public void clearEnteringBody (int bodyOid)
|
||||
public void clearEnteringBody (BodyObject body)
|
||||
{
|
||||
_entering.remove(bodyOid);
|
||||
_enterers.remove(body.getOid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locationId of an unoccupied location in this scene
|
||||
* (portals are not included when selecting). If no locations are
|
||||
* unoccupied, this method returns -1. This will mark the location as
|
||||
* pending so that subsequent calls to
|
||||
* <code>getUnoccupiedLocation()</code> do not return the previously
|
||||
* returned location as unoccupied, giving the caller a chance to
|
||||
* actually occupy the location. However, if another user moves to
|
||||
* that location bewteen the call to this method and the caller's own
|
||||
* request to move to the location, the caller's move request will
|
||||
* fail.
|
||||
*/
|
||||
public int getUnoccupiedLocation (boolean preferClusters)
|
||||
// documentation inherited
|
||||
protected void didStartup ()
|
||||
{
|
||||
int locId = SpotSceneUtil.getUnoccupiedLocation(
|
||||
_sscene.getModel(), _locationOccs, preferClusters);
|
||||
if (locId != -1) {
|
||||
// mark the location as pending
|
||||
// Log.info("Earmarked location [scene=" + where() +
|
||||
// ", locId=" + locId + "].");
|
||||
_locationOccs[_sscene.getLocationIndex(locId)] = -1;
|
||||
}
|
||||
return locId;
|
||||
}
|
||||
// get a casted reference to our place object (we need to do this
|
||||
// before calling super.didStartup() because that will call
|
||||
// sceneManagerDidResolve() which may start letting people into
|
||||
// the scene)
|
||||
_ssobj = (SpotSceneObject)_plobj;
|
||||
|
||||
/**
|
||||
* Returns true if the location in question is occupied by another
|
||||
* body (or reserved for someone who's on their way).
|
||||
*/
|
||||
public boolean isLocationOccupied (int locId)
|
||||
{
|
||||
return (_locationOccs[_sscene.getLocationIndex(locId)] != 0);
|
||||
super.didStartup();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void gotSceneData ()
|
||||
{
|
||||
super.gotSceneData();
|
||||
|
||||
// keep a casted reference around to our scene
|
||||
_sscene = (RuntimeSpotScene)_scene;
|
||||
|
||||
// now that we have our scene, we create chat objects for each of
|
||||
// the clusters in the scene
|
||||
_clusterObjs = new DObject[_sscene.getClusterCount()];
|
||||
|
||||
// create a subscriber that will grab the oids when we hear back
|
||||
// about object creation
|
||||
Subscriber sub = new Subscriber() {
|
||||
public void objectAvailable (DObject object) {
|
||||
_clusterObjs[_index++] = object;
|
||||
}
|
||||
|
||||
public void requestFailed (int oid, ObjectAccessException cause) {
|
||||
Log.warning("Failed to create cluster object " +
|
||||
"[where=" + where() + ", cluster=" + _index +
|
||||
", oid=" + oid + ", cause=" + cause + "].");
|
||||
// skip to the next cluster in case others didn't fail
|
||||
_index++;
|
||||
}
|
||||
|
||||
protected int _index = 0;
|
||||
};
|
||||
|
||||
// now issue the object creation requests
|
||||
for (int i = 0; i < _clusterObjs.length; i++) {
|
||||
_omgr.createObject(ClusterObject.class, sub);
|
||||
}
|
||||
|
||||
// create an array in which to track the occupants of each
|
||||
// location
|
||||
_locationOccs = new int[_sscene.getLocationCount()];
|
||||
|
||||
_isPortal = new boolean[_sscene.getLocationCount()];
|
||||
SpotSceneModel model = _sscene.getModel();
|
||||
for (int ii=0; ii < model.locationIds.length; ii++) {
|
||||
_isPortal[ii] = IntListUtil.contains(model.portalIds,
|
||||
model.locationIds[ii]);
|
||||
}
|
||||
_sscene = (SpotScene)_scene;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a user is entering a scene, we populate their occupant info
|
||||
* with the location prepared by the portal traversal code or with the
|
||||
* default entrance for the scene if no preparation was done.
|
||||
*/
|
||||
// documentation inherited
|
||||
protected void bodyLeft (int bodyOid)
|
||||
{
|
||||
super.bodyLeft(bodyOid);
|
||||
|
||||
// clear out their location information
|
||||
_ssobj.removeFromOccupantLocs(new Integer(bodyOid));
|
||||
|
||||
// clear any cluster they may occupy
|
||||
removeFromCluster(bodyOid);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected void populateOccupantInfo (OccupantInfo info, BodyObject body)
|
||||
{
|
||||
super.populateOccupantInfo(info, body);
|
||||
|
||||
// we have a table for tracking the locations of entering bodies
|
||||
// which is populated by the portal traversal code when a body
|
||||
// requests to enter our scene. if there's a mapped entrance
|
||||
// location for this body, use it, otherwise assume they're coming
|
||||
// in at the default entrance
|
||||
int entryLocId = _entering.remove(body.getOid());
|
||||
if (entryLocId == -1) {
|
||||
entryLocId = _sscene.getDefaultEntranceId();
|
||||
// we don't actually populate their occupant info, but instead
|
||||
// assign them their starting location in the scene
|
||||
int portalId = _enterers.remove(body.getOid());
|
||||
Portal entry;
|
||||
if (portalId != -1) {
|
||||
entry = _sscene.getPortal(portalId);
|
||||
if (entry == null) {
|
||||
Log.warning("Body mapped at invalid portal [where=" + where() +
|
||||
", who=" + body.who() +
|
||||
", portalId=" + portalId + "].");
|
||||
entry = _sscene.getDefaultEntrance();
|
||||
}
|
||||
} else {
|
||||
entry = _sscene.getDefaultEntrance();
|
||||
}
|
||||
((SpotOccupantInfo)info).locationId = entryLocId;
|
||||
|
||||
// Log.info("Positioning entering body [who=" + body.who() +
|
||||
// ", where=" + entry.getOppLocation() + "].");
|
||||
|
||||
// create a scene location for them located on the entrance portal
|
||||
// but facing the opposite direction
|
||||
_ssobj.addToOccupantLocs(
|
||||
new SceneLocation(entry.getOppLocation(), body.getOid()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the {@link SpotProvider} when we receive a request by a
|
||||
* user to occupy a particular location.
|
||||
*
|
||||
* @return the oid of the chat object associated with the cluster to
|
||||
* which this location belongs or -1 if the location is not part of a
|
||||
* cluster.
|
||||
* @param source the body to be moved.
|
||||
* @param loc the location to which to move the body.
|
||||
* @param cluster if zero, a new cluster will be created and assigned
|
||||
* to the moving user; if -1, the moving user will be removed from any
|
||||
* cluster they currently occupy and not made to occupy a new cluster;
|
||||
* if the bodyOid of another user, the moving user will be made to
|
||||
* join the other user's cluster.
|
||||
*
|
||||
* @exception InvocationException thrown with a reason code explaining
|
||||
* the location change failure if there is a problem processing the
|
||||
* location change request.
|
||||
*/
|
||||
protected int handleChangeLocRequest (BodyObject source, int locationId)
|
||||
protected void handleChangeLocRequest (
|
||||
BodyObject source, Location loc, int cluster)
|
||||
throws InvocationException
|
||||
{
|
||||
// make sure no one is already in the requested location
|
||||
int locidx = _sscene.getLocationIndex(locationId);
|
||||
if (locidx == -1) {
|
||||
Log.warning("Ignoring request to move to non-existent location " +
|
||||
"[where=" + where() + ", user=" + source.who() +
|
||||
", locId=" + locationId + "].");
|
||||
throw new InvocationException(LOCATION_OCCUPIED);
|
||||
|
||||
} else if (_locationOccs[locidx] > 0) {
|
||||
Log.info("Ignoring request to move to occupied location " +
|
||||
"[where=" + where() + ", user=" + source.who() +
|
||||
", locId=" + locationId +
|
||||
", occupantOid=" + _locationOccs[locidx] + "].");
|
||||
throw new InvocationException(LOCATION_OCCUPIED);
|
||||
}
|
||||
|
||||
// make sure they have an occupant info object in the place
|
||||
int bodyOid = source.getOid();
|
||||
SpotOccupantInfo soi = (SpotOccupantInfo)getOccupantInfo(bodyOid);
|
||||
if (soi == null) {
|
||||
Log.warning("Aiya! Can't update non-existent occupant info " +
|
||||
"with new location [where=" + where() +
|
||||
", body=" + source.who() + ":" + source.location +
|
||||
", newLocId=" + locationId + "].");
|
||||
// make sure they are in our scene
|
||||
if (!_ssobj.occupants.contains(source.getOid())) {
|
||||
Log.warning("Refusing change loc from non-scene occupant " +
|
||||
"[where=" + where() + ", who=" + source.who() +
|
||||
", loc=" + loc + "].");
|
||||
throw new InvocationException(INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
// clear out any location they previously occupied
|
||||
if (soi.locationId > 0) {
|
||||
int oldlocidx = _sscene.getLocationIndex(soi.locationId);
|
||||
if (oldlocidx == -1) {
|
||||
Log.warning("Changing location for body that was " +
|
||||
"previously in an invalid location " +
|
||||
"[where=" + where() + ", info=" + soi + "].");
|
||||
} else {
|
||||
_locationOccs[oldlocidx] = 0;
|
||||
}
|
||||
// update the user's location information in the scene which will
|
||||
// indicate to the client that their avatar should be moved from
|
||||
// its current position to their new position
|
||||
SceneLocation sloc = new SceneLocation(loc, source.getOid());
|
||||
if (!_ssobj.occupantLocs.contains(sloc)) {
|
||||
// complain if they don't already have a location configured
|
||||
Log.warning("Changing loc for occupant without previous loc " +
|
||||
"[where=" + where() + ", who=" + source.who() +
|
||||
", nloc=" + loc + "].");
|
||||
_ssobj.addToOccupantLocs(sloc);
|
||||
} else {
|
||||
_ssobj.updateOccupantLocs(sloc);
|
||||
}
|
||||
|
||||
// stick our new friend into that location, if it's not a portal
|
||||
if (!_isPortal[locidx]) {
|
||||
_locationOccs[locidx] = bodyOid;
|
||||
// handle the cluster situation
|
||||
switch (cluster) {
|
||||
case 0:
|
||||
createNewCluster(source);
|
||||
break;
|
||||
case -1:
|
||||
removeFromCluster(source.getOid());
|
||||
break;
|
||||
default:
|
||||
addToCluster(cluster, source);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// update the location and broadcast to the place
|
||||
soi.locationId = locationId;
|
||||
updateOccupantInfo(soi);
|
||||
/**
|
||||
* Creates a new cluster with the specified user being added to said
|
||||
* cluster.
|
||||
*/
|
||||
protected void createNewCluster (BodyObject creator)
|
||||
{
|
||||
// remove them from any previous cluster
|
||||
removeFromCluster(creator.getOid());
|
||||
|
||||
// figure out the cluster chat oid
|
||||
int clusterIdx = _sscene.getClusterIndex(locidx);
|
||||
return (clusterIdx == -1) ? -1 : _clusterObjs[clusterIdx].getOid();
|
||||
// create a cluster record and map this user to it
|
||||
ClusterRecord clrec = new ClusterRecord();
|
||||
if (clrec.addBody(creator)) {
|
||||
_clusters.put(creator.getOid(), clrec);
|
||||
}
|
||||
// if we failed to add the creator, the cluster record will
|
||||
// quietly off itself when it's done subscribing to its object
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified user to the cluster occupied by the specified
|
||||
* other user.
|
||||
*/
|
||||
protected void addToCluster (int memberOid, BodyObject joiner)
|
||||
{
|
||||
ClusterRecord clrec = (ClusterRecord)_clusters.get(memberOid);
|
||||
if (clrec == null) {
|
||||
// this isn't completely impossible as the last user might
|
||||
// leave a cluster just as another user is entering it, but
|
||||
// before the entering user's client was informed that the
|
||||
// cluster went away
|
||||
Log.info("Can't add user to non-existent cluster; " +
|
||||
"creating a new one just for them " +
|
||||
"[memberOid=" + memberOid +
|
||||
", joiner=" + joiner.who() + "].");
|
||||
clrec = new ClusterRecord();
|
||||
}
|
||||
if (clrec.addBody(joiner)) {
|
||||
_clusters.put(joiner.getOid(), clrec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified user from any cluster they occupy.
|
||||
*/
|
||||
protected void removeFromCluster (int bodyOid)
|
||||
{
|
||||
ClusterRecord clrec = (ClusterRecord)_clusters.remove(bodyOid);
|
||||
if (clrec != null) {
|
||||
clrec.removeBody(bodyOid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,99 +256,123 @@ public class SpotSceneManager extends SceneManager
|
||||
* request.
|
||||
*/
|
||||
protected void handleClusterSpeakRequest (
|
||||
int sourceOid, String source, int locationId,
|
||||
String bundle, String message, byte mode)
|
||||
int sourceOid, String source, String bundle, String message, byte mode)
|
||||
{
|
||||
int locIdx = _sscene.getLocationIndex(locationId);
|
||||
|
||||
// make sure this user occupies the specified location
|
||||
int locOccId = (locIdx == -1) ? -1 : _locationOccs[locIdx];
|
||||
if (locOccId != sourceOid) {
|
||||
Log.warning("User not in specified location for CCREQ " +
|
||||
ClusterRecord clrec = (ClusterRecord)_clusters.get(sourceOid);
|
||||
if (clrec == null) {
|
||||
Log.warning("Non-clustered user requested cluster speak " +
|
||||
"[where=" + where() + ", chatter=" + source +
|
||||
" (" + sourceOid + "), locId=" + locationId +
|
||||
", locIdx=" + locIdx +
|
||||
", locOccs=" + StringUtil.toString(_locationOccs) +
|
||||
", message=" + message + "].");
|
||||
return;
|
||||
" (" + sourceOid + "), msg=" + message + "].");
|
||||
} else {
|
||||
SpeakProvider.sendSpeak(clrec.getClusterObject(),
|
||||
source, bundle, message, mode);
|
||||
}
|
||||
|
||||
// make sure there's a cluster associated with this location
|
||||
int clusterIndex = _sscene.getClusterIndex(locIdx);
|
||||
if (clusterIndex == -1) {
|
||||
Log.warning("User in clusterless location sent CCREQ " +
|
||||
"[where=" + where() + ", chatter=" + source +
|
||||
" (" + sourceOid + "), locId=" + locationId +
|
||||
", message=" + message + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
DObject clusterObj = _clusterObjs[clusterIndex];
|
||||
if (clusterObj == null) {
|
||||
Log.warning("Have no cluster object for CCREQ " +
|
||||
"[where=" + where() + ", cidx=" + clusterIndex +
|
||||
", chatter=" + source + " (" + sourceOid +
|
||||
"), message=" + message + "].");
|
||||
return;
|
||||
}
|
||||
|
||||
// all is well, generate a chat notification
|
||||
SpeakProvider.sendSpeak(clusterObj, source, bundle, message, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the specified user is in the scene and
|
||||
* in a valid location (not on a portal).
|
||||
* Used to manage clusters which are groups of users that can chat to
|
||||
* one another.
|
||||
*/
|
||||
protected boolean inValidLocation (BodyObject body)
|
||||
protected static class ClusterRecord extends HashIntMap
|
||||
implements Subscriber
|
||||
{
|
||||
int bodyOid = body.getOid();
|
||||
for (int ii=0; ii < _locationOccs.length; ii++) {
|
||||
if (_locationOccs[ii] == bodyOid) {
|
||||
public ClusterRecord ()
|
||||
{
|
||||
CrowdServer.omgr.createObject(ClusterObject.class, this);
|
||||
}
|
||||
|
||||
public boolean addBody (BodyObject body)
|
||||
{
|
||||
if (body instanceof ClusteredBodyObject) {
|
||||
if (_clobj != null) {
|
||||
((ClusteredBodyObject)body).setClusterOid(_clobj.getOid());
|
||||
}
|
||||
put(body.getOid(), body);
|
||||
_clobj.addToOccupants(body.getOid());
|
||||
return true;
|
||||
|
||||
} else {
|
||||
Log.warning("Refusing to add non-clustered body to cluster " +
|
||||
"[cloid=" + _clobj.getOid() +
|
||||
", size=" + size() + ", who=" + body.who() + "].");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* When an occupant leaves the room, we want to clear out any location
|
||||
* they may have occupied.
|
||||
*/
|
||||
protected void bodyLeft (int bodyOid)
|
||||
{
|
||||
super.bodyLeft(bodyOid);
|
||||
public void removeBody (int bodyOid)
|
||||
{
|
||||
ClusteredBodyObject body = (ClusteredBodyObject)remove(bodyOid);
|
||||
if (body == null) {
|
||||
Log.warning("Requested to remove unknown body from cluster " +
|
||||
"[cloid=" + _clobj.getOid() +
|
||||
", size=" + size() + ", who=" + bodyOid + "].");
|
||||
} else {
|
||||
body.setClusterOid(-1);
|
||||
_clobj.removeFromOccupants(bodyOid);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _locationOccs.length; i++) {
|
||||
if (_locationOccs[i] == bodyOid) {
|
||||
_locationOccs[i] = 0;
|
||||
break;
|
||||
// if we've removed our last body; stick a fork in ourselves
|
||||
if (size() == 0) {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public ClusterObject getClusterObject ()
|
||||
{
|
||||
return _clobj;
|
||||
}
|
||||
|
||||
public void objectAvailable (DObject object)
|
||||
{
|
||||
// keep this feller around
|
||||
_clobj = (ClusterObject)object;
|
||||
|
||||
// let any mapped users know about our cluster
|
||||
Iterator iter = values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
ClusteredBodyObject body = (ClusteredBodyObject)iter.next();
|
||||
body.setClusterOid(_clobj.getOid());
|
||||
}
|
||||
|
||||
// if we didn't manage to add our creating user when we first
|
||||
// started up, there's no point in our sticking around
|
||||
if (size() == 0) {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public void requestFailed (int oid, ObjectAccessException cause)
|
||||
{
|
||||
Log.warning("Aiya! Failed to create cluster object " +
|
||||
"[cause=" + cause + ", penders=" + size() + "].");
|
||||
|
||||
// let any mapped users know that we're hosed
|
||||
Iterator iter = values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
ClusteredBodyObject body = (ClusteredBodyObject)iter.next();
|
||||
body.setClusterOid(-1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void destroy ()
|
||||
{
|
||||
Log.info("Cluster empty, going away " +
|
||||
"[cloid=" + _clobj.getOid() + "].");
|
||||
CrowdServer.omgr.destroyObject(_clobj.getOid());
|
||||
}
|
||||
|
||||
protected ClusterObject _clobj;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need our own extended occupant info to keep track of what
|
||||
* location each occupant occupies.
|
||||
*/
|
||||
protected Class getOccupantInfoClass ()
|
||||
{
|
||||
return SpotOccupantInfo.class;
|
||||
}
|
||||
/** A casted reference to our place object. */
|
||||
protected SpotSceneObject _ssobj;
|
||||
|
||||
/** A casted reference to our runtime scene instance. */
|
||||
protected RuntimeSpotScene _sscene;
|
||||
/** A casted reference to our scene instance. */
|
||||
protected SpotScene _sscene;
|
||||
|
||||
/** Our cluster chat objects. */
|
||||
protected DObject[] _clusterObjs;
|
||||
/** Records with information on all clusters in this scene. */
|
||||
protected HashIntMap _clusters = new HashIntMap();
|
||||
|
||||
/** Oids of the bodies that occupy each of our locations. */
|
||||
protected int[] _locationOccs;
|
||||
|
||||
/** Tracks if each location is a portal. */
|
||||
protected boolean[] _isPortal;
|
||||
|
||||
/** A table of mappings from body oids to entry location ids for
|
||||
* bodies that are entering our scene. */
|
||||
protected IntIntMap _entering = new IntIntMap();
|
||||
/** A mapping of entering bodies to portal ids. */
|
||||
protected IntIntMap _enterers = new IntIntMap();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// $Id: EditablePortal.java,v 1.2 2001/12/05 03:38:09 mdb Exp $
|
||||
// $Id: EditablePortal.java,v 1.3 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot;
|
||||
package com.threerings.whirled.spot.tools;
|
||||
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
|
||||
@@ -21,13 +21,4 @@ public class EditablePortal extends Portal
|
||||
/** The human-readable name of the portal to which this portal links
|
||||
* in its target scene. */
|
||||
public String targetPortalName;
|
||||
|
||||
// documentation inherited
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", name=").append(name);
|
||||
buf.append(", targetScene=").append(targetSceneName);
|
||||
buf.append(", targetPortal=").append(targetPortalName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
//
|
||||
// $Id: EditableSpotScene.java,v 1.5 2001/12/05 09:20:10 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot;
|
||||
|
||||
import com.threerings.whirled.tools.EditableScene;
|
||||
|
||||
import com.threerings.whirled.spot.client.DisplaySpotScene;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
/**
|
||||
* The editable spot scene interface is used in the offline scene building
|
||||
* tools as well as by the tools that load those prototype scenes into the
|
||||
* runtime database. Accordingly, it provides a means for modifying scene
|
||||
* values and for obtaining access to the underlying scene models that
|
||||
* represent the underlying scene information.
|
||||
*
|
||||
* @see EditableScene
|
||||
*/
|
||||
public interface EditableSpotScene
|
||||
extends DisplaySpotScene, EditableScene
|
||||
{
|
||||
/**
|
||||
* Sets the location id of the default entrance to this scene.
|
||||
*/
|
||||
public void setDefaultEntranceId (int defaultEntranceId);
|
||||
|
||||
/**
|
||||
* Returns the next valid location id for this scene. Newly created
|
||||
* portals or locations should be assigned a new location id via this
|
||||
* method.
|
||||
*/
|
||||
public int getNextLocationId ();
|
||||
|
||||
/**
|
||||
* Adds a location to this scene.
|
||||
*/
|
||||
public void addLocation (Location location);
|
||||
|
||||
/**
|
||||
* Removes the specified location from the scene.
|
||||
*/
|
||||
public void removeLocation (Location location);
|
||||
|
||||
/**
|
||||
* Adds a portal to this scene (it should be added appropriately to
|
||||
* both the location and portal arrays).
|
||||
*/
|
||||
public void addPortal (EditablePortal portal);
|
||||
|
||||
/**
|
||||
* Removes a portal from this scene (it should be removed accordingly
|
||||
* from both the location and portal arrays).
|
||||
*/
|
||||
public void removePortal (EditablePortal portal);
|
||||
|
||||
/**
|
||||
* Implementations must provide a scene model that represents the
|
||||
* current state of this editable scene in response to a call to this
|
||||
* method. Whether they maintain an up to date scene model all along
|
||||
* or generate one at the time this method is called is up to the
|
||||
* implementation.
|
||||
*/
|
||||
public EditableSpotSceneModel getSpotSceneModel ();
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
//
|
||||
// $Id: EditableSpotSceneImpl.java,v 1.11 2003/01/31 23:10:46 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.tools.EditableSceneModel;
|
||||
import com.threerings.whirled.tools.EditableSceneImpl;
|
||||
|
||||
import com.threerings.whirled.spot.client.DisplaySpotSceneImpl;
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
import com.threerings.whirled.spot.Log;
|
||||
|
||||
/**
|
||||
* The editable spot scene interface is used in the offline scene building
|
||||
* tools as well as by the tools that load those prototype scenes into the
|
||||
* runtime database. Accordingly, it provides a means for modifying scene
|
||||
* values and for obtaining access to the underlying scene models that
|
||||
* represent the underlying scene information.
|
||||
*
|
||||
* <p> Scrutinizers of the code might cringe at the somewhat inefficient
|
||||
* array manipulation used to preserve the integrity of the arrays
|
||||
* returned by {@link #getLocations} and {@link #getPortals}. Since we
|
||||
* expect reading to happen more often than modifying, this seemed a
|
||||
* reasonable tradeoff, and one should also note that this class will only
|
||||
* ever be used in the offline editor and not in any performance
|
||||
* constrained runtime system.
|
||||
*
|
||||
* @see com.threerings.whirled.tools.EditableScene
|
||||
*/
|
||||
public class EditableSpotSceneImpl extends EditableSceneImpl
|
||||
implements EditableSpotScene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will create and use a blank scene model.
|
||||
*/
|
||||
public EditableSpotSceneImpl ()
|
||||
{
|
||||
this(EditableSpotSceneModel.blankSpotSceneModel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and update it when changes are made.
|
||||
*/
|
||||
public EditableSpotSceneImpl (EditableSpotSceneModel model)
|
||||
{
|
||||
this(model, new DisplaySpotSceneImpl(model.spotSceneModel, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and update it when changes are made. It will delegate to the
|
||||
* supplied display spot scene instead of creating its own delegate.
|
||||
*/
|
||||
public EditableSpotSceneImpl (
|
||||
EditableSpotSceneModel model, DisplaySpotSceneImpl delegate)
|
||||
{
|
||||
super(model, delegate);
|
||||
|
||||
// keep track of these
|
||||
_model = model.spotSceneModel;
|
||||
_emodel = model;
|
||||
_delegate = delegate;
|
||||
|
||||
// go through and replace the plain portals with editable portals
|
||||
// (oh the machinations we have to go through for the lack of
|
||||
// multiple inheritance)
|
||||
List portals = _delegate.getPortals();
|
||||
for (int i = 0; i < portals.size(); i++) {
|
||||
EditablePortal port = dupePortal((Portal)portals.get(i));;
|
||||
port.name = _emodel.portalNames[i];
|
||||
port.targetSceneName = (String)_emodel.neighborNames.get(i);
|
||||
port.targetPortalName = _emodel.targetPortalNames[i];
|
||||
portals.set(i, port);
|
||||
}
|
||||
|
||||
// determine the highest location id in use by this scene
|
||||
Iterator iter = _delegate.getLocations().iterator();
|
||||
while (iter.hasNext()) {
|
||||
_nextLocationId = Math.max(_nextLocationId,
|
||||
((Location)iter.next()).locationId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an editable portal with the same configuration as the
|
||||
* supplied regular portal.
|
||||
*/
|
||||
protected EditablePortal dupePortal (Portal source)
|
||||
{
|
||||
EditablePortal port = new EditablePortal();
|
||||
port.locationId = source.locationId;
|
||||
port.x = source.x;
|
||||
port.y = source.y;
|
||||
port.orientation = source.orientation;
|
||||
port.clusterIndex = source.clusterIndex;
|
||||
port.targetSceneId = source.targetSceneId;
|
||||
port.targetLocId = source.targetLocId;
|
||||
return port;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getDefaultEntranceId ()
|
||||
{
|
||||
return _delegate.getDefaultEntranceId();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public List getLocations ()
|
||||
{
|
||||
return _delegate.getLocations();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getLocationIndex (int locationId)
|
||||
{
|
||||
return _delegate.getLocationIndex(locationId);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Location getLocation (int locationId)
|
||||
{
|
||||
return _delegate.getLocation(locationId);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public List getPortals ()
|
||||
{
|
||||
return _delegate.getPortals();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setDefaultEntranceId (int defaultEntranceId)
|
||||
{
|
||||
_model.defaultEntranceId = defaultEntranceId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getNextLocationId ()
|
||||
{
|
||||
return ++_nextLocationId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addLocation (Location loc)
|
||||
{
|
||||
// add the location to the end of the location list
|
||||
_delegate.getLocations().add(loc);
|
||||
|
||||
// make sure we've got the highest location id in our next
|
||||
// location id field
|
||||
_nextLocationId = Math.max(_nextLocationId, loc.locationId);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void removeLocation (Location loc)
|
||||
{
|
||||
// remove the location from the list
|
||||
_delegate.getLocations().remove(loc);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addPortal (EditablePortal eport)
|
||||
{
|
||||
// add it to the locations lists as well
|
||||
addLocation(eport);
|
||||
|
||||
// now add it to the end of the _portals list
|
||||
_delegate.getPortals().add(eport);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void removePortal (EditablePortal eport)
|
||||
{
|
||||
// remove it from the locations list
|
||||
removeLocation(eport);
|
||||
|
||||
// and remove it from the portals list
|
||||
_delegate.getPortals().remove(eport);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public EditableSpotSceneModel getSpotSceneModel ()
|
||||
{
|
||||
flushToModel();
|
||||
return _emodel;
|
||||
}
|
||||
|
||||
/**
|
||||
* This ensures that the modifications we've made to the location and
|
||||
* portal arrays are flushed to the model. It is called before
|
||||
* returning our model back to the caller.
|
||||
*/
|
||||
protected void flushToModel ()
|
||||
{
|
||||
super.flushToModel();
|
||||
|
||||
List locations = _delegate.getLocations();
|
||||
|
||||
// flush the locations
|
||||
int lcount = locations.size();
|
||||
_model.locationIds = new int[lcount];
|
||||
_model.locationX = new int[lcount];
|
||||
_model.locationY = new int[lcount];
|
||||
_model.locationOrients = new int[lcount];
|
||||
_model.locationClusters = new int[lcount];
|
||||
|
||||
for (int i = 0; i < lcount; i++) {
|
||||
Location loc = (Location)locations.get(i);
|
||||
_model.locationIds[i] = loc.locationId;
|
||||
_model.locationX[i] = loc.x;
|
||||
_model.locationY[i] = loc.y;
|
||||
_model.locationOrients[i] = loc.orientation;
|
||||
_model.locationClusters[i] = loc.clusterIndex;
|
||||
}
|
||||
|
||||
// flush the portals
|
||||
List portals = _delegate.getPortals();
|
||||
int pcount = portals.size();
|
||||
_model.portalIds = new int[pcount];
|
||||
_model.neighborIds = new int[pcount];
|
||||
_model.targetLocIds = new int[pcount];
|
||||
_emodel.neighborNames = new ArrayList();
|
||||
_emodel.portalNames = new String[pcount];
|
||||
_emodel.targetPortalNames = new String[pcount];
|
||||
|
||||
for (int i = 0; i < pcount; i++) {
|
||||
EditablePortal port = (EditablePortal)portals.get(i);
|
||||
_model.portalIds[i] = port.locationId;
|
||||
_model.neighborIds[i] = port.targetSceneId;
|
||||
_model.targetLocIds[i] = port.targetLocId;
|
||||
_emodel.portalNames[i] = port.name;
|
||||
_emodel.neighborNames.add(port.targetSceneName);
|
||||
_emodel.targetPortalNames[i] = port.targetPortalName;
|
||||
}
|
||||
}
|
||||
|
||||
/** Our spot scene model. */
|
||||
protected SpotSceneModel _model;
|
||||
|
||||
/** Our editable spot scene model. */
|
||||
protected EditableSpotSceneModel _emodel;
|
||||
|
||||
/** Our display spot scene delegate. */
|
||||
protected DisplaySpotSceneImpl _delegate;
|
||||
|
||||
/** A location id counter used for assigning ids to new locations. */
|
||||
protected int _nextLocationId;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
//
|
||||
// $Id: EditableSpotSceneModel.java,v 1.3 2001/12/12 02:47:17 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
import com.threerings.whirled.tools.EditableSceneModel;
|
||||
|
||||
public class EditableSpotSceneModel extends EditableSceneModel
|
||||
{
|
||||
/** The spot scene model that we extend with editable info. */
|
||||
public SpotSceneModel spotSceneModel;
|
||||
|
||||
/** The names of the portals in this scene. */
|
||||
public String[] portalNames;
|
||||
|
||||
/** The names of the portals in neighboring scenes to which our
|
||||
* portals link. */
|
||||
public String[] targetPortalNames;
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
return cloneWithDelegate((SpotSceneModel)spotSceneModel.clone());
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Object cloneWithDelegate (SpotSceneModel spotSceneModel)
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
EditableSpotSceneModel essm = (EditableSpotSceneModel)
|
||||
super.cloneWithDelegate(spotSceneModel);
|
||||
essm.spotSceneModel = spotSceneModel;
|
||||
return essm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes override this to tack their <code>toString</code>
|
||||
* data on to the string buffer.
|
||||
*/
|
||||
protected void delegatesToString (StringBuffer buf)
|
||||
{
|
||||
buf.append(spotSceneModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes override this to tack their <code>toString</code>
|
||||
* data on to the string buffer.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
super.toString(buf);
|
||||
buf.append(", portalNames=").
|
||||
append(StringUtil.toString(portalNames));
|
||||
buf.append(", targetPortalNames=").
|
||||
append(StringUtil.toString(targetPortalNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a blank scene model.
|
||||
*/
|
||||
public static EditableSpotSceneModel blankSpotSceneModel ()
|
||||
{
|
||||
EditableSpotSceneModel model = new EditableSpotSceneModel();
|
||||
model.spotSceneModel = SpotSceneModel.blankSpotSceneModel();
|
||||
model.sceneModel = model.spotSceneModel;
|
||||
populateBlankSpotSceneModel(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a blank scene model with blank values.
|
||||
*/
|
||||
protected static void populateBlankSpotSceneModel (
|
||||
EditableSpotSceneModel model)
|
||||
{
|
||||
// populate our superclass fields
|
||||
populateBlankSceneModel(model);
|
||||
|
||||
// now populate our fields
|
||||
model.portalNames = new String[0];
|
||||
model.targetPortalNames = new String[0];
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
//
|
||||
// $Id: SpotSceneParser.java,v 1.1 2001/12/05 03:38:09 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.apache.commons.digester.Digester;
|
||||
|
||||
import com.threerings.whirled.tools.spot.EditableSpotScene;
|
||||
import com.threerings.whirled.tools.spot.EditableSpotSceneImpl;
|
||||
|
||||
/**
|
||||
* A simple class for parsing an editable spot scene instance.
|
||||
*/
|
||||
public class SpotSceneParser
|
||||
{
|
||||
/**
|
||||
* Constructs a scene parser that parses scenes with the specified XML
|
||||
* path prefix. See the {@link SpotSceneRuleSet#SpotSceneRuleSet}
|
||||
* documentation for more information.
|
||||
*/
|
||||
public SpotSceneParser (String prefix)
|
||||
{
|
||||
// create and configure our digester
|
||||
_digester = new Digester();
|
||||
SpotSceneRuleSet set = new SpotSceneRuleSet();
|
||||
set.setPrefix(prefix);
|
||||
_digester.addRuleSet(set);
|
||||
_digester.addSetNext(prefix, "setScene",
|
||||
EditableSpotScene.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the XML file at the specified path into an editable scene
|
||||
* instance.
|
||||
*/
|
||||
public EditableSpotScene parseScene (String path)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
_scene = null;
|
||||
_digester.push(this);
|
||||
_digester.parse(new FileInputStream(path));
|
||||
return _scene;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the parser once the scene is parsed.
|
||||
*/
|
||||
public void setScene (EditableSpotScene scene)
|
||||
{
|
||||
_scene = scene;
|
||||
}
|
||||
|
||||
protected Digester _digester;
|
||||
protected EditableSpotScene _scene;
|
||||
}
|
||||
@@ -1,54 +1,41 @@
|
||||
//
|
||||
// $Id: SpotSceneRuleSet.java,v 1.3 2001/12/05 03:40:32 mdb Exp $
|
||||
// $Id: SpotSceneRuleSet.java,v 1.4 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot.xml;
|
||||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.commons.digester.RuleSetBase;
|
||||
package com.threerings.whirled.spot.tools.xml;
|
||||
|
||||
import com.samskivert.xml.SetPropertyFieldsRule;
|
||||
import com.threerings.tools.xml.NestableRuleSet;
|
||||
import org.apache.commons.digester.Digester;
|
||||
|
||||
import com.threerings.whirled.tools.xml.SceneRuleSet;
|
||||
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.tools.spot.EditablePortal;
|
||||
import com.threerings.whirled.tools.spot.EditableSpotScene;
|
||||
import com.threerings.whirled.tools.spot.EditableSpotSceneImpl;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
import com.threerings.whirled.spot.tools.EditablePortal;
|
||||
|
||||
/**
|
||||
* Used to parse an {@link EditableSpotScene} from XML.
|
||||
* Used to parse a {@link SpotSceneModel} from XML.
|
||||
*/
|
||||
public class SpotSceneRuleSet extends SceneRuleSet
|
||||
public class SpotSceneRuleSet implements NestableRuleSet
|
||||
{
|
||||
/**
|
||||
* Extends the scene rule set with the necessary rules to parse our
|
||||
* spot scene data.
|
||||
*/
|
||||
public void addRuleInstances (Digester digester)
|
||||
// documentation inherited from interface
|
||||
public String getOuterElement ()
|
||||
{
|
||||
super.addRuleInstances(digester);
|
||||
return SpotSceneWriter.OUTER_ELEMENT;
|
||||
}
|
||||
|
||||
// create Location instances when we see <location>
|
||||
String elclass = Location.class.getName();
|
||||
digester.addObjectCreate(_prefix + "/location", elclass);
|
||||
digester.addRule(_prefix + "/location",
|
||||
new SetPropertyFieldsRule(digester));
|
||||
digester.addSetNext(_prefix + "/location", "addLocation", elclass);
|
||||
// documentation inherited from interface
|
||||
public void addRuleInstances (String prefix, Digester digester)
|
||||
{
|
||||
digester.addObjectCreate(prefix, SpotSceneModel.class.getName());
|
||||
|
||||
// set up rules to parse and set our fields
|
||||
digester.addRule(prefix, new SetPropertyFieldsRule(digester));
|
||||
|
||||
// create EditablePortal instances when we see <portal>
|
||||
String epclass = EditablePortal.class.getName();
|
||||
digester.addObjectCreate(_prefix + "/portal", epclass);
|
||||
digester.addRule(_prefix + "/portal",
|
||||
digester.addObjectCreate(prefix + "/portal",
|
||||
EditablePortal.class.getName());
|
||||
digester.addRule(prefix + "/portal",
|
||||
new SetPropertyFieldsRule(digester));
|
||||
digester.addSetNext(_prefix + "/portal", "addPortal", epclass);
|
||||
}
|
||||
|
||||
/**
|
||||
* This indicates the class (which should implement {@link
|
||||
* EditableSpotScene}) to be instantiated during the parsing process.
|
||||
*/
|
||||
protected Class getSceneClass ()
|
||||
{
|
||||
return EditableSpotSceneImpl.class;
|
||||
digester.addSetNext(prefix + "/portal", "addPortal",
|
||||
Portal.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,61 @@
|
||||
//
|
||||
// $Id: SpotSceneWriter.java,v 1.6 2001/12/07 05:14:57 mdb Exp $
|
||||
// $Id: SpotSceneWriter.java,v 1.7 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.spot.xml;
|
||||
|
||||
import java.util.Iterator;
|
||||
package com.threerings.whirled.spot.tools.xml;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
import com.megginson.sax.DataWriter;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.tools.xml.NestableWriter;
|
||||
|
||||
import com.threerings.whirled.spot.data.Location;
|
||||
import com.threerings.whirled.spot.data.Portal;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.tools.EditableScene;
|
||||
import com.threerings.whirled.tools.spot.EditablePortal;
|
||||
import com.threerings.whirled.tools.spot.EditableSpotScene;
|
||||
import com.threerings.whirled.tools.xml.SceneWriter;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
import com.threerings.whirled.spot.tools.EditablePortal;
|
||||
|
||||
/**
|
||||
* Generates an XML representation of an {@link EditableSpotScene}.
|
||||
* Generates an XML representation of a {@link SpotSceneModel}.
|
||||
*/
|
||||
public class SpotSceneWriter extends SceneWriter
|
||||
public class SpotSceneWriter
|
||||
implements NestableWriter
|
||||
{
|
||||
protected void addSceneAttributes (
|
||||
EditableScene scene, AttributesImpl attrs)
|
||||
{
|
||||
super.addSceneAttributes(scene, attrs);
|
||||
EditableSpotScene sscene = (EditableSpotScene)scene;
|
||||
attrs.addAttribute("", "defaultEntranceId", "", "",
|
||||
Integer.toString(sscene.getDefaultEntranceId()));
|
||||
}
|
||||
/** The outer element used to enclose our spot scene definition. */
|
||||
public static final String OUTER_ELEMENT = "spot";
|
||||
|
||||
protected void writeSceneData (EditableScene scene, DataWriter writer)
|
||||
// documentation inherited from interface
|
||||
public void write (Object object, DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
// we don't want to write our superclass scene data because it
|
||||
// writes out neighbors info which we deal with differently, so we
|
||||
// mean not to call super.writeSceneData()
|
||||
SpotSceneModel model = (SpotSceneModel)object;
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
addSceneAttributes(model, attrs);
|
||||
writer.startElement("", OUTER_ELEMENT, "", attrs);
|
||||
writeSceneData(model, writer);
|
||||
writer.endElement(OUTER_ELEMENT);
|
||||
}
|
||||
|
||||
EditableSpotScene sscene = (EditableSpotScene)scene;
|
||||
|
||||
// write out the location info
|
||||
Iterator iter = sscene.getLocations().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Location loc = (Location)iter.next();
|
||||
// skip portals as we'll get those on the next run
|
||||
if (loc instanceof EditablePortal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
addSharedAttrs(attrs, loc);
|
||||
attrs.addAttribute("", "clusterIndex", "", "",
|
||||
Integer.toString(loc.clusterIndex));
|
||||
writer.emptyElement("", "location", "", attrs);
|
||||
protected void addSceneAttributes (SpotSceneModel model,
|
||||
AttributesImpl attrs)
|
||||
{
|
||||
if (model.defaultEntranceId != -1) {
|
||||
attrs.addAttribute("", "defaultEntranceId", "", "",
|
||||
Integer.toString(model.defaultEntranceId));
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeSceneData (SpotSceneModel model, DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
// write out the portal info
|
||||
iter = sscene.getPortals().iterator();
|
||||
while (iter.hasNext()) {
|
||||
EditablePortal port = (EditablePortal)iter.next();
|
||||
for (int ii = 0; ii < model.portals.length; ii++) {
|
||||
EditablePortal port = (EditablePortal)model.portals[ii];
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
addSharedAttrs(attrs, port);
|
||||
attrs.addAttribute("", "portalId", "", "",
|
||||
Integer.toString(port.portalId));
|
||||
attrs.addAttribute("", "x", "", "", Integer.toString(port.x));
|
||||
attrs.addAttribute("", "y", "", "", Integer.toString(port.y));
|
||||
attrs.addAttribute("", "orient", "", "",
|
||||
Integer.toString(port.orient));
|
||||
maybeAddAttr(attrs, "name", port.name);
|
||||
maybeAddAttr(attrs, "targetSceneName", port.targetSceneName);
|
||||
maybeAddAttr(attrs, "targetPortalName", port.targetPortalName);
|
||||
@@ -83,18 +74,4 @@ public class SpotSceneWriter extends SceneWriter
|
||||
attrs.addAttribute("", name, "", "", value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the attributes that are shared between location and portal
|
||||
* elements.
|
||||
*/
|
||||
protected void addSharedAttrs (AttributesImpl attrs, Location loc)
|
||||
{
|
||||
attrs.addAttribute("", "locationId", "", "",
|
||||
Integer.toString(loc.locationId));
|
||||
attrs.addAttribute("", "x", "", "", Integer.toString(loc.x));
|
||||
attrs.addAttribute("", "y", "", "", Integer.toString(loc.y));
|
||||
attrs.addAttribute("", "orientation", "", "",
|
||||
Integer.toString(loc.orientation));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
//
|
||||
// $Id: SpotSceneUtil.java,v 1.2 2002/06/25 01:41:59 ray Exp $
|
||||
|
||||
package com.threerings.whirled.spot.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.samskivert.util.ArrayIntSet;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.util.RandomUtil;
|
||||
|
||||
import com.threerings.presents.dobj.DSet;
|
||||
import com.threerings.whirled.spot.data.SpotOccupantInfo;
|
||||
import com.threerings.whirled.spot.data.SpotSceneModel;
|
||||
|
||||
/**
|
||||
* Spot scene utility functions shared by client and server.
|
||||
*/
|
||||
public class SpotSceneUtil
|
||||
{
|
||||
/**
|
||||
* Returns the locationId of an unoccupied location in the supplied
|
||||
* scene (portals are not included when selecting). If no locations
|
||||
* are unoccupied, this method returns -1.
|
||||
*
|
||||
* @param preferClusters if true, cluster locations (if any are empty)
|
||||
* will be preferred.
|
||||
*/
|
||||
public static int getUnoccupiedLocation (
|
||||
SpotSceneModel model, DSet occupantInfo, boolean preferClusters)
|
||||
{
|
||||
ArrayIntSet locs = getStartSet(model, preferClusters);
|
||||
|
||||
// remove any occupied locations
|
||||
Iterator iter = occupantInfo.entries();
|
||||
while (iter.hasNext()) {
|
||||
SpotOccupantInfo yoi = (SpotOccupantInfo)iter.next();
|
||||
locs.remove(yoi.locationId);
|
||||
}
|
||||
|
||||
// if there are locations left, pick one at random
|
||||
int size = locs.size();
|
||||
if (size > 0) {
|
||||
return locs.get(RandomUtil.getInt(size));
|
||||
|
||||
} else if (preferClusters) {
|
||||
// retry without the preference
|
||||
return getUnoccupiedLocation(model, occupantInfo, false);
|
||||
|
||||
} else {
|
||||
return -1; // we didn't find anything.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locationId of an unoccupied location in the supplied
|
||||
* scene (portals are not included when selecting). If no locations
|
||||
* are unoccupied, this method returns -1.
|
||||
*
|
||||
* @param preferClusters if true, cluster locations (if any are empty)
|
||||
* will be preferred.
|
||||
*/
|
||||
public static int getUnoccupiedLocation (
|
||||
SpotSceneModel model, int[] occupiedLocs, boolean preferClusters)
|
||||
{
|
||||
ArrayIntSet locs = getStartSet(model, preferClusters);
|
||||
|
||||
// remove any occupied locations
|
||||
for (int ii = 0; ii < model.locationIds.length; ii++) {
|
||||
if (occupiedLocs[ii] != 0) {
|
||||
locs.remove(model.locationIds[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
// if there are locations left, pick one at random
|
||||
int size = locs.size();
|
||||
if (size > 0) {
|
||||
return locs.get(RandomUtil.getInt(size));
|
||||
|
||||
} else if (preferClusters) {
|
||||
// retry without the preference
|
||||
return getUnoccupiedLocation(model, occupiedLocs, false);
|
||||
|
||||
} else {
|
||||
return -1; // we didn't find anything.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an unoccupied location within the specified cluster.
|
||||
*/
|
||||
public static int getUnoccupiedLocation (
|
||||
SpotSceneModel model, DSet occupantInfo, int clusterId)
|
||||
{
|
||||
ArrayIntSet locs = new ArrayIntSet();
|
||||
|
||||
// only add locations with a valid cluster Id
|
||||
for (int ii=0; ii < model.locationIds.length; ii++) {
|
||||
if (model.locationClusters[ii] == clusterId) {
|
||||
locs.add(model.locationIds[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
// remove any occupied locations
|
||||
Iterator iter = occupantInfo.entries();
|
||||
while (iter.hasNext()) {
|
||||
SpotOccupantInfo yoi = (SpotOccupantInfo)iter.next();
|
||||
locs.remove(yoi.locationId);
|
||||
}
|
||||
|
||||
// if there are locations left, pick one at random
|
||||
int size = locs.size();
|
||||
if (size > 0) {
|
||||
return locs.get(RandomUtil.getInt(size));
|
||||
|
||||
} else {
|
||||
return -1; // we didn't find anything.
|
||||
}
|
||||
}
|
||||
|
||||
/** Used by {@link #getUnoccupiedLocation}. */
|
||||
protected static ArrayIntSet getStartSet (
|
||||
SpotSceneModel model, boolean preferClusters)
|
||||
{
|
||||
ArrayIntSet locs = new ArrayIntSet();
|
||||
|
||||
if (preferClusters) {
|
||||
// only add locations with a valid cluster Id
|
||||
for (int ii=0; ii < model.locationIds.length; ii++) {
|
||||
if (model.locationClusters[ii] != 0) {
|
||||
locs.add(model.locationIds[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// start with all the locations in the scene
|
||||
locs.add(model.locationIds);
|
||||
|
||||
// remove the portals
|
||||
locs.remove(model.portalIds);
|
||||
}
|
||||
|
||||
return locs;
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
//
|
||||
// $Id: EditableScene.java,v 1.4 2001/12/12 19:06:15 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.threerings.whirled.client.DisplayScene;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* The editable scene interface is used in the offline scene building
|
||||
* tools as well as by the tools that load those prototype scenes into the
|
||||
* runtime database. Accordingly, it provides a means for modifying scene
|
||||
* values and for obtaining access to the underlying scene models that
|
||||
* represent the underlying scene information.
|
||||
*
|
||||
* <p> Because the editable scene is used in the scene editor, where it is
|
||||
* displayed, the editable scene interface extends the {@link
|
||||
* DisplayScene} interface so that the same display mechanisms can be used
|
||||
* in the client and the editor. This leaves one anomaly, however which is
|
||||
* that {@link #getPlaceConfig} is out of place in the editor or in
|
||||
* loading tools. Instead of complicating things with an additional
|
||||
* interface that factors out that method, we instead recommend that
|
||||
* editable scene implementations simply return null from that method with
|
||||
* the expectation that it will never be called.
|
||||
*/
|
||||
public interface EditableScene extends DisplayScene
|
||||
{
|
||||
/**
|
||||
* Sets this scene's unique identifier.
|
||||
*/
|
||||
public void setId (int sceneId);
|
||||
|
||||
/**
|
||||
* Sets the human readable name of this scene.
|
||||
*/
|
||||
public void setName (String name);
|
||||
|
||||
/**
|
||||
* Sets this scene's version number.
|
||||
*/
|
||||
public void setVersion (int version);
|
||||
|
||||
/**
|
||||
* Sets the ids of the neighbors of this scene.
|
||||
*/
|
||||
public void setNeighborIds (int[] neighborIds);
|
||||
|
||||
/**
|
||||
* Returns the names of the neighbors of this scene.
|
||||
*/
|
||||
public ArrayList getNeighborNames ();
|
||||
|
||||
/**
|
||||
* Adds a neighbor to this scene. If the neighbor is already listed
|
||||
* among the neighbors, it will not be added again.
|
||||
*/
|
||||
public void addNeighbor (String neighborName);
|
||||
|
||||
/**
|
||||
* Adds a neighbor to this scene.
|
||||
*
|
||||
* @return true if the neighbor was removed, false if they were not in
|
||||
* the neighbor list.
|
||||
*/
|
||||
public boolean removeNeighbor (String neighborName);
|
||||
|
||||
/**
|
||||
* Implementations must provide an editable scene model that
|
||||
* represents the current state of this editable scene in response to
|
||||
* a call to this method. Whether they maintain an up to date scene
|
||||
* model all along or generate one at the time this method is called
|
||||
* is up to the implementation.
|
||||
*/
|
||||
public EditableSceneModel getSceneModel ();
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
//
|
||||
// $Id: EditableSceneImpl.java,v 1.7 2003/01/31 23:10:46 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.client.DisplaySceneImpl;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* A basic implementation of the {@link EditableScene} interface.
|
||||
*/
|
||||
public class EditableSceneImpl implements EditableScene
|
||||
{
|
||||
/**
|
||||
* Creates an instance that will create and use a blank scene model.
|
||||
*/
|
||||
public EditableSceneImpl ()
|
||||
{
|
||||
this(EditableSceneModel.blankSceneModel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and update it when changes are made.
|
||||
*/
|
||||
public EditableSceneImpl (EditableSceneModel model)
|
||||
{
|
||||
this(model, new DisplaySceneImpl(model.sceneModel, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that will obtain data from the supplied scene
|
||||
* model and update it when changes are made. It will delegate to the
|
||||
* supplied display scene instead of creating its own delegate.
|
||||
*/
|
||||
public EditableSceneImpl (
|
||||
EditableSceneModel model, DisplaySceneImpl delegate)
|
||||
{
|
||||
_model = model.sceneModel;
|
||||
_emodel = model;
|
||||
_delegate = delegate;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getId ()
|
||||
{
|
||||
return _delegate.getId();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public String getName ()
|
||||
{
|
||||
return _delegate.getName();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int getVersion ()
|
||||
{
|
||||
return _delegate.getVersion();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public int[] getNeighborIds ()
|
||||
{
|
||||
return _delegate.getNeighborIds();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public PlaceConfig getPlaceConfig ()
|
||||
{
|
||||
return _delegate.getPlaceConfig();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setId (int sceneId)
|
||||
{
|
||||
_model.sceneId = sceneId;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setName (String name)
|
||||
{
|
||||
_model.sceneName = name;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setVersion (int version)
|
||||
{
|
||||
_model.version = version;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void setNeighborIds (int[] neighborIds)
|
||||
{
|
||||
_model.neighborIds = neighborIds;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public ArrayList getNeighborNames ()
|
||||
{
|
||||
return _emodel.neighborNames;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public void addNeighbor (String neighborName)
|
||||
{
|
||||
if (!_emodel.neighborNames.contains(neighborName)) {
|
||||
_emodel.neighborNames.add(neighborName);
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public boolean removeNeighbor (String neighborName)
|
||||
{
|
||||
return _emodel.neighborNames.remove(neighborName);
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public EditableSceneModel getSceneModel ()
|
||||
{
|
||||
flushToModel();
|
||||
return _emodel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes should override this method and flush any editable
|
||||
* modifications to the scene model when this method is called.
|
||||
*/
|
||||
protected void flushToModel ()
|
||||
{
|
||||
}
|
||||
|
||||
/** A reference to our scene model. */
|
||||
protected SceneModel _model;
|
||||
|
||||
/** A reference to our editable scene model. */
|
||||
protected EditableSceneModel _emodel;
|
||||
|
||||
/** Our display scene delegate. */
|
||||
protected DisplaySceneImpl _delegate;
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
//
|
||||
// $Id: EditableSceneModel.java,v 1.4 2001/12/12 19:06:15 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* The editable scene model contains information above and beyond the
|
||||
* regular scene model that is necessary for editing and loading scenes.
|
||||
*/
|
||||
public class EditableSceneModel
|
||||
{
|
||||
/** The scene model that we extend. */
|
||||
public SceneModel sceneModel;
|
||||
|
||||
/** The human readable name of this scene's neighbors. */
|
||||
public ArrayList neighborNames;
|
||||
|
||||
/**
|
||||
* Generates a string representation of this scene model.
|
||||
*/
|
||||
public String toString ()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("[");
|
||||
delegatesToString(buf);
|
||||
toString(buf);
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Object clone ()
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
return cloneWithDelegate((SceneModel)sceneModel.clone());
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
protected Object cloneWithDelegate (SceneModel sceneModel)
|
||||
throws CloneNotSupportedException
|
||||
{
|
||||
EditableSceneModel esm = (EditableSceneModel)super.clone();
|
||||
esm.sceneModel = sceneModel;
|
||||
return esm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes override this to tack their <code>toString</code>
|
||||
* data on to the string buffer.
|
||||
*/
|
||||
protected void delegatesToString (StringBuffer buf)
|
||||
{
|
||||
buf.append(sceneModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Derived classes override this to tack their <code>toString</code>
|
||||
* data on to the string buffer.
|
||||
*/
|
||||
protected void toString (StringBuffer buf)
|
||||
{
|
||||
buf.append(", neighborNames=").
|
||||
append(StringUtil.toString(neighborNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a blank editable scene model.
|
||||
*/
|
||||
public static EditableSceneModel blankSceneModel ()
|
||||
{
|
||||
EditableSceneModel model = new EditableSceneModel();
|
||||
model.sceneModel = SceneModel.blankSceneModel();
|
||||
populateBlankSceneModel(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates a blank editable scene model with blank values.
|
||||
*/
|
||||
protected static void populateBlankSceneModel (EditableSceneModel model)
|
||||
{
|
||||
model.neighborNames = new ArrayList();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneParser.java,v 1.1 2001/12/05 03:38:09 mdb Exp $
|
||||
// $Id: SceneParser.java,v 1.2 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.xml;
|
||||
|
||||
@@ -9,8 +9,10 @@ import java.io.FileInputStream;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.apache.commons.digester.Digester;
|
||||
|
||||
import com.threerings.whirled.tools.EditableScene;
|
||||
import com.threerings.whirled.tools.EditableSceneImpl;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.tools.xml.NestableRuleSet;
|
||||
import com.threerings.whirled.data.AuxModel;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* A simple class for parsing an editable scene instance.
|
||||
@@ -19,40 +21,75 @@ public class SceneParser
|
||||
{
|
||||
/**
|
||||
* Constructs a scene parser that parses scenes with the specified XML
|
||||
* path prefix. See the {@link SceneRuleSet#SceneRuleSet}
|
||||
* documentation for more information.
|
||||
* path prefix.
|
||||
*/
|
||||
public SceneParser (String prefix)
|
||||
{
|
||||
// create and configure our digester
|
||||
_digester = new Digester();
|
||||
SceneRuleSet set = new SceneRuleSet();
|
||||
set.setPrefix(prefix);
|
||||
_digester.addRuleSet(set);
|
||||
_digester.addSetNext(prefix, "setScene", EditableScene.class.getName());
|
||||
|
||||
// create our scene rule set
|
||||
SceneRuleSet set = createSceneRuleSet();
|
||||
|
||||
// configure our top-level path prefix
|
||||
if (StringUtil.blank(prefix)) {
|
||||
_prefix = set.getOuterElement();
|
||||
} else {
|
||||
_prefix = prefix + "/" + set.getOuterElement();
|
||||
}
|
||||
|
||||
// add the scene rules
|
||||
set.addRuleInstances(_prefix, _digester);
|
||||
|
||||
// add a rule to grab the finished scene model
|
||||
_digester.addSetNext(_prefix, "setScene", SceneModel.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the XML file at the specified path into an editable scene
|
||||
* Creates the rule set used to parse our scene.
|
||||
*/
|
||||
protected SceneRuleSet createSceneRuleSet ()
|
||||
{
|
||||
return new SceneRuleSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link NestableRuleSet} for parsing auxiliary scene models.
|
||||
*/
|
||||
public void registerAuxRuleSet (NestableRuleSet set)
|
||||
{
|
||||
// add their outer element to the prefix
|
||||
String prefix = _prefix + "/" + set.getOuterElement();
|
||||
|
||||
// add the rules to generate the aux scene model
|
||||
set.addRuleInstances(prefix, _digester);
|
||||
|
||||
// and add a rule to grab it
|
||||
_digester.addSetNext(prefix, "addAuxModel", AuxModel.class.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the XML file at the specified path into a scene model
|
||||
* instance.
|
||||
*/
|
||||
public EditableScene parseScene (String path)
|
||||
public SceneModel parseScene (String path)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
_scene = null;
|
||||
_model = null;
|
||||
_digester.push(this);
|
||||
_digester.parse(new FileInputStream(path));
|
||||
return _scene;
|
||||
return _model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the parser once the scene is parsed.
|
||||
*/
|
||||
public void setScene (EditableScene scene)
|
||||
public void setScene (SceneModel model)
|
||||
{
|
||||
_scene = scene;
|
||||
_model = model;
|
||||
}
|
||||
|
||||
protected String _prefix;
|
||||
protected Digester _digester;
|
||||
protected EditableScene _scene;
|
||||
protected SceneModel _model;
|
||||
}
|
||||
|
||||
@@ -1,63 +1,43 @@
|
||||
//
|
||||
// $Id: SceneRuleSet.java,v 1.2 2001/12/05 03:38:09 mdb Exp $
|
||||
// $Id: SceneRuleSet.java,v 1.3 2003/02/12 07:23:31 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.xml;
|
||||
|
||||
import org.apache.commons.digester.Digester;
|
||||
import org.apache.commons.digester.RuleSetBase;
|
||||
|
||||
import com.threerings.whirled.tools.EditableScene;
|
||||
import com.threerings.whirled.tools.EditableSceneImpl;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.samskivert.xml.SetPropertyFieldsRule;
|
||||
|
||||
import com.threerings.tools.xml.NestableRuleSet;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* Used to parse an {@link EditableScene} from XML.
|
||||
* Used to parse a {@link SceneModel} from XML.
|
||||
*/
|
||||
public class SceneRuleSet extends RuleSetBase
|
||||
public class SceneRuleSet implements NestableRuleSet
|
||||
{
|
||||
/**
|
||||
* Configures this scene rule set to match scenes with the supplied
|
||||
* prefix. For example, passing <code>scene</code> will match the
|
||||
* scene in the following XML file:
|
||||
*
|
||||
* <pre>
|
||||
* <scene name="Scene Name" version="3">
|
||||
* <neighbor>North Scene</neighbor>
|
||||
* <neighbor>West Scene</neighbor>
|
||||
* <!-- ... -->
|
||||
* </scene>
|
||||
* </pre>
|
||||
*/
|
||||
public void setPrefix (String prefix)
|
||||
// documentation inherited from interface
|
||||
public String getOuterElement ()
|
||||
{
|
||||
_prefix = prefix;
|
||||
return SceneWriter.OUTER_ELEMENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the necessary rules to the digester to parse our miso scene
|
||||
* data.
|
||||
*/
|
||||
public void addRuleInstances (Digester digester)
|
||||
// documentation inherited from interface
|
||||
public void addRuleInstances (String prefix, Digester digester)
|
||||
{
|
||||
// this creates the appropriate instance when we encounter our tag
|
||||
digester.addObjectCreate(_prefix, getSceneClass().getName());
|
||||
digester.addObjectCreate(prefix, getSceneClass().getName());
|
||||
|
||||
// set up rules to parse and set our fields
|
||||
digester.addSetProperties(_prefix);
|
||||
digester.addCallMethod(_prefix + "/neighbor", "addNeighbor", 0);
|
||||
digester.addRule(prefix, new SetPropertyFieldsRule(digester));
|
||||
}
|
||||
|
||||
/**
|
||||
* This indicates the class (which should implement {@link
|
||||
* EditableScene}) to be instantiated during the parsing process.
|
||||
* This indicates the class (which should extend {@link SceneModel})
|
||||
* to be instantiated during the parsing process.
|
||||
*/
|
||||
protected Class getSceneClass ()
|
||||
{
|
||||
return EditableSceneImpl.class;
|
||||
return SceneModel.class;
|
||||
}
|
||||
|
||||
/** The prefix at which me match our scenes. */
|
||||
protected String _prefix = DEFAULT_SCENE_PREFIX;
|
||||
|
||||
/** The default prefix which matches <scene>. */
|
||||
protected static final String DEFAULT_SCENE_PREFIX = "scene";
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
//
|
||||
// $Id: SceneWriter.java,v 1.3 2003/01/30 19:16:50 mdb Exp $
|
||||
// $Id: SceneWriter.java,v 1.4 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.tools.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
@@ -13,78 +14,92 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
|
||||
import com.megginson.sax.DataWriter;
|
||||
import com.samskivert.util.StringUtil;
|
||||
import com.threerings.tools.xml.NestableWriter;
|
||||
|
||||
import com.threerings.whirled.tools.EditableScene;
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.data.AuxModel;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* Generates an XML representation of an {@link EditableScene}.
|
||||
* Generates an XML representation of an {@link SceneModel}.
|
||||
*/
|
||||
public class SceneWriter
|
||||
{
|
||||
/** The outer element used to enclose our scene definition. */
|
||||
public static final String OUTER_ELEMENT = "scene";
|
||||
|
||||
/**
|
||||
* Writes the data for the supplied {@link EditableScene} to the XML
|
||||
* writer supplied. The writer will already be configured with the
|
||||
* appropriate indentation level so that this writer can simply output
|
||||
* its elements and allow the calling code to determine where in the
|
||||
* greater scene description file the scene data should live.
|
||||
* Registers a writer for writing auxiliary scene models of the
|
||||
* supplied class.
|
||||
*/
|
||||
public void writeScene (EditableScene scene, DataWriter writer)
|
||||
throws SAXException
|
||||
public void registerAuxWriter (Class aclass, NestableWriter writer)
|
||||
{
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
addSceneAttributes(scene, attrs);
|
||||
writer.startElement("", sceneElementName(), "", attrs);
|
||||
writeSceneData(scene, writer);
|
||||
writer.endElement(sceneElementName());
|
||||
_auxers.put(aclass, writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the top-level element that we'll use when we
|
||||
* write out the scene (defaults to <code>scene</code>).
|
||||
* Writes the supplied scene out to the specified file.
|
||||
*/
|
||||
protected String sceneElementName ()
|
||||
{
|
||||
return "scene";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds attributes to the top-level element before it gets written.
|
||||
*/
|
||||
protected void addSceneAttributes (
|
||||
EditableScene scene, AttributesImpl attrs)
|
||||
{
|
||||
attrs.addAttribute("", "name", "", "", scene.getName());
|
||||
attrs.addAttribute("", "version", "", "",
|
||||
Integer.toString(scene.getVersion()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes just the scene data which is handy for derived classes which
|
||||
* may wish to add their own scene data to the scene output.
|
||||
*/
|
||||
protected void writeSceneData (EditableScene scene, DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
Iterator iter = scene.getNeighborNames().iterator();
|
||||
while (iter.hasNext()) {
|
||||
writer.dataElement("neighbor", (String)iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the supplied scene out to the specified file using the
|
||||
* supplied scene writer.
|
||||
*/
|
||||
public static void writeScene (File out, SceneWriter writer,
|
||||
EditableScene scene)
|
||||
public void writeScene (File out, SceneModel model)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
FileWriter fout = new FileWriter(out);
|
||||
DataWriter dout = new DataWriter(fout);
|
||||
dout.setIndentStep(2);
|
||||
dout.startDocument();
|
||||
writer.writeScene(scene, dout);
|
||||
writeSceneModel(model, dout);
|
||||
dout.endDocument();
|
||||
fout.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the data for the supplied {@link SceneModel} to the XML data
|
||||
* writer supplied. The writer should already be configured with the
|
||||
* appropriate indentation level so that this writer can simply output
|
||||
* its elements and allow the calling code to determine where in the
|
||||
* greater scene description file the scene data should live.
|
||||
*/
|
||||
public void writeSceneModel (SceneModel model, DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
addSceneAttributes(model, attrs);
|
||||
writer.startElement("", OUTER_ELEMENT, "", attrs);
|
||||
writeSceneData(model, writer);
|
||||
writer.endElement(OUTER_ELEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds attributes to the top-level element before it gets written.
|
||||
*/
|
||||
protected void addSceneAttributes (
|
||||
SceneModel model, AttributesImpl attrs)
|
||||
{
|
||||
attrs.addAttribute("", "name", "", "", model.name);
|
||||
attrs.addAttribute("", "version", "", "",
|
||||
Integer.toString(model.version));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes just the scene data which is handy for derived classes which
|
||||
* may wish to add their own scene data to the scene output.
|
||||
*/
|
||||
protected void writeSceneData (SceneModel model, DataWriter writer)
|
||||
throws SAXException
|
||||
{
|
||||
// write out our auxiliary scene models
|
||||
for (int ii = 0; ii < model.auxModels.length; ii++) {
|
||||
AuxModel amodel = model.auxModels[ii];
|
||||
NestableWriter awriter = (NestableWriter)
|
||||
_auxers.get(amodel.getClass());
|
||||
if (awriter != null) {
|
||||
awriter.write(amodel, writer);
|
||||
} else {
|
||||
Log.warning("No writer registered for auxiliary scene model " +
|
||||
"[mclass=" + amodel.getClass() + "].");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected HashMap _auxers = new HashMap();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// $Id: SceneFactory.java,v 1.1 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.util;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.Scene;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
|
||||
/**
|
||||
* This is used by the Whirled services to obtain a {@link Scene}
|
||||
* implementation given a scene model and associated data.
|
||||
*/
|
||||
public interface SceneFactory
|
||||
{
|
||||
/**
|
||||
* Creates a {@link Scene} implementation given the supplied scene
|
||||
* model and place config.
|
||||
*/
|
||||
public Scene createScene (SceneModel model, PlaceConfig config);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
//
|
||||
// $Id: UpdateList.java,v 1.1 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
|
||||
/**
|
||||
* A list specialized for storing {@link SceneUpdate} objects.
|
||||
*/
|
||||
public class UpdateList
|
||||
{
|
||||
public UpdateList ()
|
||||
{
|
||||
_updates = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an update to this list. The update must follow appropriately
|
||||
* the chain of updates established by the updates already in the list
|
||||
* (meaning it must operate on one version higher than the most recent
|
||||
* update already in the list).
|
||||
*/
|
||||
public void addUpdate (SceneUpdate update)
|
||||
{
|
||||
if (_minVersion == -1) {
|
||||
// this is our first update, so we initialize our min version
|
||||
_minVersion = update.getSceneVersion();
|
||||
|
||||
} else {
|
||||
int gotVersion = update.getSceneVersion();
|
||||
int expVersion = _minVersion + _updates.size();
|
||||
if (gotVersion > expVersion) {
|
||||
Log.warning("Update continuity broken, flushing list " +
|
||||
"[got=" + update + ", expect=" + expVersion +
|
||||
", ucount=" + _updates.size() + "].");
|
||||
// flush out our old updates and start anew from here
|
||||
_updates.clear();
|
||||
_minVersion = expVersion;
|
||||
|
||||
} else if (gotVersion < expVersion) {
|
||||
// we somehow got an update that's older than updates we
|
||||
// already have? wick wick wack
|
||||
String errmsg = "Invalid update version " +
|
||||
"[want=" + expVersion + ", got=" + update + "]";
|
||||
throw new IllegalArgumentException(errmsg);
|
||||
}
|
||||
}
|
||||
_updates.add(update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the updates that should be applied to a scene with
|
||||
* the specified version to bring it up to date. <code>null</code> is
|
||||
* returned if the scene's version is older than the oldest update in
|
||||
* our list, in which case it cannot be brought up to date by applying
|
||||
* updates from this list.
|
||||
*/
|
||||
public SceneUpdate[] getUpdates (int fromVersion)
|
||||
{
|
||||
if (fromVersion < _minVersion) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int offset = fromVersion - _minVersion;
|
||||
int ucount = _updates.size() - offset;
|
||||
SceneUpdate[] updates = new SceneUpdate[ucount];
|
||||
for (int ii = 0; ii < ucount; ii++) {
|
||||
updates[ii] = (SceneUpdate)_updates.get(ii+offset);
|
||||
}
|
||||
return updates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the supplied actual scene version is in accordance
|
||||
* with the updates contained in this list.
|
||||
*/
|
||||
public boolean validate (int sceneVersion)
|
||||
{
|
||||
return ((_minVersion == -1) || // we have no updates
|
||||
(_minVersion + _updates.size() == sceneVersion));
|
||||
}
|
||||
|
||||
protected ArrayList _updates;
|
||||
protected int _minVersion = -1;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ZoneDirector.java,v 1.13 2003/01/18 22:45:16 mdb Exp $
|
||||
// $Id: ZoneDirector.java,v 1.14 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.zone.client;
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.threerings.crowd.data.PlaceConfig;
|
||||
|
||||
import com.threerings.whirled.client.SceneDirector;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
import com.threerings.whirled.util.WhirledContext;
|
||||
|
||||
import com.threerings.whirled.zone.Log;
|
||||
@@ -158,19 +159,38 @@ public class ZoneDirector extends BasicDirector
|
||||
notifyObservers(summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a successful {@link ZoneService#moveTo}
|
||||
* request when our cached scene was out of date and the server
|
||||
* determined that we needed some updates.
|
||||
*/
|
||||
public void moveSucceededWithUpdates (
|
||||
int placeId, PlaceConfig config, ZoneSummary summary,
|
||||
SceneUpdate[] updates)
|
||||
{
|
||||
// keep track of the summary
|
||||
_summary = summary;
|
||||
|
||||
// pass the rest off to the standard scene transition code
|
||||
_scdir.moveSucceededWithUpdates(placeId, config, updates);
|
||||
|
||||
// and let the zone observers know what's up
|
||||
notifyObservers(summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a successful {@link ZoneService#moveTo}
|
||||
* request when our cached scene was out of date and the server
|
||||
* determined that we needed an updated copy.
|
||||
*/
|
||||
public void moveSucceededPlusUpdate (
|
||||
public void moveSucceededWithScene (
|
||||
int placeId, PlaceConfig config, ZoneSummary summary, SceneModel model)
|
||||
{
|
||||
// keep track of the summary
|
||||
_summary = summary;
|
||||
|
||||
// pass the rest off to the standard scene transition code
|
||||
_scdir.moveSucceededPlusUpdate(placeId, config, model);
|
||||
_scdir.moveSucceededWithScene(placeId, config, model);
|
||||
|
||||
// and let the zone observers know what's up
|
||||
notifyObservers(summary);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ZoneService.java,v 1.6 2002/08/14 19:07:58 mdb Exp $
|
||||
// $Id: ZoneService.java,v 1.7 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.zone.client;
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.threerings.presents.client.InvocationService;
|
||||
|
||||
import com.threerings.crowd.data.PlaceConfig;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
|
||||
import com.threerings.whirled.zone.data.ZoneSummary;
|
||||
|
||||
@@ -17,12 +18,17 @@ import com.threerings.whirled.zone.data.ZoneSummary;
|
||||
*/
|
||||
public interface ZoneService extends InvocationService
|
||||
{
|
||||
/** Used to deliver responses to {@link #moveTo} requests. */
|
||||
public static interface ZoneMoveListener extends InvocationListener
|
||||
{
|
||||
public void moveSucceeded (
|
||||
int placeId, PlaceConfig config, ZoneSummary summary);
|
||||
|
||||
public void moveSucceededPlusUpdate (
|
||||
public void moveSucceededWithUpdates (
|
||||
int placeId, PlaceConfig config, ZoneSummary summary,
|
||||
SceneUpdate[] updates);
|
||||
|
||||
public void moveSucceededWithScene (
|
||||
int placeId, PlaceConfig config, ZoneSummary summary,
|
||||
SceneModel model);
|
||||
}
|
||||
@@ -33,11 +39,11 @@ public interface ZoneService extends InvocationService
|
||||
*
|
||||
* @param zoneId the zone id to which we want to move.
|
||||
* @param sceneId the scene id to which we want to move.
|
||||
* @param sceneVers the version number of the scene object that we
|
||||
* have in our local repository.
|
||||
* @param version the version number of the scene object that we have
|
||||
* in our local repository.
|
||||
* @param listener the object that will receive the callback when the
|
||||
* request succeeds or fails.
|
||||
*/
|
||||
public void moveTo (Client client, int zoneId, int sceneId,
|
||||
int sceneVers, ZoneMoveListener listener);
|
||||
int version, ZoneMoveListener listener);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ZoneMarshaller.java,v 1.2 2002/08/20 19:38:16 mdb Exp $
|
||||
// $Id: ZoneMarshaller.java,v 1.3 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.zone.data;
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.threerings.presents.client.Client;
|
||||
import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.dobj.InvocationResponseEvent;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
import com.threerings.whirled.zone.client.ZoneService;
|
||||
import com.threerings.whirled.zone.client.ZoneService.ZoneMoveListener;
|
||||
import com.threerings.whirled.zone.data.ZoneSummary;
|
||||
@@ -18,10 +19,6 @@ import com.threerings.whirled.zone.data.ZoneSummary;
|
||||
* on the server. Also provides an implementation of the response listener
|
||||
* interfaces that marshall the response arguments and deliver them back
|
||||
* to the requesting client.
|
||||
*
|
||||
* <p> Generated from <code>
|
||||
* $Id: ZoneMarshaller.java,v 1.2 2002/08/20 19:38:16 mdb Exp $
|
||||
* </code>
|
||||
*/
|
||||
public class ZoneMarshaller extends InvocationMarshaller
|
||||
implements ZoneService
|
||||
@@ -42,15 +39,27 @@ public class ZoneMarshaller extends InvocationMarshaller
|
||||
new Object[] { new Integer(arg1), arg2, arg3 }));
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #moveSucceededPlusUpdate}
|
||||
/** The method id used to dispatch {@link #moveSucceededWithUpdates}
|
||||
* responses. */
|
||||
public static final int MOVE_SUCCEEDED_PLUS_UPDATE = 2;
|
||||
public static final int MOVE_SUCCEEDED_WITH_UPDATES = 2;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceededPlusUpdate (int arg1, PlaceConfig arg2, ZoneSummary arg3, SceneModel arg4)
|
||||
public void moveSucceededWithUpdates (int arg1, PlaceConfig arg2, ZoneSummary arg3, SceneUpdate[] arg4)
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, MOVE_SUCCEEDED_PLUS_UPDATE,
|
||||
callerOid, requestId, MOVE_SUCCEEDED_WITH_UPDATES,
|
||||
new Object[] { new Integer(arg1), arg2, arg3, arg4 }));
|
||||
}
|
||||
|
||||
/** The method id used to dispatch {@link #moveSucceededWithScene}
|
||||
* responses. */
|
||||
public static final int MOVE_SUCCEEDED_WITH_SCENE = 3;
|
||||
|
||||
// documentation inherited from interface
|
||||
public void moveSucceededWithScene (int arg1, PlaceConfig arg2, ZoneSummary arg3, SceneModel arg4)
|
||||
{
|
||||
omgr.postEvent(new InvocationResponseEvent(
|
||||
callerOid, requestId, MOVE_SUCCEEDED_WITH_SCENE,
|
||||
new Object[] { new Integer(arg1), arg2, arg3, arg4 }));
|
||||
}
|
||||
|
||||
@@ -63,8 +72,13 @@ public class ZoneMarshaller extends InvocationMarshaller
|
||||
((Integer)args[0]).intValue(), (PlaceConfig)args[1], (ZoneSummary)args[2]);
|
||||
return;
|
||||
|
||||
case MOVE_SUCCEEDED_PLUS_UPDATE:
|
||||
((ZoneMoveListener)listener).moveSucceededPlusUpdate(
|
||||
case MOVE_SUCCEEDED_WITH_UPDATES:
|
||||
((ZoneMoveListener)listener).moveSucceededWithUpdates(
|
||||
((Integer)args[0]).intValue(), (PlaceConfig)args[1], (ZoneSummary)args[2], (SceneUpdate[])args[3]);
|
||||
return;
|
||||
|
||||
case MOVE_SUCCEEDED_WITH_SCENE:
|
||||
((ZoneMoveListener)listener).moveSucceededWithScene(
|
||||
((Integer)args[0]).intValue(), (PlaceConfig)args[1], (ZoneSummary)args[2], (SceneModel)args[3]);
|
||||
return;
|
||||
|
||||
@@ -87,5 +101,5 @@ public class ZoneMarshaller extends InvocationMarshaller
|
||||
});
|
||||
}
|
||||
|
||||
// Class file generated on 12:33:05 08/20/02.
|
||||
// Generated on 15:03:19 02/08/03.
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ZoneDispatcher.java,v 1.2 2002/08/20 19:38:16 mdb Exp $
|
||||
// $Id: ZoneDispatcher.java,v 1.3 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.zone.server;
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.threerings.presents.data.InvocationMarshaller;
|
||||
import com.threerings.presents.server.InvocationDispatcher;
|
||||
import com.threerings.presents.server.InvocationException;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.data.SceneUpdate;
|
||||
import com.threerings.whirled.zone.client.ZoneService;
|
||||
import com.threerings.whirled.zone.client.ZoneService.ZoneMoveListener;
|
||||
import com.threerings.whirled.zone.data.ZoneMarshaller;
|
||||
@@ -17,10 +18,6 @@ import com.threerings.whirled.zone.data.ZoneSummary;
|
||||
|
||||
/**
|
||||
* Dispatches requests to the {@link ZoneProvider}.
|
||||
*
|
||||
* <p> Generated from <code>
|
||||
* $Id: ZoneDispatcher.java,v 1.2 2002/08/20 19:38:16 mdb Exp $
|
||||
* </code>
|
||||
*/
|
||||
public class ZoneDispatcher extends InvocationDispatcher
|
||||
{
|
||||
@@ -56,4 +53,6 @@ public class ZoneDispatcher extends InvocationDispatcher
|
||||
super.dispatchRequest(source, methodId, args);
|
||||
}
|
||||
}
|
||||
|
||||
// Generated on 15:03:19 02/08/03.
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ZoneProvider.java,v 1.13 2002/12/03 06:58:57 mdb Exp $
|
||||
// $Id: ZoneProvider.java,v 1.14 2003/02/12 07:23:32 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.zone.server;
|
||||
|
||||
@@ -161,10 +161,10 @@ public class ZoneProvider
|
||||
}
|
||||
|
||||
// check to see if they need a newer version of the scene data
|
||||
SceneModel model = scmgr.getSceneModel();
|
||||
SceneModel model = scmgr.getScene().getSceneModel();
|
||||
if (sceneVersion < model.version) {
|
||||
// then send the moveTo response
|
||||
listener.moveSucceededPlusUpdate(ploid, config, summary, model);
|
||||
listener.moveSucceededWithScene(ploid, config, summary, model);
|
||||
|
||||
} else {
|
||||
// then send the moveTo response
|
||||
|
||||
Reference in New Issue
Block a user