- The server should apply the property set immediately, not wait until
the event trundles through the queue, especially since the 'test' was being done immediately. - Simplified some stuff on the server. - Fixed up the test, as EZgame arrays will auto-grow. - Do not set the property immediately on the client! Dangerz! We will add a new function for that, so that set() behaves like testAndSet() without the test, and set() behaves like setImmediate() without the immediate. (And there's no such thing as test and set immediately.) git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@196 c613c5cb-e716-0410-b11b-feb51c14d237
This commit is contained in:
@@ -173,9 +173,6 @@ public class GameControlBackend
|
||||
_ezObj.ezGameService.setProperty(
|
||||
_ctx.getClient(), propName, encoded, index,
|
||||
false, null, createLoggingConfirmListener("setProperty"));
|
||||
|
||||
// set it immediately in the game object
|
||||
_ezObj.applyPropertySet(propName, value, index);
|
||||
}
|
||||
|
||||
public function testAndSetProperty_v1 (
|
||||
|
||||
@@ -34,6 +34,7 @@ public class PropertySetEvent extends NamedEvent
|
||||
// from abstract DEvent
|
||||
override public function applyToObject (target :DObject) :Boolean
|
||||
{
|
||||
// since we're in actionscript, we're always on the client
|
||||
_oldValue =
|
||||
EZGameObject(target).applyPropertySet(_name, _data, _index);
|
||||
return true;
|
||||
|
||||
@@ -9,6 +9,8 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.samskivert.util.ObjectUtil;
|
||||
|
||||
import com.threerings.util.Name;
|
||||
|
||||
import com.threerings.io.ObjectInputStream;
|
||||
@@ -85,6 +87,8 @@ public class EZGameObject extends GameObject
|
||||
|
||||
/**
|
||||
* Called by PropertySetEvent to effect the property update.
|
||||
*
|
||||
* @return the old value.
|
||||
*/
|
||||
public Object applyPropertySet (String propName, Object data, int index)
|
||||
{
|
||||
@@ -123,6 +127,7 @@ public class EZGameObject extends GameObject
|
||||
|
||||
} else if (data != null) {
|
||||
_props.put(propName, data);
|
||||
|
||||
} else {
|
||||
_props.remove(propName);
|
||||
}
|
||||
@@ -131,44 +136,70 @@ public class EZGameObject extends GameObject
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares whether the old value and the test value are the same.
|
||||
* Test the specified property against the specified value. This is
|
||||
* called on the server to validate testAndSet events.
|
||||
*
|
||||
* @return true if the property contains the value specified.
|
||||
*/
|
||||
public boolean testProperty (
|
||||
String propName, int index, boolean testAndSet, Object testValue)
|
||||
String propName, int index, Object testValue)
|
||||
{
|
||||
boolean result = false;
|
||||
if (! isOnServer() || // if this is the client, don't test - only test on server
|
||||
! testAndSet) // test was not requested
|
||||
{
|
||||
result = true;
|
||||
|
||||
} else {
|
||||
Object oldValue = _props.get(propName);
|
||||
|
||||
// test if both are null
|
||||
if (testValue == null || oldValue == null) {
|
||||
result = (oldValue == testValue);
|
||||
|
||||
} else {
|
||||
Object curValue = _props.get(propName);
|
||||
|
||||
// if the old value is an array, extract the appropriate element first
|
||||
if (index >= 0 && oldValue instanceof byte[][])
|
||||
{
|
||||
byte[][] arr = (byte[][]) oldValue;
|
||||
if (arr != null) { oldValue = arr[index]; }
|
||||
if (curValue != null && index >= 0) {
|
||||
// see if there's an array there already
|
||||
if (isOnServer()) {
|
||||
if (curValue instanceof byte[][]) {
|
||||
byte[][] curArray = (byte[][]) curValue;
|
||||
if (curArray.length > index) {
|
||||
curValue = curArray[index];
|
||||
|
||||
} else {
|
||||
// the index is out of range, but since we auto-grow,
|
||||
// we treat it like null
|
||||
curValue = null;
|
||||
}
|
||||
|
||||
} else {
|
||||
// curData is not an array, so the test fails
|
||||
return false;
|
||||
}
|
||||
|
||||
// now perform byte comparison
|
||||
if (oldValue instanceof byte[] &&
|
||||
testValue instanceof byte[])
|
||||
{
|
||||
result = Arrays.equals (
|
||||
(byte[]) oldValue, (byte[]) testValue);
|
||||
|
||||
} else {
|
||||
if (curValue instanceof Object[]) {
|
||||
Object[] curArray = (Object[]) curValue;
|
||||
if (curArray.length > index) {
|
||||
curValue = curArray[index];
|
||||
|
||||
} else {
|
||||
// the index is out of range, but since we auto-grow,
|
||||
// we treat it like null
|
||||
curValue = null;
|
||||
}
|
||||
|
||||
} else {
|
||||
// curData is not an array, so the test fails
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
// let's test the values!
|
||||
if ((testValue instanceof Object[]) && (curValue instanceof Object[])) {
|
||||
// testing an array against another array
|
||||
return Arrays.deepEquals((Object[]) testValue, (Object[]) curValue);
|
||||
|
||||
} else if ((testValue instanceof byte[]) && (curValue instanceof byte[])) {
|
||||
// testing a property against another property (may have
|
||||
// been from inside an array)
|
||||
return Arrays.equals((byte[]) testValue, (byte[]) curValue);
|
||||
|
||||
// TODO: other array types must be tested if we're on the client
|
||||
// ??
|
||||
} else {
|
||||
// will catch null == null...
|
||||
return ObjectUtil.equals(testValue, curValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,11 +30,12 @@ public class PropertySetEvent extends NamedEvent
|
||||
* Create a PropertySetEvent.
|
||||
*/
|
||||
public PropertySetEvent (
|
||||
int targetOid, String propName, Object value, int index)
|
||||
int targetOid, String propName, Object value, int index, Object oldValue)
|
||||
{
|
||||
super(targetOid, propName);
|
||||
_data = value;
|
||||
_index = index;
|
||||
_oldValue = oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,7 +69,10 @@ public class PropertySetEvent extends NamedEvent
|
||||
if (!ezObj.isOnServer()) {
|
||||
_data = EZObjectMarshaller.decode(_data);
|
||||
}
|
||||
_oldValue = ezObj.applyPropertySet(_name, _data, _index);
|
||||
if (_oldValue == UNSET_OLD_VALUE) {
|
||||
// only apply the property change if we haven't already
|
||||
_oldValue = ezObj.applyPropertySet(_name, _data, _index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -95,5 +99,5 @@ public class PropertySetEvent extends NamedEvent
|
||||
protected Object _data;
|
||||
|
||||
/** The old value. */
|
||||
protected transient Object _oldValue;
|
||||
protected transient Object _oldValue = UNSET_OLD_VALUE;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,10 @@ public class EZGameManager extends GameManager
|
||||
throws InvocationException
|
||||
{
|
||||
validateUser(caller);
|
||||
setProperty(propName, data, index, testAndSet, testValue);
|
||||
if (testAndSet && !_gameObj.testProperty(propName, index, testValue)) {
|
||||
return; // the test failed: do not set the property
|
||||
}
|
||||
setProperty(propName, data, index);
|
||||
}
|
||||
|
||||
// from EZGameProvider
|
||||
@@ -221,7 +224,7 @@ public class EZGameManager extends GameManager
|
||||
}
|
||||
|
||||
if (playerId == 0) {
|
||||
setProperty(msgOrPropName, result, -1, false, null);
|
||||
setProperty(msgOrPropName, result, -1);
|
||||
|
||||
} else {
|
||||
sendPrivateMessage(playerId, msgOrPropName, result);
|
||||
@@ -402,15 +405,12 @@ public class EZGameManager extends GameManager
|
||||
* Helper method to post a property set event.
|
||||
*/
|
||||
protected void setProperty (
|
||||
String propName, Object value, int index,
|
||||
boolean testAndSet, Object testValue)
|
||||
String propName, Object value, int index)
|
||||
{
|
||||
if (_gameObj.testProperty (propName, index, testAndSet, testValue))
|
||||
{
|
||||
_gameObj.postEvent(
|
||||
new PropertySetEvent(
|
||||
_gameObj.getOid(), propName, value, index));
|
||||
}
|
||||
// apply the property set immediately
|
||||
Object oldValue = _gameObj.applyPropertySet(propName, value, index);
|
||||
_gameObj.postEvent(new PropertySetEvent(
|
||||
_gameObj.getOid(), propName, value, index, oldValue));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user