Fixes for property setting via atomic test-and-set:

- Moved property testing, so that it happens before any propertySet events are
  dispatched. In the previous version, testing happened while processing the
  set event on the server - but since by that time client events have already been 
  sent, it introduced the possibility of short-lived inconsistencies between client 
  and server data models.   

- Introduced a separate EZ API call for test and set - not only does it perform
  the test, but unlike regular set, it does not cache the new value ahead of time. 
  Instead the new value will have to arrive from the server, at some future point.

- Trimmed PropertySetEvent and other handlers back down - they don't need to
  carry any of the test info around, after it's already been performed. Also 
  cut redundant testing on the clients.




git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@195 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
Robert Zubeck
2007-02-19 19:40:09 +00:00
parent e21ad04665
commit 83e02730cf
16 changed files with 183 additions and 123 deletions
@@ -72,7 +72,7 @@ public class GameControlBackend
{
_ctx = ctx;
_ezObj = ezObj;
_gameData = new GameData(setProperty_v2, _ezObj.getUserProps());
_gameData = new GameData(setProperty_v1, _ezObj.getUserProps());
_ezObj.addListener(this);
_ctx.getClient().getClientObject().addListener(_userListener);
@@ -136,7 +136,8 @@ public class GameControlBackend
o["gameData"] = _gameData;
// functions
o["setProperty_v2"] = setProperty_v2;
o["setProperty_v1"] = setProperty_v1;
o["testAndSetProperty_v1"] = testAndSetProperty_v1;
o["mergeCollection_v1"] = mergeCollection_v1;
o["setTicker_v1"] = setTicker_v1;
o["sendChat_v1"] = sendChat_v1;
@@ -163,20 +164,33 @@ public class GameControlBackend
o["getPlayers_v1"] = getPlayers_v1;
}
public function setProperty_v2 (
propName :String, value :Object, index :int, testAndSet :Boolean) :void
public function setProperty_v1 (
propName :String, value :Object, index :int) :void
{
validatePropertyChange(propName, value, index);
var encoded :Object = EZObjectMarshaller.encode(value, (index == -1));
_ezObj.ezGameService.setProperty(
_ctx.getClient(), propName, encoded, index, testAndSet,
createLoggingConfirmListener("setProperty"));
_ctx.getClient(), propName, encoded, index,
false, null, createLoggingConfirmListener("setProperty"));
// set it immediately in the game object
_ezObj.applyPropertySet(propName, value, index, testAndSet);
_ezObj.applyPropertySet(propName, value, index);
}
public function testAndSetProperty_v1 (
propName :String, value :Object, testValue :Object, index :int) :void
{
validatePropertyChange(propName, value, index);
var encodedValue :Object = EZObjectMarshaller.encode(value, (index == -1));
var encodedTestValue :Object = EZObjectMarshaller.encode(testValue, (index == -1));
_ezObj.ezGameService.setProperty(
_ctx.getClient(), propName, encodedValue, index,
true, encodedTestValue, createLoggingConfirmListener("setProperty"));
}
public function mergeCollection_v1 (
srcColl :String, intoColl :String) :void
{