Phase one of the scene refactoring (which will set the stage for all
manner of happiness and joy). git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@615 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// $Id: DisplayScene.java,v 1.1 2001/11/12 20:56:55 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 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 ();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// $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);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// $Id: DisplaySceneImpl.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;
|
||||
|
||||
/**
|
||||
* 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 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: SceneCodes.java,v 1.2 2001/10/11 04:07:54 mdb Exp $
|
||||
// $Id: SceneCodes.java,v 1.3 2001/11/12 20:56:55 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
@@ -12,4 +12,11 @@ public interface SceneCodes extends LocationCodes
|
||||
{
|
||||
/** The module name for the scene services. */
|
||||
public static final String MODULE_NAME = "whirled!scene";
|
||||
|
||||
/** The response identifier for a successful moveTo request that
|
||||
* includes an updated scene model. This is mapped by the invocation
|
||||
* services to a call to {@link
|
||||
* SceneDirector#handleMoveSucceededPlusUpdate}. */
|
||||
public static final String MOVE_SUCCEEDED_PLUS_UPDATE_RESPONSE =
|
||||
"MoveSucceededPlusUpdate";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// $Id: SceneController.java,v 1.1 2001/11/12 20:56:55 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
import com.threerings.crowd.client.PlaceController;
|
||||
|
||||
/**
|
||||
* The base scene controller class. It is expected that users of the
|
||||
* Whirled services will extend this controller class when creating
|
||||
* specialized controllers for their scenes. Presently there are no basic
|
||||
* scene services provided by this controller, but its existence affords
|
||||
* the addition of such services should they become necessary in the
|
||||
* future.
|
||||
*/
|
||||
public abstract class SceneController extends PlaceController
|
||||
{
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: SceneDirector.java,v 1.6 2001/10/11 04:07:54 mdb Exp $
|
||||
// $Id: SceneDirector.java,v 1.7 2001/11/12 20:56:55 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client;
|
||||
|
||||
@@ -16,43 +16,50 @@ import com.threerings.crowd.data.PlaceObject;
|
||||
|
||||
import com.threerings.whirled.Log;
|
||||
import com.threerings.whirled.client.persist.SceneRepository;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.util.NoSuchSceneException;
|
||||
import com.threerings.whirled.data.Scene;
|
||||
import com.threerings.whirled.util.WhirledContext;
|
||||
|
||||
/**
|
||||
* The scene director is the client's interface to all things scene
|
||||
* related. It interfaces with the scene repository to ensure that scene
|
||||
* objects are available when the client enters a particular scene. It
|
||||
* handles moving from scene to scene (it extends and replaces the
|
||||
* location director in order to do this).
|
||||
* handles moving from scene to scene (it extends and replaces the {@link
|
||||
* LocationDirector} in order to do this).
|
||||
*
|
||||
* <p> Note that when the scene director is in use instead of the location
|
||||
* director, scene ids instead of place oids will be supplied to {@link
|
||||
* com.threerings.crowd.client.LocationObserver#locationMayChange}
|
||||
* and {@link
|
||||
* com.threerings.crowd.client.LocationObserver#locationChangeFailed}.
|
||||
* LocationObserver#locationMayChange} and {@link
|
||||
* LocationObserver#locationChangeFailed}.
|
||||
*/
|
||||
public class SceneDirector
|
||||
extends LocationDirector implements SceneCodes
|
||||
{
|
||||
/**
|
||||
* Creates a new scene director with the specified context.
|
||||
*
|
||||
* @param ctx the active client context.
|
||||
* @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.
|
||||
*/
|
||||
public SceneDirector (WhirledContext ctx, SceneRepository screp)
|
||||
public SceneDirector (WhirledContext ctx, SceneRepository screp,
|
||||
DisplaySceneFactory dsfact)
|
||||
{
|
||||
super(ctx);
|
||||
|
||||
// we'll need these for later
|
||||
_ctx = ctx;
|
||||
_screp = screp;
|
||||
_dsfact = dsfact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scene object associated with the scene we currently
|
||||
* occupy or null if we currently occupy no scene.
|
||||
* Returns the dispaly scene object associated with the scene we
|
||||
* currently occupy or null if we currently occupy no scene.
|
||||
*/
|
||||
public Scene getScene ()
|
||||
public DisplayScene getScene ()
|
||||
{
|
||||
return _scene;
|
||||
}
|
||||
@@ -86,10 +93,10 @@ public class SceneDirector
|
||||
// load up the pending scene so that we can communicate it's most
|
||||
// recent version to the server
|
||||
int sceneVers = 0;
|
||||
_pendingScene = loadScene(sceneId);
|
||||
_pendingModel = loadSceneModel(sceneId);
|
||||
// if we were unable to load it, assume a previous version of zero
|
||||
if (_pendingScene != null) {
|
||||
sceneVers = _pendingScene.getVersion();
|
||||
if (_pendingModel != null) {
|
||||
sceneVers = _pendingModel.version;
|
||||
}
|
||||
|
||||
// make a note of our pending scene id
|
||||
@@ -113,22 +120,54 @@ public class SceneDirector
|
||||
// parallelize and go ahead and load up the new scene now rather
|
||||
// than wait until subscription to our place object succeeds
|
||||
|
||||
// release the old scene
|
||||
releaseScene(_scene);
|
||||
|
||||
// update our scene id tracking fields
|
||||
// keep track of our previous scene info
|
||||
_previousSceneId = _sceneId;
|
||||
|
||||
// clear out the old info
|
||||
clearScene();
|
||||
|
||||
// make the pending scene the active scene
|
||||
_sceneId = _pendingSceneId;
|
||||
_pendingSceneId = -1;
|
||||
|
||||
// and load the new scene
|
||||
_scene = loadScene(_sceneId);
|
||||
// load the new scene model
|
||||
_model = loadSceneModel(_sceneId);
|
||||
|
||||
// complain if we didn't find a scene
|
||||
if (_scene == null) {
|
||||
if (_model == null) {
|
||||
Log.warning("Aiya! Unable to load scene [sid=" + _sceneId +
|
||||
", plid=" + placeId + "].");
|
||||
}
|
||||
|
||||
// and finally create a display scene instance with the model and
|
||||
// the place config
|
||||
_scene = _dsfact.createScene(_model, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called in response to a successful <code>moveTo</code> request when
|
||||
* our cached scene was out of date and the server determined that we
|
||||
* needed an updated copy.
|
||||
*/
|
||||
public void handleMoveSucceededPlusUpdate (
|
||||
int invid, int placeId, PlaceConfig config, SceneModel model)
|
||||
{
|
||||
// update the model in the repository
|
||||
try {
|
||||
_screp.updateSceneModel(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.logStackTrace(ioe);
|
||||
}
|
||||
|
||||
// update our scene cache
|
||||
_scache.put(model.sceneId, model);
|
||||
|
||||
// and pass through to the normal move succeeded handler
|
||||
handleMoveSucceeded(invid, placeId, config);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,13 +183,17 @@ public class SceneDirector
|
||||
notifyFailure(sceneId, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when something breaks down in the process of performing a
|
||||
* <code>moveTo</code> request.
|
||||
*/
|
||||
protected void recoverFailedMove (int placeId)
|
||||
{
|
||||
// clear out our now bogus scene tracking info
|
||||
// we'll need this momentarily
|
||||
int sceneId = _sceneId;
|
||||
_sceneId = -1;
|
||||
releaseScene(_scene);
|
||||
_scene = null;
|
||||
|
||||
// clear out our now bogus scene tracking info
|
||||
clearScene();
|
||||
|
||||
// if we were previously somewhere (and that somewhere isn't where
|
||||
// we just tried to go), try going back to that happy place
|
||||
@@ -159,20 +202,37 @@ public class SceneDirector
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears out our current scene information and releases the scene
|
||||
* model for the loaded scene back to the cache.
|
||||
*/
|
||||
protected void clearScene ()
|
||||
{
|
||||
// clear out our scene id info
|
||||
_sceneId = -1;
|
||||
|
||||
// release the old scene model
|
||||
releaseSceneModel(_model);
|
||||
|
||||
// clear out our references
|
||||
_model = null;
|
||||
_scene = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a scene from the repository. If the scene is cached, it will
|
||||
* be returned from the cache instead.
|
||||
*/
|
||||
protected Scene loadScene (int sceneId)
|
||||
protected SceneModel loadSceneModel (int sceneId)
|
||||
{
|
||||
// first look in the cache
|
||||
Scene scene = (Scene)_scache.get(sceneId);
|
||||
// first look in the model cache
|
||||
SceneModel model = (SceneModel)_scache.get(sceneId);
|
||||
|
||||
// load from the repository if it's not cached
|
||||
if (scene == null) {
|
||||
if (model == null) {
|
||||
try {
|
||||
scene = _screp.loadScene(sceneId);
|
||||
_scache.put(sceneId, scene);
|
||||
model = _screp.loadSceneModel(sceneId);
|
||||
_scache.put(sceneId, model);
|
||||
|
||||
} catch (NoSuchSceneException nsse) {
|
||||
// nothing special here, just fall through and return null
|
||||
@@ -184,34 +244,46 @@ public class SceneDirector
|
||||
}
|
||||
}
|
||||
|
||||
return scene;
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads a scene that was previously loaded via {@link #loadScene}.
|
||||
* The scene will probably continue to live in the cache for a while
|
||||
* in case we quickly return to it.
|
||||
* Unloads a scene model that was previously loaded via {@link
|
||||
* #loadSceneModel}. The model will probably continue to live in the
|
||||
* cache for a while in case we quickly return to it.
|
||||
*/
|
||||
protected void releaseScene (Scene scene)
|
||||
protected void releaseSceneModel (SceneModel model)
|
||||
{
|
||||
// we're cool if we're called with null
|
||||
if (scene == null) {
|
||||
if (model == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** Access to general client services. */
|
||||
protected WhirledContext _ctx;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** A cache of scene model information. */
|
||||
protected HashIntMap _scache = new HashIntMap();
|
||||
|
||||
/** The scene object of the scene we currently occupy. */
|
||||
protected Scene _scene;
|
||||
/** The display scene object for the scene we currently occupy. */
|
||||
protected DisplayScene _scene;
|
||||
|
||||
/** The scene model for the scene we currently occupy. */
|
||||
protected SceneModel _model;
|
||||
|
||||
/** The id of the scene we currently occupy. */
|
||||
protected int _sceneId = -1;
|
||||
|
||||
/** Our most recent copy of the scene we're about to enter. */
|
||||
protected Scene _pendingScene;
|
||||
/** Our most recent copy of the scene model for the scene we're about
|
||||
* to enter. */
|
||||
protected SceneModel _pendingModel;
|
||||
|
||||
/**
|
||||
* The id of the scene for which we have an outstanding moveTo
|
||||
|
||||
@@ -1,42 +1,43 @@
|
||||
//
|
||||
// $Id: SceneRepository.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||
// $Id: SceneRepository.java,v 1.3 2001/11/12 20:56:55 mdb Exp $
|
||||
|
||||
package com.threerings.whirled.client.persist;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.threerings.whirled.data.Scene;
|
||||
import com.threerings.whirled.data.SceneModel;
|
||||
import com.threerings.whirled.util.NoSuchSceneException;
|
||||
|
||||
/**
|
||||
* The scene repository provides access to a persistent repository of
|
||||
* scene information. The scenes in the repository can be updated with
|
||||
* individual scenes fetched from the server as well as with new scene
|
||||
* 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.
|
||||
*
|
||||
* @see com.threerings.whirled.data.Scene
|
||||
* @see SceneModel
|
||||
*/
|
||||
public interface SceneRepository
|
||||
{
|
||||
/**
|
||||
* Fetches the scene with the specified scene id.
|
||||
* Fetches the mode for the scene with the specified scene id.
|
||||
*
|
||||
* @exception IOException thrown if an error occurs attempting to load
|
||||
* a scene.
|
||||
* the scene data.
|
||||
* @exception NoSuchSceneException thrown if no scene exists with the
|
||||
* specified scene id.
|
||||
*/
|
||||
public Scene loadScene (int sceneId)
|
||||
public SceneModel loadSceneModel (int sceneId)
|
||||
throws IOException, NoSuchSceneException;
|
||||
|
||||
/**
|
||||
* Updates the specified scene in the repository with the information
|
||||
* provided in the scene object.
|
||||
* 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.
|
||||
*
|
||||
* @exception IOException thrown if an error occurs attempting to
|
||||
* update the scene.
|
||||
* update the scene data.
|
||||
*/
|
||||
public void updateScene (Scene scene)
|
||||
public void updateSceneModel (SceneModel model)
|
||||
throws IOException;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user