Moved to vilya.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4213 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2006-06-23 19:20:52 +00:00
parent 9136cd4bce
commit f6f3c89fe0
38 changed files with 0 additions and 3654 deletions
@@ -1,92 +0,0 @@
//
// $Id: SceneController.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.client {
import com.threerings.presents.dobj.MessageEvent;
import com.threerings.presents.dobj.MessageListener;
import com.threerings.crowd.client.PlaceController;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.whirled.data.SceneCodes;
import com.threerings.whirled.data.SceneUpdate;
import com.threerings.whirled.util.WhirledContext;
/**
* 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.
*/
public /*abstract*/ class SceneController extends PlaceController
{
// documentation inherited
override public function init (ctx :CrowdContext, config :PlaceConfig) :void
{
super.init(ctx, config);
_wctx = WhirledContext(ctx);
}
// documentation inherited
override public function willEnterPlace (plobj :PlaceObject) :void
{
super.willEnterPlace(plobj);
plobj.addListener(_updateListener);
}
// documentation inherited
override public function didLeavePlace (plobj :PlaceObject) :void
{
super.didLeavePlace(plobj);
plobj.removeListener(_updateListener);
}
/**
* This method is called if a scene update is recorded while we
* currently occupy a scene. The default implementation will update
* our local scene and scene model, but derived classes will likely
* want to ensure that the update is properly displayed.
*/
protected function sceneUpdated (update :SceneUpdate) :void
{
// apply the update to the scene
_wctx.getSceneDirector().getScene().updateReceived(update);
// we don't persistify these updates in this circumstance, but
// next time we come to this scene we'll redownload the update and
// apply it to the repository; as the updates are meant to be very
// small, this shouldn't be horribly less efficient
}
/** Used to listen for scene updates. */
protected var _updateListener :MessageListener = new MessageAdapter(
function (event :MessageEvent) :void {
if (event.getName() == SceneCodes.SCENE_UPDATE) {
sceneUpdated(event.getArgs()[0] as SceneUpdate);
}
}
);
protected var _wctx :WhirledContext;
}
}
@@ -1,68 +0,0 @@
//
// $Id: SceneDecoder.java 3914 2006-03-06 21:51:59Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2006 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.client {
import com.threerings.presents.client.InvocationDecoder;
import com.threerings.whirled.client.SceneReceiver;
/**
* Dispatches calls to a {@link SceneReceiver} instance.
*/
public class SceneDecoder extends InvocationDecoder
{
/** The generated hash code used to identify this receiver class. */
public static const RECEIVER_CODE :String =
"c4d0cf66b81a6e83d119b2d607725651";
/** The method id used to dispatch {@link SceneReceiver#forcedMove}
* notifications. */
public static const FORCED_MOVE :int = 1;
/**
* Creates a decoder that may be registered to dispatch invocation
* service notifications to the specified receiver.
*/
public function SceneDecoder (receiver :SceneReceiver)
{
this.receiver = receiver;
}
// documentation inherited
override public function getReceiverCode () :String
{
return RECEIVER_CODE;
}
// documentation inherited
override public function dispatchNotification (methodId :int, args :Array) :void
{
switch (methodId) {
case FORCED_MOVE:
(receiver as SceneReceiver).forcedMove(args[0] as int);
return;
default:
super.dispatchNotification(methodId, args);
}
}
}
}
@@ -1,527 +0,0 @@
//
// $Id: SceneDirector.java 4088 2006-05-04 00:39:46Z mjohnson $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.client {
import flash.errors.IOError;
import flash.errors.IllegalOperationError;
import com.threerings.util.HashMap;
import com.threerings.util.ResultListener;
import com.threerings.io.TypedArray;
import com.threerings.presents.client.BasicDirector;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.ClientEvent;
import com.threerings.presents.data.InvocationCodes;
import com.threerings.crowd.client.LocationDirector;
import com.threerings.crowd.client.LocationDirector_FailureHandler;
import com.threerings.crowd.client.LocationObserver;
import com.threerings.crowd.data.PlaceConfig;
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.NoSuchSceneError;
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
* 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 coordinates with 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
* LocationObserver#locationMayChange} and {@link
* LocationObserver#locationChangeFailed}.
*/
public class SceneDirector extends BasicDirector
implements LocationDirector_FailureHandler,
SceneReceiver, SceneService_SceneMoveListener
{
private static const log :Log = Log.getLog(SceneDirector);
/**
* Creates a new scene director with the specified context.
*
* @param ctx the active client context.
* @param locdir the location director in use on the client, with
* which the scene director will coordinate when changing location.
* @param screp the entity from which the scene director will load
* scene data from the local client scene storage. This may be null
* when the SceneDirector is constructed, but it should be
* supplied via {@link #setSceneRepository} prior to really using
* this director.
* @param fact the factory that knows which derivation of {@link
* Scene} to create for the current system.
*/
public function SceneDirector (
ctx :WhirledContext, locdir :LocationDirector,
screp :SceneRepository, fact :SceneFactory)
{
super(ctx);
// we'll need these for later
_wctx = ctx;
_locdir = locdir;
setSceneRepository(screp);
_fact = fact;
// set ourselves up as a failure handler with the location
// director because we need to do special processing
_locdir.setFailureHandler(this);
// register for scene notifications
_wctx.getClient().getInvocationDirector().registerReceiver(
new SceneDecoder(this));
}
/**
* Set the scene repository.
*/
public function setSceneRepository (screp :SceneRepository) :void
{
_screp = screp;
_scache.clear();
}
/**
* Returns the display scene object associated with the scene we
* currently occupy or null if we currently occupy no scene.
*/
public function getScene () :Scene
{
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.
*
* @return true if the move to request was issued, false if it was
* rejected by a location observer or because we have another request
* outstanding.
*/
public function moveTo (sceneId :int) :Boolean
{
// make sure the sceneId is valid
if (sceneId < 0) {
log.warning("Refusing moveTo(): invalid sceneId " + sceneId + ".");
return false;
}
// sanity-check the destination scene id
if (sceneId == _sceneId) {
log.warning("Refusing request to move to the same scene " +
"[sceneId=" + sceneId + "].");
return false;
}
// prepare to move to this scene (sets up pending data)
if (!prepareMoveTo(sceneId, null)) {
return false;
}
// check the version of our cached copy of the scene to which
// we're requesting to move; if we were unable to load it, assume
// a cached version of zero
var sceneVers :int = 0;
if (_pendingModel != null) {
sceneVers = _pendingModel.version;
}
// issue a moveTo request
log.info("Issuing moveTo(" + sceneId + ", " + sceneVers + ").");
_sservice.moveTo(_wctx.getClient(), sceneId, sceneVers, this);
return true;
}
/**
* Prepares to move to the requested scene. The location observers are
* asked to ratify the move and our pending scene mode is loaded from
* the scene repository. This can be called by cooperating directors
* that need to coopt the moveTo process.
*/
public function prepareMoveTo (sceneId :int, rl :ResultListener) :Boolean
{
// first check to see if our observers are happy with this move
// request
if (!_locdir.mayMoveTo(sceneId, rl)) {
return false;
}
// we need to call this both to mark that we're issuing a move
// request and to check to see if the last issued request should
// be considered stale
var refuse :Boolean = _locdir.checkRepeatMove();
// complain if we're over-writing a pending request
if (_pendingSceneId != -1) {
if (refuse) {
log.warning("Refusing moveTo; We have a request outstanding " +
"[psid=" + _pendingSceneId +
", nsid=" + sceneId + "].");
return false;
} else {
log.warning("Overriding stale moveTo request " +
"[psid=" + _pendingSceneId +
", nsid=" + sceneId + "].");
}
}
// load up the pending scene so that we can communicate it's most
// recent version to the server
_pendingModel = loadSceneModel(sceneId);
// make a note of our pending scene id
_pendingSceneId = sceneId;
// all systems go
return true;
}
/**
* Returns the model loaded in preparation for a scene
* transition. This is made available only for cooperating directors
* which may need to coopt the scene transition process. The pending
* model is only valid immediately following a call to {@link
* #prepareMoveTo}.
*/
public function getPendingModel () :SceneModel
{
return _pendingModel;
}
// documentation inherited from interface SceneService_SceneMoveListener
public function moveSucceeded (placeId :int, config :PlaceConfig) :void
{
// our move request was successful, deal with subscribing to our
// new place object
_locdir.didMoveTo(placeId, config);
// 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
// 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;
// load the new scene model
_model = loadSceneModel(_sceneId);
// complain if we didn't find a scene
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 = _fact.createScene(_model, config);
}
// documentation inherited from interface SceneService_SceneMoveListener
public function moveSucceededWithUpdates (
placeId :int, config :PlaceConfig, updates :TypedArray) :void
{
log.info("Got updates [placeId=" + placeId + ", config=" + config +
", updates=" + updates + "].");
// apply the updates to our cached scene
var model :SceneModel = loadSceneModel(_pendingSceneId);
var failure :Boolean = false;
for each (var update :SceneUpdate in updates) {
try {
update.validate(model);
} catch (ise :IllegalOperationError) {
log.warning("Scene update failed validation [model=" + model +
", update=" + update +
", error=" + ise.getMessage() + "].");
failure = true;
break;
}
try {
update.apply(model);
} catch (e :Error) {
log.warning("Failure applying scene update [model=" + model +
", update=" + update + "].");
log.logStackTrace(e);
failure = true;
break;
}
}
if (failure) {
// delete the now half-booched scene model from the repository
try {
_screp.deleteSceneModel(_pendingSceneId);
} catch (ioe :IOError) {
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(InvocationCodes.INTERNAL_ERROR);
return;
}
// store the updated scene in the repository
try {
_screp.storeSceneModel(model);
} catch (ioe :IOError) {
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 SceneService-SceneMoveListener
public function moveSucceededWithScene (
placeId :int, config :PlaceConfig, model :SceneModel) :void
{
log.info("Got updated scene model [placeId=" + placeId +
", config=" + config + ", scene=" + model.sceneId + "/" +
model.name + "/" + model.version + "].");
// update the model in the repository
try {
_screp.storeSceneModel(model);
} catch (ioe :IOError) {
log.warning("Failed to update repository with new version " +
"[sceneId=" + model.sceneId +
", nvers=" + model.version + "].");
log.logStackTrace(ioe);
}
// update our scene cache
_scache.put(model.sceneId, model);
// and pass through to the normal move succeeded handler
moveSucceeded(placeId, config);
}
// documentation inherited from interface
public function requestFailed (reason :String) :void
{
// clear out our pending request oid
var sceneId :int = _pendingSceneId;
_pendingSceneId = -1;
// let our observers know that something has gone horribly awry
_locdir.failedToMoveTo(sceneId, reason);
}
/**
* Called to clean up our place and scene state information when we
* leave a scene.
*/
public function didLeaveScene () :void
{
// let the location director know what's up
_locdir.didLeavePlace();
// clear out our own scene state
clearScene();
}
// documentation inherited from interface
public function forcedMove (sceneId :int) :void
{
log.info("Moving at request of server [sceneId=" + sceneId + "].");
// clear out our old scene and place data
didLeaveScene();
// move to the new scene
moveTo(sceneId);
}
/**
* Sets the moveHandler for use in recoverFailedMove.
*/
public function setMoveHandler (handler :SceneDirector_MoveHandler) :void
{
if (_moveHandler != null) {
log.warning("Requested to set move handler, but we've " +
"already got one. The conflicting entities will " +
"likely need to perform more sophisticated " +
"coordination to deal with failures. " +
"[old=" + _moveHandler + ", new=" + handler + "].");
} else {
_moveHandler = handler;
}
}
/**
* Called when something breaks down in the process of performing a
* <code>moveTo</code> request.
*/
public function recoverFailedMove (placeId :int) :void
{
// we'll need this momentarily
var sceneId :int = _sceneId;
// 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
if (_previousSceneId != -1 && _previousSceneId != sceneId) {
// if we have a move handler use that
if (_moveHandler != null) {
_moveHandler.recoverMoveTo(_previousSceneId);
} else {
moveTo(_previousSceneId);
}
}
}
/**
* Clears out our current scene information and releases the scene
* model for the loaded scene back to the cache.
*/
protected function clearScene () :void
{
// clear out our scene id info
_sceneId = -1;
// 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 function loadSceneModel (sceneId :int) :SceneModel
{
// first look in the model cache
var model :SceneModel = (_scache.get(sceneId) as SceneModel);
// load from the repository if it's not cached
if (model == null) {
try {
model = _screp.loadSceneModel(sceneId);
_scache.put(sceneId, model);
} catch (nsse :NoSuchSceneError) {
// nothing special here, just fall through and return null
} catch (ioe :IOError) {
// complain first, then return null
log.warning("Error loading scene [scid=" + sceneId +
", error=" + ioe + "].");
}
}
return model;
}
// documentation inherited
override public function clientDidLogoff (event :ClientEvent) :void
{
super.clientDidLogoff(event);
// clear out our business
clearScene();
_scache.clear();
_pendingSceneId = -1;
_pendingModel = null;
_previousSceneId = -1;
_sservice = null;
}
// documentation inherited
override protected function fetchServices (client :Client) :void
{
// get a handle on our scene service
_sservice = (client.requireService(SceneService) as SceneService);
}
/** Access to general client services. */
protected var _wctx :WhirledContext;
/** Access to our scene services. */
protected var _sservice :SceneService;
/** The client's active location director. */
protected var _locdir :LocationDirector;
/** The entity via which we load scene data. */
protected var _screp :SceneRepository;
/** The entity we use to create scenes from scene models. */
protected var _fact :SceneFactory;
/** A cache of scene model information. */
protected var _scache :HashMap = new HashMap(); // TODO: LRUHashMap(5)
/** The display scene object for the scene we currently occupy. */
protected var _scene :Scene;
/** The scene model for the scene we currently occupy. */
protected var _model :SceneModel;
/** The id of the scene we currently occupy. */
protected var _sceneId :int = -1;
/** Our most recent copy of the scene model for the scene we're about
* to enter. */
protected var _pendingModel :SceneModel;
/** The id of the scene for which we have an outstanding moveTo
* request, or -1 if we have no outstanding request. */
protected var _pendingSceneId :int = -1;
/** The id of the scene we previously occupied. */
protected var _previousSceneId :int = -1;
/** Reference to our move handler. */
protected var _moveHandler :SceneDirector_MoveHandler = null;
}
}
@@ -1,14 +0,0 @@
package com.threerings.whirled.client {
/**
* Used to recover from a problem after a completed moveTo.
*/
public interface SceneDirector_MoveHandler
{
/**
* Should instruct the client to move the last known working
* location (as well as clean up after the failed moveTo request).
*/
function recoverMoveTo (sceneId :int) :void;
}
}
@@ -1,40 +0,0 @@
//
// $Id: SceneReceiver.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.client {
import com.threerings.presents.client.InvocationReceiver;
/**
* Defines, for the scene services, a set of notifications delivered
* asynchronously by the server to the client.
*/
public interface SceneReceiver extends InvocationReceiver
{
/**
* Used to communicate a required move notification to the client. The
* server will have removed the client from their existing scene
* and the client is then responsible for generating a {@link
* SceneService#moveTo} request to move to the new scene.
*/
function forcedMove (sceneId :int) :void
}
}
@@ -1,50 +0,0 @@
//
// $Id: SceneService.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.client {
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
* related invocation services (e.g. moving from scene to scene).
*/
public interface SceneService extends InvocationService
{
/**
* 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 version the version number of the scene object that we have
* in our local repository.
*/
function moveTo (
client :Client, sceneId :int, version :int,
listener :SceneService_SceneMoveListener) :void;
}
}
@@ -1,50 +0,0 @@
package com.threerings.whirled.client {
import com.threerings.presents.client.InvocationListener;
import com.threerings.io.TypedArray;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.data.SceneUpdate;
/**
* Used to communicate the response to a {@link #moveTo} request.
*/
public interface SceneService_SceneMoveListener extends InvocationListener
{
/**
* Indicates that a move succeeded.
*
* @param placeId the place object id of the newly occupied scene.
* @param config metadata related to the newly occupied scene.
*/
function moveSucceeded (placeId :int, config :PlaceConfig) :void;
/**
* 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 updates updates that must be applied to the client's
* copy of a scene model to bring it up to date.
*/
function moveSucceededWithUpdates (
placeId :int, config :PlaceConfig,
updates :TypedArray /*of SceneUpdate*/) :void;
/**
* 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.
*/
function moveSucceededWithScene (
placeId :int, config :PlaceConfig, model :SceneModel) :void;
}
}
@@ -1,66 +0,0 @@
//
// $Id: SceneRepository.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.client.persist {
import flash.errors.IOError;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.util.NoSuchSceneError;
/**
* The scene repository provides access to a persistent repository of
* scene information.
*
* @see SceneModel
*/
public interface SceneRepository
{
/**
* Fetches the model for the scene with the specified id.
*
* @exception IOException thrown if an error occurs attempting to load
* the scene data.
* @exception NoSuchSceneException thrown if no scene exists with the
* specified scene id.
*/
function loadSceneModel (sceneId :int) :SceneModel;
//throws IOException, NoSuchSceneException;
/**
* Updates or inserts this scene model as appropriate.
*
* @exception IOException thrown if an error occurs attempting to
* access the repository.
*/
function storeSceneModel (model :SceneModel) :void;
//throws IOException;
/**
* Deletes the specified scene model from the repository.
*
* @exception IOException thrown if an error occurs attempting to
* access the repository.
*/
function deleteSceneModel (sceneId :int) :void;
//throws IOException;
}
}
@@ -1,35 +0,0 @@
//
// $Id: AuxModel.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.util.Cloneable;
import com.threerings.io.Streamable;
/**
* An interface that must be implemented by auxiliary scene models.
*/
public interface AuxModel extends Streamable, Cloneable
{
// no new methods
}
}
@@ -1,45 +0,0 @@
//
// $Id: DefaultSceneConfig.java 4026 2006-04-18 01:32:41Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.whirled.client.SceneController;
/**
* The default scene config simply causes the default scene manager and
* controller to be created. A user of the Whirled services would most
* likely extend the default scene config.
*
* <p> Note that this place config won't even work on the client side
* because it instantiates a {@link SceneController} which is an abstract
* class. It is used only for testing the server side and as a placeholder
* in case standard scene configuration information is one day needed.
*/
public class DefaultSceneConfig extends PlaceConfig
{
// documentation inherited
public function getManagerClassName () :String
{
return "com.threerings.whirled.server.SceneManager";
}
}
}
@@ -1,84 +0,0 @@
//
// $Id: Scene.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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.
*/
function getId () :int;
/**
* Returns the human readable name of this scene.
*/
function getName () :String;
/**
* Returns the version number of this scene.
*/
function getVersion () :int;
/**
* 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.
*/
function getPlaceConfig () :PlaceConfig;
/**
* Sets this scene's unique identifier.
*/
function setId (sceneId :int) :void;
/**
* Sets the human readable name of this scene.
*/
function setName (name :String) :void;
/**
* Sets this scene's version number.
*/
function setVersion (version :int) :void;
/**
* Called to inform the scene that an update has been received while
* the scene was resolved and active. The update should be applied to
* the underlying scene model and any derivative data should be
* appropriately updated.
*/
function updateReceived (update :SceneUpdate) :void;
/**
* Returns the scene model from which this scene was created.
*/
function getSceneModel () :SceneModel;
}
}
@@ -1,34 +0,0 @@
//
// $Id: SceneCodes.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.crowd.data.LocationCodes;
/**
* Contains codes used by the scene invocation services.
*/
public class SceneCodes extends LocationCodes
{
/** The message identifier for scene update messages. */
public static const SCENE_UPDATE :String = "scene_update";
}
}
@@ -1,124 +0,0 @@
//
// $Id: SceneImpl.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.crowd.data.PlaceConfig;
/**
* 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 function SceneImpl (
model :SceneModel = null, config :PlaceConfig = null)
{
if (model != null) {
_model = model;
_config = config;
} else {
_model = SceneModel.blankSceneModel();
}
}
// documentation inherited
public function getId () :int
{
return _model.sceneId;
}
// documentation inherited
public function getName () :String
{
return _model.name;
}
// documentation inherited
public function getVersion () :int
{
return _model.version;
}
// documentation inherited
public function getPlaceConfig () :PlaceConfig
{
return _config;
}
// documentation inherited from interface
public function setId (sceneId :int) :void
{
_model.sceneId = sceneId;
}
// documentation inherited from interface
public function setName (name :String) :void
{
_model.name = name;
}
// documentation inherited from interface
public function setVersion (version :int) :void
{
_model.version = version;
}
// documentation inherited from interface
public function updateReceived (update :SceneUpdate) :void
{
try {
// validate and apply the update
update.validate(_model);
update.apply(_model);
} catch (e :Error) {
var log :Log = Log.getLog(this);
log.warning("Error applying update [scene=" + this +
", update=" + update + "].");
log.logStackTrace(e);
}
}
// documentation inherited from interface
public function getSceneModel () :SceneModel
{
return _model;
}
/**
* Generates a string representation of this instance.
*/
public function toString () :String
{
return "[model=" + _model + ", config=" + _config + "]";
}
/** A reference to our scene model. */
protected var _model :SceneModel;
/** A reference to our place configuration. */
protected var _config :PlaceConfig;
}
}
@@ -1,53 +0,0 @@
//
// $Id: SceneMarshaller.java 3793 2005-12-21 02:12:57Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.util.Integer;
import com.threerings.presents.client.Client;
import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.whirled.client.SceneService;
import com.threerings.whirled.client.SceneService_SceneMoveListener;
/**
* Provides the implementation of the {@link SceneService} interface
* that marshalls the arguments and delivers the request to the provider
* 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.
*/
public class SceneMarshaller extends InvocationMarshaller
implements SceneService
{
/** The method id used to dispatch {@link #moveTo} requests. */
public static const MOVE_TO :int = 1;
// documentation inherited from interface
public function moveTo (arg1 :Client, arg2 :int, arg3 :int, arg4 :SceneService_SceneMoveListener) :void
{
var listener4 :SceneMarshaller_SceneMoveMarshaller = new SceneMarshaller_SceneMoveMarshaller();
listener4.listener = arg4;
sendRequest(arg1, MOVE_TO, [ new Integer(arg2), new Integer(arg3), listener4 ]);
}
}
}
@@ -1,81 +0,0 @@
package com.threerings.whirled.data {
import com.threerings.util.Integer;
import com.threerings.io.TypedArray;
import com.threerings.presents.data.InvocationMarshaller_ListenerMarshaller;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.presents.dobj.InvocationResponseEvent;
import com.threerings.whirled.client.SceneService_SceneMoveListener;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.data.SceneUpdate;
public class SceneMarshaller_SceneMoveMarshaller extends InvocationMarshaller_ListenerMarshaller
implements SceneService_SceneMoveListener
{
/** The method id used to dispatch {@link #moveSucceeded}
* responses. */
public static const MOVE_SUCCEEDED :int = 1;
// documentation inherited from interface SceneService_SceneMoveListener
public function moveSucceeded (arg1 :int, arg2 :PlaceConfig) :void
{
omgr.postEvent(new InvocationResponseEvent(
callerOid, requestId, MOVE_SUCCEEDED,
[ new Integer(arg1), arg2 ]));
}
/** The method id used to dispatch {@link #moveSucceededWithScene}
* responses. */
public static const MOVE_SUCCEEDED_WITH_SCENE :int = 2;
// documentation inherited from interface SceneService_SceneMoveListener
public function moveSucceededWithScene (arg1 :int, arg2 :PlaceConfig, arg3 :SceneModel) :void
{
omgr.postEvent(new InvocationResponseEvent(
callerOid, requestId, MOVE_SUCCEEDED_WITH_SCENE,
[ new Integer(arg1), arg2, arg3 ]));
}
/** The method id used to dispatch {@link #moveSucceededWithUpdates}
* responses. */
public static const MOVE_SUCCEEDED_WITH_UPDATES :int = 3;
// documentation inherited from interface SceneService_SceneMoveListener
public function moveSucceededWithUpdates (arg1 :int, arg2 :PlaceConfig, arg3 :TypedArray /* of SceneUpdate */) :void
{
omgr.postEvent(new InvocationResponseEvent(
callerOid, requestId, MOVE_SUCCEEDED_WITH_UPDATES,
[ new Integer(arg1), arg2, arg3 ]));
}
// documentation inherited
override public function dispatchResponse (methodId :int, args :Array) :void
{
switch (methodId) {
case MOVE_SUCCEEDED:
(listener as SceneService_SceneMoveListener).moveSucceeded(
(args[0] as Integer).value, args[1] as PlaceConfig);
return;
case MOVE_SUCCEEDED_WITH_SCENE:
(listener as SceneService_SceneMoveListener).moveSucceededWithScene(
(args[0] as Integer).value, args[1] as PlaceConfig, args[2] as SceneModel);
return;
case MOVE_SUCCEEDED_WITH_UPDATES:
(listener as SceneService_SceneMoveListener).moveSucceededWithUpdates(
(args[0] as Integer).value, args[1] as PlaceConfig, args[2] as TypedArray);
return;
default:
super.dispatchResponse(methodId, args);
}
}
}
}
@@ -1,118 +0,0 @@
//
// $Id: SceneModel.java 3726 2005-10-11 19:17:43Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.util.ClassUtil;
import com.threerings.util.Cloneable;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
import com.threerings.io.TypedArray;
/**
* 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 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
* server to the client.
*/
public class SceneModel
implements Streamable, Cloneable
{
/** This scene's unique identifier. */
public var sceneId :int;
/** The human readable name of this scene. */
public var name :String;
/** The version number of this scene. Versions are incremented
* whenever modifications are made to a scene so that clients can
* determine whether or not they have the latest version of a
* scene. */
public var version :int;
/** Auxiliary scene model information. */
public var auxModels :TypedArray =
new TypedArray("[Lcom.threerings.whirled.data.AuxModel;");
/**
* Adds the specified auxiliary model to this scene model.
*/
public function addAuxModel (auxModel :AuxModel) :void
{
auxModels.push(auxModel);
}
// documentation inherited from interface Cloneable
public function clone () :Object
{
var clazz :Class = ClassUtil.getClass(this);
var model :SceneModel = new clazz();
for each (var aux :AuxModel in auxModels) {
model.addAuxModel(aux.clone() as AuxModel);
}
return model;
}
// documentation inherited from interface Streamable
public function writeObject (out :ObjectOutputStream) :void
{
out.writeInt(sceneId);
out.writeField(name);
out.writeInt(version);
out.writeObject(auxModels);
}
// documentation inherited from interface Streamable
public function readObject (ins :ObjectInputStream) :void
{
sceneId = ins.readInt();
name = (ins.readField(String) as String);
version = ins.readInt();
auxModels = (ins.readObject() as TypedArray);
}
/**
* Creates and returns a blank scene model.
*/
public static function blankSceneModel () :SceneModel
{
var model :SceneModel = new SceneModel();
populateBlankSceneModel(model);
return model;
}
/**
* Populates a blank scene model with blank values.
*/
protected static function populateBlankSceneModel (model :SceneModel) :void
{
model.sceneId = -1;
model.name = "<blank>";
model.version = 0;
}
}
}
@@ -1,29 +0,0 @@
//
// $Id: SceneObject.java 3288 2004-12-28 03:51:29Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import com.threerings.crowd.data.PlaceObject;
public class SceneObject extends PlaceObject
{
}
}
@@ -1,153 +0,0 @@
//
// $Id: SceneUpdate.java 3760 2005-11-15 03:08:23Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
import flash.errors.IllegalOperationError;
import com.threerings.util.StringBuilder;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
/**
* 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 class SceneUpdate
implements Streamable /*, Cloneable */
{
/**
* Initializes this scene update such that it 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 function init (targetId :int, targetVersion :int) :void
{
_targetId = targetId;
_targetVersion = targetVersion;
}
/**
* Returns the scene id for which this update is appropriate.
*/
public function getSceneId () :int
{
return _targetId;
}
/**
* Returns the scene version for which this update is appropriate.
*/
public function getSceneVersion () :int
{
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 function validate (model :SceneModel) :void
//throws IllegalStateException
{
if (model.sceneId != _targetId) {
var errmsg :String = "Wrong target scene, expected id " +
_targetId + " got id " + model.sceneId;
throw new IllegalOperationError(errmsg);
}
if (model.version != _targetVersion) {
var errmsg :String = "Target scene not proper version, expected " +
_targetVersion + " got " + model.version;
throw new IllegalOperationError(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.apply</code>.
*/
public function apply (model :SceneModel) :void
{
// 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.getLog(this).warning("Egads! This scene has been updated two" +
" billion times [model=" + model + ", update=" + this + "].");
}
}
// documentation inherited from interface Streamable
public function writeObject (out :ObjectOutputStream) :void
//throws IOException
{
out.writeInt(_targetId);
out.writeInt(_targetVersion);
}
// documentation inherited from interface Streamable
public function readObject (ins :ObjectInputStream) :void
//throws IOException, ClassNotFoundException
{
_targetId = ins.readInt();
_targetVersion = ins.readInt();
}
/**
* Generates a string representation of this instance.
*/
public function toString () :String
{
var buf :StringBuilder = new StringBuilder("[");
toStringBuf(buf);
return buf.append("]").toString();
}
/**
* An extensible mechanism for generating a string representation of
* this instance.
*/
protected function toStringBuf (buf :StringBuilder) :void
{
buf.append("sceneId=").append(_targetId);
buf.append(", version=").append(_targetVersion);
}
/** The version number of the scene on which we operate. */
protected var _targetId :int;
/** The version number of the scene on which we operate. */
protected var _targetVersion :int;
}
}
@@ -1,40 +0,0 @@
//
// $Id: ScenedBodyObject.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.data {
/**
* A system that uses the whirled services must provide a body object
* extension that implements this interface.
*/
public interface ScenedBodyObject
{
/**
* Returns the scene id currently occupied by this body.
*/
function getSceneId () :int;
/**
* Sets the scene id currently occupied by this body.
*/
function setSceneId (sceneId :int) :void;
}
}
@@ -1,37 +0,0 @@
//
// $Id: SpotSceneController.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.client {
import com.threerings.whirled.client.SceneController;
/**
* The base spot scene controller class. It is expected that users of the
* Whirled Spot 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 SpotSceneController extends SceneController
{
}
}
@@ -1,472 +0,0 @@
//
// $Id: SpotSceneDirector.java 3890 2006-02-24 19:51:11Z mthomas $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.client {
import com.threerings.util.ResultListener;
import com.threerings.presents.client.BasicDirector;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.ClientEvent;
import com.threerings.presents.client.ConfirmAdapter;
import com.threerings.presents.client.ConfirmListener;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.dobj.AttributeChangeListener;
import com.threerings.presents.dobj.AttributeChangedEvent;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.DObjectManager;
import com.threerings.presents.dobj.ObjectAccessError;
import com.threerings.presents.dobj.Subscriber;
import com.threerings.crowd.chat.client.ChatDirector;
import com.threerings.crowd.chat.data.ChatCodes;
import com.threerings.crowd.client.LocationAdapter;
import com.threerings.crowd.client.LocationDirector;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.whirled.client.SceneDirector;
import com.threerings.whirled.data.SceneModel;
import com.threerings.whirled.data.ScenedBodyObject;
import com.threerings.whirled.util.WhirledContext;
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 Subscriber, AttributeChangeListener
{
private static const log :Log = Log.getLog(SpotSceneDirector);
/**
* Creates a new spot scene director with the specified context and
* which will cooperate with the supplied scene director.
*
* @param ctx the active client context.
* @param locdir the location director with which we will be
* cooperating.
* @param scdir the scene director with which we will be cooperating.
*/
public function SpotSceneDirector (
ctx :WhirledContext, locdir :LocationDirector, scdir :SceneDirector)
{
super(ctx);
_wctx = ctx;
_scdir = scdir;
// wire ourselves up to hear about leave place notifications
locdir.addLocationObserver(new LocationAdapter(null,
function (place :PlaceObject) :void {
handleDeparture();
}));
}
/**
* Configures this spot scene director with a chat director, with
* which it will coordinate to implement cluster chatting.
*/
public function setChatDirector (chatdir :ChatDirector) :void
{
_chatdir = chatdir;
}
/**
* Returns our current location unless we have a location change
* pending, in which case our pending location is returned.
*/
public function getIntendedLocation () :Location
{
return (_pendingLoc != null) ? _pendingLoc : _location;
}
/**
* Requests that this client move to the location specified by the
* supplied portal id. A request will be made and when the response is
* received, the location observers will be notified of success or
* failure.
*
* @return true if the request was issued, false if it was rejected by
* a location observer or because we have another request outstanding.
*/
public function traversePortal (
portalId :int,
rl :com.threerings.util.ResultListener = null) :Boolean
{
// look up the destination scene and location
var scene :SpotScene = (_scdir.getScene() as SpotScene);
if (scene == null) {
log.warning("Requested to traverse portal when we have " +
"no scene [portalId=" + portalId + "].");
return false;
}
// sanity check the server's notion of what scene we're in with
// our notion of it
var sceneId :int = _scdir.getScene().getId();
var sbobj :ScenedBodyObject =
(_wctx.getClient().getClientObject() as ScenedBodyObject);
if (sceneId != sbobj.getSceneId()) {
log.warning("Client and server differ in opinion of what scene " +
"we're in [sSceneId=" + sbobj.getSceneId() +
", cSceneId=" + sceneId + "].");
return false;
}
// find the portal they're talking about
var dest :Portal = scene.getPortal(portalId);
if (dest == null) {
log.warning("Requested to traverse non-existent portal " +
"[portalId=" + portalId + ", portals=" + scene.getPortals() +
"].");
return false;
}
// prepare to move to this scene (sets up pending data)
if (!_scdir.prepareMoveTo(dest.targetSceneId, rl)) {
log.info("Portal traversal vetoed by scene director " +
"[portalId=" + portalId + "].");
return false;
}
// check the version of our cached copy of the scene to which
// we're requesting to move; if we were unable to load it, assume
// a cached version of zero
var sceneVer :int = 0;
var pendingModel :SceneModel = _scdir.getPendingModel();
if (pendingModel != null) {
sceneVer = pendingModel.version;
}
// issue a traversePortal request
log.info("Issuing traversePortal(" +
sceneId + ", " + dest + ", " + sceneVer + ").");
_sservice.traversePortal(
_wctx.getClient(), sceneId, portalId, sceneVer, _scdir);
return true;
}
/**
* Issues a request to change our location within the scene to the
* specified location.
*
* @param loc the new location to which to move.
* @param listener 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 function changeLocation (
loc :Location, listener :com.threerings.util.ResultListener) :void
{
// refuse if there's a pending location change or if we're already
// at the specified location
if (loc.equivalent(_location)) {
log.info("Not going to " + loc + "; we're at " + _location +
" and we're headed to " + _pendingLoc + ".");
if (listener != null) {
// This isn't really a failure, it's just a no-op.
listener.requestCompleted(_location);
}
return;
}
if (_pendingLoc != null) {
log.info("Not going to " + loc + "; we're at " + _location +
" and we're headed to " + _pendingLoc + ".");
if (listener != null) {
// Already moving, best thing to do is ignore it.
listener.requestCompleted(_pendingLoc);
}
return;
}
var scene :SpotScene = (_scdir.getScene() as SpotScene);
if (scene == null) {
log.warning("Requested to change locations, but we're not " +
"currently in any scene [loc=" + loc + "].");
if (listener != null) {
listener.requestFailed(new Error("m.cant_get_there"));
}
return;
}
var sceneId :int = _scdir.getScene().getId();
log.info("Sending changeLocation request [scid=" + sceneId +
", loc=" + loc + "].");
_pendingLoc = (loc.clone() as Location);
var clist :ConfirmAdapter = new ConfirmAdapter(
function () :void {
_location = _pendingLoc;
_pendingLoc = null;
if (listener != null) {
listener.requestCompleted(_location);
}
},
function (reason :String) :void {
_pendingLoc = null;
if (listener != null) {
listener.requestFailed(new Error(reason));
}
});
_sservice.changeLocation(_wctx.getClient(), sceneId, loc, clist);
}
/**
* Issues a request to join the cluster associated with the specified
* user (starting one if necessary).
*
* @param froid the bodyOid of another user; the calling user will
* be made to join the target user's cluster.
* @param listener will be notified of success or failure.
*/
public function joinCluster (
froid :int, listener :com.threerings.util.ResultListener) :void
{
var scene :SpotScene = (_scdir.getScene() as SpotScene);
if (scene == null) {
log.warning("Requested to join cluster, but we're not " +
"currently in any scene [froid=" + froid + "].");
if (listener != null) {
listener.requestFailed(new Error("m.cant_get_there"));
}
return;
}
log.info("Joining cluster [friend=" + froid + "].");
_sservice.joinCluster(_wctx.getClient(), froid, new ConfirmAdapter(
function () :void {
if (listener != null) {
listener.requestCompleted(null);
}
},
function (reason :String) :void {
if (listener != null) {
listener.requestFailed(new Error(reason));
}
}));
}
/**
* Sends a chat message to the other users in the cluster to which the
* location that we currently occupy belongs.
*
* @return true if a cluster speak message was delivered, false if we
* are not in a valid cluster and refused to deliver the request.
*/
public function requestClusterSpeak (
message :String, mode :int = ChatCodes.DEFAULT_MODE) :Boolean
{
// make sure we're currently in a scene
var scene :SpotScene = (_scdir.getScene() as SpotScene);
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 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;
}
message = _chatdir.filter(message, null, true);
if (message != null) {
_sservice.clusterSpeak(_wctx.getClient(), message, mode);
}
return true;
}
// documentation inherited from interface
public function objectAvailable (object :DObject) :void
{
clearCluster(false);
var oid :int = object.getOid();
if (oid != _self.getClusterOid()) {
// we got it too late, just unsubscribe
var omgr :DObjectManager = _wctx.getDObjectManager();
omgr.unsubscribeFromObject(oid, this);
} else {
// it's our new cluster!
_clobj = object;
if (_chatdir != null) {
_chatdir.addAuxiliarySource(object,
SpotCodes.CLUSTER_CHAT_TYPE);
}
}
}
// documentation inherited from interface
public function requestFailed (oid :int, cause :ObjectAccessError) :void
{
log.warning("Unable to subscribe to cluster chat object " +
"[oid=" + oid + ", cause=" + cause + "].");
}
// documentation inherited from interface
public function attributeChanged (event :AttributeChangedEvent) :void
{
if (event.getName() == _self.getClusterField() &&
event.getValue() != event.getOldValue()) {
maybeUpdateCluster();
}
}
// documentation inherited
override public function clientDidLogon (event :ClientEvent) :void
{
super.clientDidLogon(event);
var clientObj :ClientObject = event.getClient().getClientObject();
if (clientObj is ClusteredBodyObject) {
// listen to the client object
clientObj.addListener(this);
_self = (clientObj as ClusteredBodyObject);
// we may need to subscribe to a cluster due to session resumption
maybeUpdateCluster();
}
}
// documentation inherited
override public function clientObjectDidChange (event :ClientEvent) :void
{
super.clientObjectDidChange(event);
// listen to the client object
var clientObj :ClientObject = event.getClient().getClientObject();
clientObj.addListener(this);
_self = (clientObj as ClusteredBodyObject);
}
// documentation inherited
override public function clientDidLogoff (event :ClientEvent) :void
{
super.clientDidLogoff(event);
// clear out our business
_location = null;
_pendingLoc = null;
_sservice = null;
clearCluster(true);
// stop listening to the client object
event.getClient().getClientObject().removeListener(this);
_self = null;
}
// documentation inherited
override protected function fetchServices (client :Client) :void
{
_sservice = (client.requireService(SpotService) as SpotService);
}
/**
* Clean up after a few things when we depart from a scene.
*/
protected function handleDeparture () :void
{
// clear out our last known location id
_location = null;
}
/**
* Checks to see if our cluster has changed and does the necessary
* subscription machinations if necessary.
*/
protected function maybeUpdateCluster () :void
{
var cloid :int = _self.getClusterOid();
if ((_clobj == null && cloid <= 0) ||
(_clobj != null && cloid == _clobj.getOid())) {
// our cluster didn't change, we can stop now
return;
}
// clear out any old cluster object
clearCluster(false);
// if there's a new cluster object, subscribe to it
if (_chatdir != null && cloid > 0) {
var omgr :DObjectManager = _wctx.getDObjectManager();
// we'll wire up to the chat director when this completes
omgr.subscribeToObject(cloid, this);
}
}
/**
* Convenience routine to unwire chat for and unsubscribe from our
* current cluster, if any.
*
* @param force clear the cluster even if we're still apparently in it.
*/
protected function clearCluster (force :Boolean) :void
{
if (_clobj != null &&
(force || (_clobj.getOid() != _self.getClusterOid()))) {
if (_chatdir != null) {
_chatdir.removeAuxiliarySource(_clobj);
}
var omgr :DObjectManager = _wctx.getDObjectManager();
omgr.unsubscribeFromObject(_clobj.getOid(), this);
_clobj = null;
}
}
/** The active client context. */
protected var _wctx :WhirledContext;
/** Access to spot scene services. */
protected var _sservice :SpotService;
/** The scene director with which we are cooperating. */
protected var _scdir :SceneDirector;
/** A casted reference to our clustered body object. */
protected var _self :ClusteredBodyObject;
/** A reference to the chat director with which we coordinate. */
protected var _chatdir :ChatDirector;
/** The location we currently occupy. */
protected var _location :Location;
/** The location to which we have an outstanding change location
* request. */
protected var _pendingLoc :Location;
/** The cluster chat object for the cluster we currently occupy. */
protected var _clobj :DObject;
}
}
@@ -1,85 +0,0 @@
//
// $Id: SpotService.java 3363 2005-02-22 18:54:48Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.client {
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 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 sceneId the player's current scene which is used to sanity
* check things when the request actually arrives.
* @param portalId the portal to be traversed.
* @param destSceneVer the version of the destination scene data that
* the client has in its local repository.
*/
function traversePortal (
client :Client, sceneId :int, portalId :int, destSceneVer :int,
listener :SceneService_SceneMoveListener) :void;
/**
* Requests that this client's body be made to move to the specified
* location. The user will be removed from any cluster from which they
* are an occupant.
*
* @param sceneId the id of the scene in which to change location.
* @param loc the location to which to move.
*/
function changeLocation (
client :Client, sceneId :int, loc :Location,
listener :ConfirmListener) :void;
/**
* Requests that this client start or join the specified cluster. They
* will be relocated appropriately by the scene manager.
*
* @param friendOid the bodyOid of another user or the oid of an
* existing cluster; the calling user will be made to join the cluster
* or target user's cluster, or create a cluster with the target user
* if they are not already in one.
*/
function joinCluster (
client :Client, friendOid :int, listener :ConfirmListener) :void;
/**
* 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.).
*/
function clusterSpeak (client :Client, message :String, mode :int) :void;
}
}
@@ -1,76 +0,0 @@
//
// $Id: Cluster.java 3310 2005-01-24 23:08:21Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import flash.geom.Rectangle;
import com.threerings.io.Streamable;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.dobj.DSet_Entry;
/**
* Contains information on clusters.
*/
public class Cluster extends Rectangle
implements DSet_Entry, Streamable
{
/** A unique identifier for this cluster (also the distributed object
* id of the cluster chat object). */
public var clusterOid :int;
// documentation inherited from interface DSet_Entry
public function getKey () :Object
{
return clusterOid;
}
// documentation inherited from interface Streamable
public function writeObject (out :ObjectOutputStream) :void
{
out.writeInt(x);
out.writeInt(y);
out.writeInt(width);
out.writeInt(height);
out.writeInt(clusterOid);
}
// documentation inherited from interface Streamable
public function readObject (ins :ObjectInputStream) :void
{
x = ins.readInt();
y = ins.readInt();
width = ins.readInt();
height = ins.readInt();
clusterOid = ins.readInt();
}
/**
* Generates a string representation of this instance.
*/
public function toString () :String
{
return super.toString() + ", clusterOid=" + clusterOid;
}
}
}
@@ -1,66 +0,0 @@
//
// $Id: ClusterObject.java 3288 2004-12-28 03:51:29Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.OidList;
import com.threerings.crowd.chat.data.SpeakObject;
/**
* Used to dispatch chat in clusters.
*/
public class ClusterObject extends DObject
{
// AUTO-GENERATED: FIELDS START
/** The field name of the <code>occupants</code> field. */
public static const OCCUPANTS :String = "occupants";
// AUTO-GENERATED: FIELDS END
/**
* Tracks the oid of the body objects that occupy this cluster.
*/
public var occupants :OidList = new OidList();
// AUTO-GENERATED: METHODS START
/**
* Requests that <code>oid</code> be added to the <code>occupants</code>
* oid list. The list will not change until the event is actually
* propagated through the system.
*/
public function addToOccupants (oid :int) :void
{
requestOidAdd(OCCUPANTS, oid);
}
/**
* Requests that <code>oid</code> be removed from the
* <code>occupants</code> oid list. The list will not change until the
* event is actually propagated through the system.
*/
public function removeFromOccupants (oid :int) :void
{
requestOidRemove(OCCUPANTS, oid);
}
// AUTO-GENERATED: METHODS END
}
}
@@ -1,48 +0,0 @@
//
// $Id: ClusteredBodyObject.java 3310 2005-01-24 23:08:21Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.whirled.data.ScenedBodyObject;
/**
* Defines some required methods for a {@link ScenedBodyObject} that is to
* participate in the Whirled Spot system.
*/
public interface ClusteredBodyObject extends ScenedBodyObject
{
/**
* Returns the field name of the cluster oid distributed object field.
*/
function getClusterField () :String;
/**
* Returns the oid of the cluster to which this user currently
* belongs.
*/
function getClusterOid () :int;
/**
* Sets the oid of the cluster to which this user currently belongs.
*/
function setClusterOid (clusterOid :int) :void;
}
}
@@ -1,52 +0,0 @@
//
// $Id: Location.java 3726 2005-10-11 19:17:43Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.io.Streamable;
import com.threerings.util.Cloneable;
import com.threerings.util.Hashable;
/**
* Contains information on a scene occupant's position and orientation.
*/
public interface Location extends Cloneable, Streamable, Hashable
{
/**
* Get a new Location instance that is equals() to this one but that
* has an orientation facing the opposite direction.
*/
function getOpposite () :Location;
/**
* Two locations are equivalent if they specify the same location
* and orientation.
*/
function equivalent (other :Location) :Boolean;
/** Two locations are equals by coordinates only. */
//function equals (other :Object) :Boolean;
/** The hashcode should be based on coordinates only. */
//function hashCode () :int;
}
}
@@ -1,141 +0,0 @@
//
// $Id: Portal.java 4072 2006-04-28 01:34:02Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.util.ClassUtil;
import com.threerings.util.Cloneable;
import com.threerings.io.Streamable;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.util.Hashable;
/**
* 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
implements Streamable, Hashable, Cloneable
{
/** This portal's unique identifier. */
public var portalId :int;
/** The location of the portal. Typically this is a base Location (2d)
* class, but different games could use a different subclass of
* Location. */
public var loc :Location;
/** The scene identifier of the scene to which a body will exit when
* they "use" this portal. */
public var targetSceneId :int;
/** The portal identifier of the portal at which a body will enter
* the target scene when they "use" this portal. */
public var targetPortalId :int;
/**
* Returns a location instance configured with the location and
* orientation of this portal.
*/
public function getLocation () :Location
{
return (loc.clone() as Location);
}
/**
* 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 function getOppLocation () :Location
{
return loc.getOpposite();
}
/**
* 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 function isValid () :Boolean
{
return (targetSceneId > 0) && (targetPortalId > 0);
}
// documentation inherited from interface Streamable
public function writeObject (out :ObjectOutputStream) :void
{
out.writeShort(portalId);
out.writeObject(loc);
out.writeInt(targetSceneId);
out.writeShort(targetPortalId);
}
// documentation inherited from interface Streamable
public function readObject (ins :ObjectInputStream) :void
{
portalId = ins.readShort();
loc = (ins.readObject() as Location);
targetSceneId = ins.readInt();
targetPortalId = ins.readShort();
}
// documentation inherited from interface Cloneable
public function clone () :Object
{
var clazz :Class = ClassUtil.getClass(this);
var p :Portal = new clazz();
p.portalId = portalId;
p.loc = loc;
p.targetSceneId = targetSceneId;
p.targetPortalId = targetPortalId;
return p;
}
// documentation inherited from interface Hashable
public function equals (other :Object) :Boolean
{
return (other is Portal) &&
((other as Portal).portalId == portalId);
}
// documentation inherited from interface Hashable
public function hashCode () :int
{
return portalId;
}
public function toString () :String
{
return "Portal[id=" + portalId + ", destScene=" + targetSceneId +
", loc=" + loc + "].";
}
}
}
@@ -1,86 +0,0 @@
//
// $Id: SceneLocation.java 3310 2005-01-24 23:08:21Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.util.Hashable;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.dobj.DSet_Entry;
/**
* Extends {@link Location} with the data and functionality needed to
* represent a particular user's location in a scene.
*/
public class SceneLocation
implements DSet_Entry, Hashable
{
/** The oid of the body that occupies this location. */
public var bodyOid :int;
/** The actual location, which is interpreted by the display system. */
public var loc :Location;
/**
* Creates a scene location with the specified information.
*/
public function SceneLocation (loc :Location = null, bodyOid :int = 0)
{
this.loc = loc;
this.bodyOid = bodyOid;
}
// documentation inherited from interface DSet_Entry
public function getKey () :Object
{
return bodyOid;
}
// documentation inherited from interface Hashable
public function equals (other :Object) :Boolean
{
return (other is SceneLocation) &&
this.loc.equals((other as SceneLocation).loc);
}
// documentation inherited from interface Hashable
public function hashCode () :int
{
return loc.hashCode();
}
// documentation inherited from superinterface Streamable
public function writeObject (out :ObjectOutputStream) :void
{
out.writeInt(bodyOid);
out.writeObject(loc);
}
// documentation inherited from superinterface Streamable
public function readObject (ins :ObjectInputStream) :void
{
bodyOid = ins.readInt();
loc = (ins.readObject() as Location);
}
}
}
@@ -1,58 +0,0 @@
//
// $Id: SpotCodes.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.crowd.chat.data.ChatCodes;
import com.threerings.whirled.data.SceneCodes;
/**
* Contains codes used by the Spot invocation services.
*/
public class SpotCodes extends SceneCodes /*, ChatCodes */
{
/** An error code indicating that the portal specified in a
* traversePortal request does not exist. */
public static const NO_SUCH_PORTAL :String = "m.no_such_portal";
/** An error code indicating that a location is occupied. Usually
* generated by a failed changeLoc request. */
public static const LOCATION_OCCUPIED :String = "m.location_occupied";
/** An error code indicating that a location is not valid. Usually
* generated by a failed changeLoc request. */
public static const INVALID_LOCATION :String = "m.invalid_location";
/** An error code indicating that a cluster is not valid. Usually
* generated by a failed joinCluster request. */
public static const NO_SUCH_CLUSTER :String = "m.no_such_cluster";
/** An error code indicating that a cluster is full. Usually generated
* by a failed joinCluster request. */
public static const CLUSTER_FULL :String = "m.cluster_full";
/** The chat type code with which we register our cluster auxiliary
* chat objects. Chat display implementations should interpret chat
* messages with this type accordingly. */
public static const CLUSTER_CHAT_TYPE :String = "clusterChat";
}
}
@@ -1,100 +0,0 @@
//
// $Id$
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.util.Byte;
import com.threerings.util.Integer;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.InvocationService;
import com.threerings.presents.client.ConfirmListener;
import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.presents.data.InvocationMarshaller_ConfirmMarshaller;
import com.threerings.presents.dobj.InvocationResponseEvent;
import com.threerings.whirled.client.SceneService;
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.data.Location;
/**
* Provides the implementation of the {@link SpotService} interface
* that marshalls the arguments and delivers the request to the provider
* 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.
*/
public class SpotMarshaller extends InvocationMarshaller
implements SpotService
{
/** The method id used to dispatch {@link #changeLocation} requests. */
public static const CHANGE_LOCATION :int = 1;
// documentation inherited from interface
public function changeLocation (arg1 :Client, arg2 :int, arg3 :Location, arg4 :ConfirmListener) :void
{
var listener4 :InvocationMarshaller_ConfirmMarshaller = new InvocationMarshaller_ConfirmMarshaller();
listener4.listener = arg4;
sendRequest(arg1, CHANGE_LOCATION, [
new Integer(arg2), arg3, listener4
]);
}
/** The method id used to dispatch {@link #clusterSpeak} requests. */
public static const CLUSTER_SPEAK :int = 2;
// documentation inherited from interface
public function clusterSpeak (arg1 :Client, arg2 :String, arg3 :int) :void
{
sendRequest(arg1, CLUSTER_SPEAK, [
arg2, new Byte(arg3)
]);
}
/** The method id used to dispatch {@link #joinCluster} requests. */
public static const JOIN_CLUSTER :int = 3;
// documentation inherited from interface
public function joinCluster (arg1 :Client, arg2 :int, arg3 :ConfirmListener) :void
{
var listener3 :InvocationMarshaller_ConfirmMarshaller = new InvocationMarshaller_ConfirmMarshaller();
listener3.listener = arg3;
sendRequest(arg1, JOIN_CLUSTER, [
new Integer(arg2), listener3
]);
}
/** The method id used to dispatch {@link #traversePortal} requests. */
public static const TRAVERSE_PORTAL :int = 4;
// documentation inherited from interface
public function traversePortal (arg1 :Client, arg2 :int, arg3 :int, arg4 :int, arg5 :SceneService_SceneMoveListener) :void
{
var listener5 :SceneMarshaller_SceneMoveMarshaller = new SceneMarshaller_SceneMoveMarshaller();
listener5.listener = arg5;
sendRequest(arg1, TRAVERSE_PORTAL, [
new Integer(arg2), new Integer(arg3), new Integer(arg4), listener5
]);
}
}
}
@@ -1,81 +0,0 @@
//
// $Id: SpotScene.java 3451 2005-03-31 19:40:55Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.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.
*/
function getPortal (portalId :int) :Portal;
/**
* Returns the number of portals in this scene.
*/
function getPortalCount () :int;
/**
* Returns an iterator over the portals in this scene.
*/
function getPortals () :Iterator;
/**
* Returns the portal id that should be assigned to the next portal
* added to this scene.
*/
function getNextPortalId () :int;
/**
* 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.
*/
function getDefaultEntrance () :Portal;
/**
* Adds a portal to this scene, immediately making the requisite
* modifications to the underlying scene model. The portal id should
* have already been assigned using the value obtained from {@link
* #getNextPortalId}.
*/
function addPortal (portal :Portal) :void;
/**
* Removes the specified portal from the scene.
*/
function removePortal (portal :Portal) :void;
/**
* Sets the default entrance in this scene, immediately making the
* requisite modifications to the underlying scene model.
*/
function setDefaultEntrance (portal :Portal) :void;
}
}
@@ -1,152 +0,0 @@
//
// $Id: SpotSceneImpl.java 3451 2005-03-31 19:40:55Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.util.ArrayIterator;
import com.threerings.util.Iterator;
import com.threerings.util.HashMap;
/**
* 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 function SpotSceneImpl (model :SpotSceneModel = null)
{
if (model != null) {
_smodel = model;
readPortals();
} else {
_smodel = new SpotSceneModel();
}
}
protected function readPortals () :void
{
_portals.clear();
for each (var port :Portal in _smodel.portals) {
_portals.put(port.portalId, port);
}
}
// documentation inherited from interface
public function getPortal (portalId :int) :Portal
{
return (_portals.get(portalId) as Portal);
}
// documentation inherited from interface
public function getPortalCount () :int
{
return _portals.size();
}
// documentation inherited from interface
public function getPortals () :Iterator
{
return new ArrayIterator(_portals.values());
}
// documentation inherited from interface
public function getNextPortalId () :int
{
// compute a new portal id for our friend the portal
for (var ii :int = 1; ii < MAX_PORTAL_ID; ii++) {
if (!_portals.containsKey(ii)) {
return ii;
}
}
return -1;
}
// documentation inherited from interface
public function getDefaultEntrance () :Portal
{
return getPortal(_smodel.defaultEntranceId);
}
// documentation inherited from interface
public function addPortal (portal :Portal) :void
{
if (portal.portalId <= 0) {
Log.getLog(this).warning("Refusing to add zero-id portal " +
"[scene=" + this + ", portal=" + portal + "].");
return;
}
// add it to our model
_smodel.addPortal(portal);
// and slap it into our table
_portals.put(portal.portalId, portal);
}
// documentation inherited from interface
public function removePortal (portal :Portal) :void
{
// 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 function setDefaultEntranceId (defaultEntranceId :int) :void
{
_smodel.defaultEntranceId = defaultEntranceId;
}
// documentation inherited from interface
public function setDefaultEntrance (portal :Portal) :void
{
_smodel.defaultEntranceId = (portal == null) ? -1 : portal.portalId;
}
/**
* This should be called if a scene update was received that caused
* our underlying scene model to change.
*/
public function updateReceived () :void
{
readPortals();
}
/** A casted reference to our scene model. */
protected var _smodel :SpotSceneModel;
/** A mapping from portal id to portal. */
protected var _portals :HashMap = new HashMap();
/** We don't allow more than ~32k portals in a scene. Things would
* slow down *way* before we got there. */
protected static const MAX_PORTAL_ID :int = int(Math.pow(2, 15) - 1);
}
}
@@ -1,115 +0,0 @@
//
// $Id: SpotSceneModel.java 3726 2005-10-11 19:17:43Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.util.ClassUtil;
import com.threerings.io.Streamable;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.TypedArray;
import com.threerings.whirled.data.AuxModel;
import com.threerings.whirled.data.SceneModel;
/**
* The spot scene model extends the standard scene model with information
* 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
implements Streamable, AuxModel
{
/** An array containing all portals in this scene. */
public var portals :TypedArray =
new TypedArray(TypedArray.getJavaType(Portal));
/** The portal id of the default entrance to this scene. If a body
* enters the scene without coming from another scene, this is the
* portal at which they would appear. */
public var defaultEntranceId :int = -1;
/**
* Adds a portal to this scene model.
*/
public function addPortal (portal :Portal) :void
{
portals.push(portal);
}
/**
* Removes a portal from this model.
*/
public function removePortal (portal :Portal) :void
{
for (var ii :int = 0; ii < portals.length; ii++) {
if (portal.equals(portals[ii])) {
portals.splice(ii, 1);
return;
}
}
}
// documentation inherited from superinterface Cloneable
public function clone () :Object
{
var clazz :Class = ClassUtil.getClass(this);
var model :SpotSceneModel = new clazz();
for each (var portal :Portal in portals) {
model.portals.push(portal.clone());
}
return model;
}
// documentation inherited from interface Streamable
public function writeObject (out :ObjectOutputStream) :void
{
out.writeObject(portals);
out.writeInt(defaultEntranceId);
}
// documentation inherited from interface Streamable
public function readObject (ins :ObjectInputStream) :void
{
portals = (ins.readObject() as TypedArray);
defaultEntranceId = ins.readInt();
}
/**
* 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 function getSceneModel (model :SceneModel) :SpotSceneModel
{
for each (var aux :AuxModel in model.auxModels) {
if (aux is SpotSceneModel) {
return (aux as SpotSceneModel);
}
}
return null;
}
}
}
@@ -1,162 +0,0 @@
//
// $Id: SpotSceneObject.java 3300 2005-01-08 22:05:00Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.spot.data {
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
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
{
// AUTO-GENERATED: FIELDS START
/** The field name of the <code>occupantLocs</code> field. */
public static const OCCUPANT_LOCS :String = "occupantLocs";
/** The field name of the <code>clusters</code> field. */
public static const CLUSTERS :String = "clusters";
// AUTO-GENERATED: FIELDS END
/** A distributed set containing {@link SceneLocation} records for all
* occupants of this scene. */
public var occupantLocs :DSet = new DSet();
/** Contains information on all {@link Cluster}s in this scene. */
public var clusters :DSet = new DSet();
// AUTO-GENERATED: METHODS START
/**
* 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 function addToOccupantLocs (elem :DSet_Entry) :void
{
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 function removeFromOccupantLocs (key :Object) :void
{
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 function updateOccupantLocs (elem :DSet_Entry) :void
{
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 function setOccupantLocs (value :DSet) :void
{
requestAttributeChange(OCCUPANT_LOCS, value, this.occupantLocs);
this.occupantLocs = value;
}
/**
* Requests that the specified entry be added to the
* <code>clusters</code> set. The set will not change until the event is
* actually propagated through the system.
*/
public function addToClusters (elem :DSet_Entry) :void
{
requestEntryAdd(CLUSTERS, elem);
}
/**
* Requests that the entry matching the supplied key be removed from
* the <code>clusters</code> set. The set will not change until the
* event is actually propagated through the system.
*/
public function removeFromClusters (key :Object) :void
{
requestEntryRemove(CLUSTERS, key);
}
/**
* Requests that the specified entry be updated in the
* <code>clusters</code> set. The set will not change until the event is
* actually propagated through the system.
*/
public function updateClusters (elem :DSet_Entry) :void
{
requestEntryUpdate(CLUSTERS, elem);
}
/**
* Requests that the <code>clusters</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 function setClusters (value :DSet) :void
{
requestAttributeChange(CLUSTERS, value, this.clusters);
this.clusters = value;
}
// AUTO-GENERATED: METHODS END
// documentation inherited
override public function writeObject (out :ObjectOutputStream) :void
{
super.writeObject(out);
out.writeObject(occupantLocs);
out.writeObject(clusters);
}
// documentation inherited
override public function readObject (ins :ObjectInputStream) :void
{
super.readObject(ins);
occupantLocs = (ins.readObject() as DSet);
clusters = (ins.readObject() as DSet);
}
}
}
@@ -1,43 +0,0 @@
//
// $Id: NoSuchSceneError.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.util {
/**
* Thrown when an attempt to load a non-existent scene is made on the
* repository.
*/
public class NoSuchSceneError extends Error
{
public function NoSuchSceneError (sceneid :int)
{
super("No such scene [sceneid=" + sceneid + "]");
_sceneid = sceneid;
}
public function getSceneId () :int
{
return _sceneid;
}
protected var _sceneid :int;
}
}
@@ -1,40 +0,0 @@
//
// $Id: SceneFactory.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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.
*/
function createScene (model :SceneModel, config :PlaceConfig) :Scene;
}
}
@@ -1,99 +0,0 @@
//
// $Id: UpdateList.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.util {
import com.threerings.whirled.data.SceneUpdate;
/**
* A list specialized for storing {@link SceneUpdate} objects.
*/
public class UpdateList
{
public function UpdateList ()
{
_updates = new Array();
}
/**
* 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 function addUpdate (update :SceneUpdate) :void
{
if (_minVersion == -1) {
// this is our first update, so we initialize our min version
_minVersion = update.getSceneVersion();
} else {
var gotVersion :int = update.getSceneVersion();
var expVersion :int = _minVersion + _updates.length;
if (gotVersion > expVersion) {
Log.getLog(this).warning("Update continuity broken, " +
"flushing list [got=" + update + ", expect=" + expVersion +
", ucount=" + _updates.length + "].");
// flush out our old updates and start anew from here
_updates.length = 0;
_minVersion = expVersion;
} else if (gotVersion < expVersion) {
// we somehow got an update that's older than updates we
// already have? wick wick wack
throw new IllegalArgumentError("Invalid update version " +
"[want=" + expVersion + ", got=" + update + "]");
}
}
_updates.push(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 function getUpdates (fromVersion :int) :Array /*of SceneUpdate*/
{
if (_minVersion == -1 || fromVersion < _minVersion) {
return null;
}
var offset :int = fromVersion - _minVersion;
return _updates.slice(offset);
}
/**
* Returns true if the supplied actual scene version is in accordance
* with the updates contained in this list.
*/
public function validate (sceneVersion :int) :Boolean
{
return ((_minVersion == -1) || // we have no updates
(_minVersion + _updates.length == sceneVersion));
}
protected var _updates :Array;
protected var _minVersion :int = -1;
}
}
@@ -1,38 +0,0 @@
//
// $Id: WhirledContext.java 3099 2004-08-27 02:21:06Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.whirled.util {
import com.threerings.crowd.util.CrowdContext;
import com.threerings.whirled.client.SceneDirector;
/**
* The whirled context provides access to the various managers, etc. that
* are needed by the whirled client code.
*/
public interface WhirledContext extends CrowdContext
{
/**
* Returns a reference to the scene director.
*/
function getSceneDirector () :SceneDirector;
}
}