A whirlwind of whirled updates. Moving from scene to scene seems to mostly
work now. Scene activation is implemented. Some tests are written. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@242 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -1,18 +1,9 @@
|
|||||||
Whirled Design -*- mode: outline -*-
|
Whirled Design -*- mode: outline -*-
|
||||||
|
|
||||||
* Notes
|
* Notes
|
||||||
Scenes map to places.
|
|
||||||
|
|
||||||
Scene manager extends place manager, handles scene related stuff.
|
|
||||||
|
|
||||||
Scene manager registers a timer when it becomes empty and flushes itself
|
Scene manager registers a timer when it becomes empty and flushes itself
|
||||||
from memory after timeout period.
|
from memory after timeout period.
|
||||||
|
|
||||||
Location manager is used to navigate between scenes on the client;
|
|
||||||
location services will need extensions to support delivering scene version
|
|
||||||
with moveTo request and serialized scene data with moveTo response
|
|
||||||
(desirable to avoid extra server round-trips).
|
|
||||||
|
|
||||||
Client should avoid unsubscribing from scene objects straight away so that
|
Client should avoid unsubscribing from scene objects straight away so that
|
||||||
it can avoid resubscribing if they bounce back and forth between scenes.
|
it can avoid resubscribing if they bounce back and forth between scenes.
|
||||||
|
|
||||||
@@ -20,6 +11,10 @@ We'll want the scenes to adhere to some sort of hierarchy so that we can
|
|||||||
associate properties files with classes of scenes which will be used to
|
associate properties files with classes of scenes which will be used to
|
||||||
configure the scene managers when they are initialized.
|
configure the scene managers when they are initialized.
|
||||||
|
|
||||||
|
Add code to deal with receiving updated scenes from the server.
|
||||||
|
|
||||||
|
Add code to flush scenes from the client scene manager cache.
|
||||||
|
|
||||||
* Overview
|
* Overview
|
||||||
Whirled builds on top of the Cocktail platform and provides a framework
|
Whirled builds on top of the Cocktail platform and provides a framework
|
||||||
for building a virtual world made up of a node network of individual
|
for building a virtual world made up of a node network of individual
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
# $Id: server.properties,v 1.1 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
#
|
||||||
|
# Configuration for the Whirled server
|
||||||
|
|
||||||
|
# These invocation service providers will be registered with the
|
||||||
|
# invocation manager during the server init process
|
||||||
|
providers = \
|
||||||
|
whirled!scene = com.threerings.whirled.server.SceneProvider
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
//
|
||||||
|
// $Id: SceneDirector.java,v 1.1 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.whirled.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.cher.dobj.DObject;
|
||||||
|
import com.threerings.cocktail.cher.dobj.ObjectAccessException;
|
||||||
|
import com.threerings.cocktail.cher.util.IntMap;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.party.client.LocationManager;
|
||||||
|
import com.threerings.cocktail.party.client.LocationObserver;
|
||||||
|
import com.threerings.cocktail.party.data.PlaceObject;
|
||||||
|
|
||||||
|
import com.threerings.whirled.Log;
|
||||||
|
import com.threerings.whirled.client.persist.SceneRepository;
|
||||||
|
import com.threerings.whirled.util.NoSuchSceneException;
|
||||||
|
import com.threerings.whirled.data.Scene;
|
||||||
|
import com.threerings.whirled.util.WhirledContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scene manager 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 manager in order to do this).
|
||||||
|
*
|
||||||
|
* <p> Note that when the scene manager is in use instead of the location
|
||||||
|
* manager, scene ids instead of place oids will be supplied to {@link
|
||||||
|
* com.threerings.cocktail.party.client.LocationObserver#locationMayChange}
|
||||||
|
* and {@link
|
||||||
|
* com.threerings.cocktail.party.client.LocationObserver#locationChangeFailed}.
|
||||||
|
*/
|
||||||
|
public class SceneManager extends LocationManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new scene manager with the specified context.
|
||||||
|
*/
|
||||||
|
public SceneManager (WhirledContext ctx, SceneRepository screp)
|
||||||
|
{
|
||||||
|
super(ctx);
|
||||||
|
|
||||||
|
// we'll need these for later
|
||||||
|
_ctx = ctx;
|
||||||
|
_screp = screp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the scene object associated with the scene we currently
|
||||||
|
* occupy or null if we currently occupy no scene.
|
||||||
|
*/
|
||||||
|
public Scene getScene ()
|
||||||
|
{
|
||||||
|
return _scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that this client move the specified scene. A request will
|
||||||
|
* be made and when the response is received, the location observers
|
||||||
|
* will be notified of success or failure.
|
||||||
|
*/
|
||||||
|
public void moveTo (int sceneId)
|
||||||
|
{
|
||||||
|
// first check to see if our observers are happy with this move
|
||||||
|
// request
|
||||||
|
if (!mayMoveTo(sceneId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// complain if we're over-writing a pending request
|
||||||
|
if (_pendingSceneId != -1) {
|
||||||
|
Log.warning("We appear to have a moveTo request outstanding " +
|
||||||
|
"[psid=" + _pendingSceneId +
|
||||||
|
", nsid=" + sceneId + "].");
|
||||||
|
// but we're going to fall through and do it anyway because
|
||||||
|
// refusing to switch scenes at this point will inevitably
|
||||||
|
// result in some strange bug causing a move request to be
|
||||||
|
// dropped by the server and the client that did it to be
|
||||||
|
// totally hosed because they can no longer move to new scenes
|
||||||
|
// because they still have an outstanding request
|
||||||
|
}
|
||||||
|
|
||||||
|
// load up the pending scene so that we can communicate it's most
|
||||||
|
// recent version to the server
|
||||||
|
int sceneVers = 0;
|
||||||
|
_pendingScene = loadScene(sceneId);
|
||||||
|
// if we were unable to load it, assume a previous version of zero
|
||||||
|
if (_pendingScene != null) {
|
||||||
|
sceneVers = _pendingScene.getVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a note of our pending scene id
|
||||||
|
_pendingSceneId = sceneId;
|
||||||
|
|
||||||
|
// issue a moveTo request
|
||||||
|
SceneService.moveTo(_ctx.getClient(), sceneId, sceneVers, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in response to a successful <code>moveTo</code> request.
|
||||||
|
*/
|
||||||
|
public void handleMoveSucceeded (int invid, int placeId)
|
||||||
|
{
|
||||||
|
// our move request was successful, deal with subscribing to our
|
||||||
|
// new place object
|
||||||
|
didMoveTo(placeId);
|
||||||
|
|
||||||
|
// since we're committed to moving to the new scene, we'll
|
||||||
|
// 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
|
||||||
|
_previousSceneId = _sceneId;
|
||||||
|
_sceneId = _pendingSceneId;
|
||||||
|
_pendingSceneId = -1;
|
||||||
|
|
||||||
|
// and load the new scene
|
||||||
|
_scene = loadScene(_sceneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in response to a failed <code>moveTo</code> request.
|
||||||
|
*/
|
||||||
|
public void handleMoveFailed (int invid, String reason)
|
||||||
|
{
|
||||||
|
// clear out our pending request oid
|
||||||
|
int sceneId = _pendingSceneId;
|
||||||
|
_pendingSceneId = -1;
|
||||||
|
|
||||||
|
// let our observers know that something has gone horribly awry
|
||||||
|
notifyFailure(sceneId, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void recoverFailedMove (int placeId)
|
||||||
|
{
|
||||||
|
// clear out our now bogus scene tracking info
|
||||||
|
int sceneId = _sceneId;
|
||||||
|
_sceneId = -1;
|
||||||
|
releaseScene(_scene);
|
||||||
|
_scene = null;
|
||||||
|
|
||||||
|
// if we were previously somewhere (and that somewhere isn't where
|
||||||
|
// we just tried to go), try going back to that happy place
|
||||||
|
if (_previousSceneId != -1 && _previousSceneId != sceneId) {
|
||||||
|
moveTo(_previousSceneId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a scene from the repository. If the scene is cached, it will
|
||||||
|
* be returned from the cache instead.
|
||||||
|
*/
|
||||||
|
protected Scene loadScene (int sceneId)
|
||||||
|
{
|
||||||
|
// first look in the cache
|
||||||
|
Scene scene = (Scene)_scache.get(sceneId);
|
||||||
|
|
||||||
|
// load from the repository if it's not cached
|
||||||
|
if (scene == null) {
|
||||||
|
try {
|
||||||
|
scene = _screp.loadScene(sceneId);
|
||||||
|
_scache.put(sceneId, scene);
|
||||||
|
|
||||||
|
} catch (NoSuchSceneException nsse) {
|
||||||
|
// nothing special here, just fall through and return null
|
||||||
|
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// complain first, then return null
|
||||||
|
Log.warning("Error loading scene [scid=" + sceneId +
|
||||||
|
", error=" + ioe + "].");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
protected void releaseScene (Scene scene)
|
||||||
|
{
|
||||||
|
// we're cool if we're called with null
|
||||||
|
if (scene == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected WhirledContext _ctx;
|
||||||
|
protected SceneRepository _screp;
|
||||||
|
protected IntMap _scache = new IntMap();
|
||||||
|
|
||||||
|
/** The scene object of the scene we currently occupy. */
|
||||||
|
protected Scene _scene;
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the scene for which we have an outstanding moveTo
|
||||||
|
* request, or -1 if we have no outstanding request.
|
||||||
|
*/
|
||||||
|
protected int _pendingSceneId = -1;
|
||||||
|
|
||||||
|
/** The id of the scene we previously occupied. */
|
||||||
|
protected int _previousSceneId = -1;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SceneService.java,v 1.1 2001/08/11 04:09:50 mdb Exp $
|
// $Id: SceneService.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.whirled.client;
|
package com.threerings.whirled.client;
|
||||||
|
|
||||||
@@ -10,10 +10,29 @@ import com.threerings.whirled.Log;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The scene service class provides the client interface to the scene
|
* The scene service class provides the client interface to the scene
|
||||||
* related invocation services.
|
* related invocation services (e.g. moving from scene to scene).
|
||||||
*/
|
*/
|
||||||
public class SceneService
|
public class SceneService
|
||||||
{
|
{
|
||||||
/** The module name for the scene services. */
|
/** The module name for the scene services. */
|
||||||
public static final String MODULE = "whirled!scene";
|
public static final String MODULE = "whirled!scene";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests that that this client's body be moved to the specified
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public static void moveTo (Client client, int sceneId,
|
||||||
|
int sceneVers, SceneManager rsptarget)
|
||||||
|
{
|
||||||
|
InvocationManager invmgr = client.getInvocationManager();
|
||||||
|
Object[] args = new Object[] {
|
||||||
|
new Integer(sceneId), new Integer(sceneVers) };
|
||||||
|
invmgr.invoke(MODULE, "MoveTo", args, rsptarget);
|
||||||
|
Log.info("Sent moveTo request [scene=" + sceneId +
|
||||||
|
", version=" + sceneVers + "].");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SceneRepository.java,v 1.1 2001/08/11 04:09:50 mdb Exp $
|
// $Id: SceneRepository.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.whirled.client.persist;
|
package com.threerings.whirled.client.persist;
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ import com.threerings.whirled.util.NoSuchSceneException;
|
|||||||
* bundles that are periodically distributed to bring all clients into
|
* bundles that are periodically distributed to bring all clients into
|
||||||
* sync with the latest snapshot of the scene database.
|
* sync with the latest snapshot of the scene database.
|
||||||
*
|
*
|
||||||
* @see com.threerings.whirled.client.Scene
|
* @see com.threerings.whirled.data.Scene
|
||||||
*/
|
*/
|
||||||
public interface SceneRepository
|
public interface SceneRepository
|
||||||
{
|
{
|
||||||
@@ -27,6 +27,16 @@ public interface SceneRepository
|
|||||||
* @exception NoSuchSceneException thrown if no scene exists with the
|
* @exception NoSuchSceneException thrown if no scene exists with the
|
||||||
* specified scene id.
|
* specified scene id.
|
||||||
*/
|
*/
|
||||||
public Scene getScene (int sceneid)
|
public Scene loadScene (int sceneId)
|
||||||
throws IOException, NoSuchSceneException;
|
throws IOException, NoSuchSceneException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the specified scene in the repository with the information
|
||||||
|
* provided in the scene object.
|
||||||
|
*
|
||||||
|
* @exception IOException thrown if an error occurs attempting to
|
||||||
|
* update the scene.
|
||||||
|
*/
|
||||||
|
public void updateScene (Scene scene)
|
||||||
|
throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// $Id: DummyScene.java,v 1.1 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.whirled.client.test;
|
||||||
|
|
||||||
|
import com.threerings.whirled.data.Scene;
|
||||||
|
|
||||||
|
public class DummyScene implements Scene
|
||||||
|
{
|
||||||
|
public DummyScene (int sceneId)
|
||||||
|
{
|
||||||
|
_sceneId = sceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId ()
|
||||||
|
{
|
||||||
|
return _sceneId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getExitIds ()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int _sceneId;
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SceneRegistry.java,v 1.1 2001/08/11 04:09:50 mdb Exp $
|
// $Id: SceneRegistry.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.whirled.server;
|
package com.threerings.whirled.server;
|
||||||
|
|
||||||
@@ -44,6 +44,7 @@ public class SceneRegistry
|
|||||||
|
|
||||||
// we'll use this to do database stuff
|
// we'll use this to do database stuff
|
||||||
_invoker = new Invoker();
|
_invoker = new Invoker();
|
||||||
|
_invoker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,6 +92,8 @@ public class SceneRegistry
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.info("Resolving scene [id=" + sceneId + "].");
|
||||||
|
|
||||||
// otherwise we've got to resolve the scene and call them back
|
// otherwise we've got to resolve the scene and call them back
|
||||||
// later; we can manipulate the penders table with impunity here
|
// later; we can manipulate the penders table with impunity here
|
||||||
// because we only do so on the dobjmgr thread
|
// because we only do so on the dobjmgr thread
|
||||||
@@ -113,6 +116,8 @@ public class SceneRegistry
|
|||||||
// keywords...
|
// keywords...
|
||||||
final int fsceneId = sceneId;
|
final int fsceneId = sceneId;
|
||||||
|
|
||||||
|
Log.info("Invoking scene repository [id=" + sceneId + "].");
|
||||||
|
|
||||||
// then we queue up an execution unit that'll load the scene
|
// then we queue up an execution unit that'll load the scene
|
||||||
// and initialize it and all that
|
// and initialize it and all that
|
||||||
_invoker.postUnit(new Invoker.Unit() {
|
_invoker.postUnit(new Invoker.Unit() {
|
||||||
@@ -120,7 +125,7 @@ public class SceneRegistry
|
|||||||
public boolean invoke ()
|
public boolean invoke ()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
_scene = _screp.getScene(fsceneId);
|
_scene = _screp.loadScene(fsceneId);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
_cause = e;
|
_cause = e;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: WhirledServer.java,v 1.1 2001/08/11 04:09:50 mdb Exp $
|
// $Id: WhirledServer.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.whirled.server;
|
package com.threerings.whirled.server;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ import com.threerings.cocktail.party.server.PartyServer;
|
|||||||
|
|
||||||
import com.threerings.whirled.Log;
|
import com.threerings.whirled.Log;
|
||||||
import com.threerings.whirled.server.persist.SceneRepository;
|
import com.threerings.whirled.server.persist.SceneRepository;
|
||||||
import com.threerings.whirled.server.persist.DummySceneRepository;
|
import com.threerings.whirled.server.test.DummySceneRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The whirled server extends the party server and provides access to
|
* The whirled server extends the party server and provides access to
|
||||||
@@ -75,7 +75,7 @@ public class WhirledServer extends PartyServer
|
|||||||
protected final static String PROVIDERS_KEY = CONFIG_KEY + ".providers";
|
protected final static String PROVIDERS_KEY = CONFIG_KEY + ".providers";
|
||||||
|
|
||||||
// scene repository related configuration info
|
// scene repository related configuration info
|
||||||
protected final static String SCENEREP_KEY = "scene_rep";
|
protected final static String SCENEREP_KEY = CONFIG_KEY + ".scene_rep";
|
||||||
protected final static String DEF_SCENEREP =
|
protected final static String DEF_SCENEREP =
|
||||||
DummySceneRepository.class.getName();
|
DummySceneRepository.class.getName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
//
|
//
|
||||||
// $Id: DummySceneRepository.java,v 1.1 2001/08/11 04:09:50 mdb Exp $
|
// $Id: DummySceneRepository.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.whirled.server.persist;
|
package com.threerings.whirled.server.test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.threerings.whirled.Log;
|
||||||
import com.threerings.whirled.data.Scene;
|
import com.threerings.whirled.data.Scene;
|
||||||
|
import com.threerings.whirled.server.persist.SceneRepository;
|
||||||
import com.threerings.whirled.util.NoSuchSceneException;
|
import com.threerings.whirled.util.NoSuchSceneException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,10 +18,11 @@ import com.threerings.whirled.util.NoSuchSceneException;
|
|||||||
public class DummySceneRepository implements SceneRepository
|
public class DummySceneRepository implements SceneRepository
|
||||||
{
|
{
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
public Scene getScene (int sceneid)
|
public Scene loadScene (int sceneId)
|
||||||
throws IOException, NoSuchSceneException
|
throws IOException, NoSuchSceneException
|
||||||
{
|
{
|
||||||
return null;
|
Log.info("Creating dummy scene [id=" + sceneId + "].");
|
||||||
|
return new DummyScene(sceneId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited
|
// documentation inherited
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// $Id: SceneRepository.java,v 1.1 2001/08/11 04:09:50 mdb Exp $
|
// $Id: SceneRepository.java,v 1.2 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
package com.threerings.whirled.server.persist;
|
package com.threerings.whirled.server.persist;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ public interface SceneRepository
|
|||||||
* @exception NoSuchSceneException thrown if no scene exists with the
|
* @exception NoSuchSceneException thrown if no scene exists with the
|
||||||
* specified scene id.
|
* specified scene id.
|
||||||
*/
|
*/
|
||||||
public Scene getScene (int sceneid)
|
public Scene loadScene (int sceneId)
|
||||||
throws IOException, NoSuchSceneException;
|
throws IOException, NoSuchSceneException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// $Id: WhirledContext.java,v 1.1 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.whirled.util;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.party.util.PartyContext;
|
||||||
|
import com.threerings.whirled.client.SceneManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The whirled context provides access to the various managers, etc. that
|
||||||
|
* are needed by the whirled client code.
|
||||||
|
*/
|
||||||
|
public interface WhirledContext extends PartyContext
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a reference to the scene manager.
|
||||||
|
*/
|
||||||
|
public SceneManager getSceneManager ();
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// $Id: DummyClientSceneRepository.java,v 1.1 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.whirled.client.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.threerings.whirled.Log;
|
||||||
|
import com.threerings.whirled.client.persist.SceneRepository;
|
||||||
|
import com.threerings.whirled.data.Scene;
|
||||||
|
import com.threerings.whirled.util.NoSuchSceneException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dummy scene repository just pretends to load and store scenes, but
|
||||||
|
* in fact it just creates new blank scenes when requested to load a scene
|
||||||
|
* and does nothing when requested to save one.
|
||||||
|
*/
|
||||||
|
public class DummySceneRepository implements SceneRepository
|
||||||
|
{
|
||||||
|
// documentation inherited
|
||||||
|
public Scene loadScene (int sceneId)
|
||||||
|
throws IOException, NoSuchSceneException
|
||||||
|
{
|
||||||
|
Log.info("Creating dummy scene [id=" + sceneId + "].");
|
||||||
|
return new DummyScene(sceneId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited
|
||||||
|
public void updateScene (Scene scene)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// nothing doing
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
//
|
||||||
|
// $Id: TestClient.java,v 1.1 2001/08/14 06:51:07 mdb Exp $
|
||||||
|
|
||||||
|
package com.threerings.whirled.client.test;
|
||||||
|
|
||||||
|
import com.samskivert.util.Config;
|
||||||
|
import com.samskivert.util.Queue;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.cher.client.*;
|
||||||
|
import com.threerings.cocktail.cher.dobj.DObjectManager;
|
||||||
|
import com.threerings.cocktail.cher.net.*;
|
||||||
|
|
||||||
|
import com.threerings.cocktail.party.Log;
|
||||||
|
import com.threerings.cocktail.party.client.LocationManager;
|
||||||
|
import com.threerings.cocktail.party.client.LocationObserver;
|
||||||
|
import com.threerings.cocktail.party.data.PlaceObject;
|
||||||
|
|
||||||
|
import com.threerings.whirled.client.SceneManager;
|
||||||
|
import com.threerings.whirled.client.persist.SceneRepository;
|
||||||
|
import com.threerings.whirled.util.WhirledContext;
|
||||||
|
|
||||||
|
public class TestClient
|
||||||
|
implements Client.Invoker, ClientObserver, LocationObserver
|
||||||
|
{
|
||||||
|
public TestClient (Credentials creds)
|
||||||
|
{
|
||||||
|
// create our context
|
||||||
|
_ctx = new WhirledContextImpl();
|
||||||
|
|
||||||
|
// create the handles for our various services
|
||||||
|
_config = new Config();
|
||||||
|
_client = new Client(creds, this);
|
||||||
|
_screp = new DummySceneRepository();
|
||||||
|
_scmgr = new SceneManager(_ctx, _screp);
|
||||||
|
|
||||||
|
// we want to know about logon/logoff
|
||||||
|
_client.addObserver(this);
|
||||||
|
|
||||||
|
// we want to know about location changes
|
||||||
|
_scmgr.addLocationObserver(this);
|
||||||
|
|
||||||
|
// for test purposes, hardcode the server info
|
||||||
|
_client.setServer("localhost", 4007);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run ()
|
||||||
|
{
|
||||||
|
// log on
|
||||||
|
_client.logon();
|
||||||
|
|
||||||
|
// loop over our queue, running the runnables
|
||||||
|
while (true) {
|
||||||
|
Runnable run = (Runnable)_queue.get();
|
||||||
|
run.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invokeLater (Runnable run)
|
||||||
|
{
|
||||||
|
// queue it on up
|
||||||
|
_queue.append(run);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clientDidLogon (Client client)
|
||||||
|
{
|
||||||
|
Log.info("Client did logon [client=" + client + "].");
|
||||||
|
|
||||||
|
// request to move to scene 0
|
||||||
|
_ctx.getSceneManager().moveTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clientFailedToLogon (Client client, Exception cause)
|
||||||
|
{
|
||||||
|
Log.info("Client failed to logon [client=" + client +
|
||||||
|
", cause=" + cause + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clientConnectionFailed (Client client, Exception cause)
|
||||||
|
{
|
||||||
|
Log.info("Client connection failed [client=" + client +
|
||||||
|
", cause=" + cause + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean clientWillLogoff (Client client)
|
||||||
|
{
|
||||||
|
Log.info("Client will logoff [client=" + client + "].");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clientDidLogoff (Client client)
|
||||||
|
{
|
||||||
|
Log.info("Client did logoff [client=" + client + "].");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean locationMayChange (int placeId)
|
||||||
|
{
|
||||||
|
// we're easy
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void locationDidChange (PlaceObject place)
|
||||||
|
{
|
||||||
|
Log.info("At new location [plobj=" + place +
|
||||||
|
", scene=" + _scmgr.getScene() + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void locationChangeFailed (int placeId, String reason)
|
||||||
|
{
|
||||||
|
Log.warning("Location change failed [plid=" + placeId +
|
||||||
|
", reason=" + reason + "].");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
UsernamePasswordCreds creds =
|
||||||
|
new UsernamePasswordCreds("test", "test");
|
||||||
|
// create our test client
|
||||||
|
TestClient tclient = new TestClient(creds);
|
||||||
|
// start it running
|
||||||
|
tclient.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class WhirledContextImpl implements WhirledContext
|
||||||
|
{
|
||||||
|
public Config getConfig ()
|
||||||
|
{
|
||||||
|
return _config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client getClient ()
|
||||||
|
{
|
||||||
|
return _client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DObjectManager getDObjectManager ()
|
||||||
|
{
|
||||||
|
return _client.getDObjectManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocationManager getLocationManager ()
|
||||||
|
{
|
||||||
|
return _scmgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SceneManager getSceneManager ()
|
||||||
|
{
|
||||||
|
return _scmgr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Config _config;
|
||||||
|
protected Client _client;
|
||||||
|
protected SceneManager _scmgr;
|
||||||
|
protected SceneRepository _screp;
|
||||||
|
protected WhirledContext _ctx;
|
||||||
|
|
||||||
|
protected Queue _queue = new Queue();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user