Keep our pending data in an extensible object so that we can easily preserve it

across server switches, when it would otherwise be cleared out.


git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@365 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Michael Bayne
2007-07-17 21:14:40 +00:00
parent 08f7029220
commit b6562d91e6
@@ -161,24 +161,26 @@ public class SceneDirector extends BasicDirector
var refuse :Boolean = _locdir.checkRepeatMove();
// complain if we're over-writing a pending request
if (_pendingSceneId != -1) {
if (_pendingData != null) {
if (refuse) {
log.warning("Refusing moveTo; We have a request outstanding " +
"[psid=" + _pendingSceneId + ", nsid=" + sceneId + "].");
"[psid=" + _pendingData.sceneId + ", nsid=" + sceneId + "].");
return false;
} else {
log.warning("Overriding stale moveTo request [psid=" + _pendingSceneId +
log.warning("Overriding stale moveTo request [psid=" + _pendingData.sceneId +
", nsid=" + sceneId + "].");
}
}
// load up the pending scene so that we can communicate it's most recent version to the
// server
_pendingModel = loadSceneModel(sceneId);
// create and initialize a new pending data record
_pendingData = createPendingData();
// load up the cached pending scene so that we can communicate its version to the server
_pendingData.model = loadSceneModel(sceneId);
// make a note of our pending scene id
_pendingSceneId = sceneId;
_pendingData.sceneId = sceneId;
// all systems go
return true;
@@ -191,7 +193,7 @@ public class SceneDirector extends BasicDirector
*/
public function getPendingModel () :SceneModel
{
return _pendingModel;
return _pendingData == null ? null : _pendingData.model;
}
// from interface SceneService_SceneMoveListener
@@ -200,10 +202,6 @@ public class SceneDirector extends BasicDirector
// 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;
@@ -211,10 +209,12 @@ public class SceneDirector extends BasicDirector
clearScene();
// make the pending scene the active scene
_sceneId = _pendingSceneId;
_pendingSceneId = -1;
_sceneId = _pendingData.sceneId;
_pendingData = null;
// load the new scene model
// 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
_model = loadSceneModel(_sceneId);
// complain if we didn't find a scene
@@ -235,7 +235,7 @@ public class SceneDirector extends BasicDirector
", updates=" + updates + "].");
// apply the updates to our cached scene
var model :SceneModel = loadSceneModel(_pendingSceneId);
var model :SceneModel = loadSceneModel(_pendingData.sceneId);
var failure :Boolean = false;
for each (var update :SceneUpdate in updates) {
try {
@@ -261,10 +261,10 @@ public class SceneDirector extends BasicDirector
if (failure) {
// delete the now half-booched scene model from the repository
try {
_screp.deleteSceneModel(_pendingSceneId);
_screp.deleteSceneModel(_pendingData.sceneId);
} catch (ioe :IOError) {
log.warning("Failure removing booched scene model " +
"[sceneId=" + _pendingSceneId + "].");
"[sceneId=" + _pendingData.sceneId + "].");
log.logStackTrace(ioe);
}
@@ -302,6 +302,11 @@ public class SceneDirector extends BasicDirector
// from interface SceneService_SceneMoveListener
public function moveRequiresServerSwitch (hostname :String, ports :TypedArray) :void
{
log.info("Scene switch requires server switch [host=" + hostname +
", ports=" + ports + "].");
// keep track of our current pending data because it will be cleared when we log off of
// this server and onto the next one
var pendingData :PendingData = _pendingData;
// ship on over to the other server
_wctx.getClient().moveToServer(hostname, ports, new ConfirmAdapter(
function (reason :String) :void { // failed
@@ -309,6 +314,7 @@ public class SceneDirector extends BasicDirector
},
function () :void { // succeeded
// resend our move request now that we're connected to the new server
_pendingData = pendingData;
sendMoveRequest();
}
));
@@ -317,9 +323,9 @@ public class SceneDirector extends BasicDirector
// documentation inherited from interface
public function requestFailed (reason :String) :void
{
// clear out our pending request oid
var sceneId :int = _pendingSceneId;
_pendingSceneId = -1;
// clear out our pending info
var sceneId :int = _pendingData.sceneId;
_pendingData = null;
// let our observers know that something has gone horribly awry
_locdir.failedToMoveTo(sceneId, reason);
@@ -399,18 +405,45 @@ public class SceneDirector extends BasicDirector
}
}
// documentation inherited
override public function clientDidLogoff (event :ClientEvent) :void
{
super.clientDidLogoff(event);
// clear out our business
clearScene();
_scache.clear();
_pendingData = null;
_previousSceneId = -1;
_sservice = null;
}
/**
* Issues the scene move request using information from the supplied pending data.
*/
protected function sendMoveRequest () :void
{
// 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;
if (_pendingData.model != null) {
sceneVers = _pendingData.model.version;
}
// issue a moveTo request
log.info("Issuing moveTo(" + _pendingSceneId + ", " + sceneVers + ").");
_sservice.moveTo(_wctx.getClient(), _pendingSceneId, sceneVers, this);
log.info("Issuing moveTo(" + _pendingData.sceneId + ", " + sceneVers + ").");
_sservice.moveTo(_wctx.getClient(), _pendingData.sceneId, sceneVers, this);
}
/**
* Creates a pending scene move request. Derived classes may wish to extend this data with
* additional information to be tracked during movement between scenes. This is encapsulated so
* that if a scene move requires a switch to a new server, all necessary data can be properly
* tracked during the server switch.
*/
protected function createPendingData () :PendingData
{
return new PendingData();
}
/**
@@ -468,20 +501,6 @@ public class SceneDirector extends BasicDirector
}
}
// 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;
}
// from BasicDirector
override protected function registerServices (client :Client) :void
{
@@ -522,12 +541,9 @@ public class SceneDirector extends BasicDirector
/** 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;
/** Information for the scene for which we have an outstanding moveTo request, or null if we
* have no outstanding request. */
protected var _pendingData :PendingData;
/** The id of the scene we previously occupied. */
protected var _previousSceneId :int = -1;