diff --git a/src/main/java/com/threerings/crowd/data/PlaceObject.java b/src/main/java/com/threerings/crowd/data/PlaceObject.java index a5bda449d..3d3d0ce82 100644 --- a/src/main/java/com/threerings/crowd/data/PlaceObject.java +++ b/src/main/java/com/threerings/crowd/data/PlaceObject.java @@ -154,7 +154,7 @@ public class PlaceObject extends DObject @Generated(value={"com.threerings.presents.tools.GenDObjectTask"}) public void addToOccupants (int oid) { - requestOidAdd(OCCUPANTS, oid); + requestOidAdd(OCCUPANTS, occupants, oid); } /** @@ -165,7 +165,7 @@ public class PlaceObject extends DObject @Generated(value={"com.threerings.presents.tools.GenDObjectTask"}) public void removeFromOccupants (int oid) { - requestOidRemove(OCCUPANTS, oid); + requestOidRemove(OCCUPANTS, occupants, oid); } /** diff --git a/src/main/java/com/threerings/presents/dobj/DObject.java b/src/main/java/com/threerings/presents/dobj/DObject.java index 669b435a8..2386fec8e 100644 --- a/src/main/java/com/threerings/presents/dobj/DObject.java +++ b/src/main/java/com/threerings/presents/dobj/DObject.java @@ -896,19 +896,28 @@ public class DObject /** * Calls by derived instances when an oid adder method was called. */ - protected void requestOidAdd (String name, int oid) + protected void requestOidAdd (String name, OidList list, int oid) { - // dispatch an object added event - postEvent(new ObjectAddedEvent(_oid, name, oid)); + // if we're on the authoritative server, we update the set immediately + boolean applyImmediately = isAuthoritative(); + if (applyImmediately) { + list.add(oid); + } + postEvent(new ObjectAddedEvent(_oid, name, oid, applyImmediately)); } /** * Calls by derived instances when an oid remover method was called. */ - protected void requestOidRemove (String name, int oid) + protected void requestOidRemove (String name, OidList list, int oid) { + // if we're on the authoritative server, we update the set immediately + boolean applyImmediately = isAuthoritative(); + if (applyImmediately) { + list.remove(oid); + } // dispatch an object removed event - postEvent(new ObjectRemovedEvent(_oid, name, oid)); + postEvent(new ObjectRemovedEvent(_oid, name, oid, applyImmediately)); } /** @@ -917,13 +926,12 @@ public class DObject protected void requestEntryAdd (String name, DSet set, T entry) { // if we're on the authoritative server, we update the set immediately - boolean alreadyApplied = false; - if (_omgr != null && _omgr.isManager(this)) { + boolean applyImmediately = isAuthoritative(); + if (applyImmediately) { set.add(entry); - alreadyApplied = true; } // dispatch an entry added event - postEvent(new EntryAddedEvent(_oid, name, entry, alreadyApplied)); + postEvent(new EntryAddedEvent(_oid, name, entry, applyImmediately)); } /** @@ -934,7 +942,7 @@ public class DObject { // if we're on the authoritative server, we update the set immediately T oldEntry = null; - if (_omgr != null && _omgr.isManager(this)) { + if (isAuthoritative()) { oldEntry = set.removeKey(key); if (oldEntry == null) { log.warning("Requested to remove non-element", "set", name, "key", key, @@ -961,7 +969,7 @@ public class DObject { // if we're on the authoritative server, we update the set immediately T oldEntry = null; - if (_omgr != null && _omgr.isManager(this)) { + if (isAuthoritative()) { oldEntry = set.update(entry); if (oldEntry == null) { log.warning("Set update had no old entry", "name", name, "entry", entry, @@ -972,6 +980,11 @@ public class DObject postEvent(new EntryUpdatedEvent(_oid, name, entry, oldEntry, transport)); } + protected boolean isAuthoritative () + { + return _omgr != null && _omgr.isManager(this); + } + /** * Returns the {@link Accessor} for the field with the specified name throws an {@link * IllegalArgumentException}. diff --git a/src/main/java/com/threerings/presents/dobj/ObjectAddedEvent.java b/src/main/java/com/threerings/presents/dobj/ObjectAddedEvent.java index b1941bb80..7f0541578 100644 --- a/src/main/java/com/threerings/presents/dobj/ObjectAddedEvent.java +++ b/src/main/java/com/threerings/presents/dobj/ObjectAddedEvent.java @@ -42,9 +42,15 @@ public class ObjectAddedEvent extends NamedEvent * @param oid the oid to add to the oid list attribute. */ public ObjectAddedEvent (int targetOid, String name, int oid) + { + this(targetOid, name, oid, false); + } + + protected ObjectAddedEvent (int targetOid, String name, int oid, boolean alreadyApplied) { super(targetOid, name); _oid = oid; + _alreadyApplied = alreadyApplied; } /** @@ -63,12 +69,20 @@ public class ObjectAddedEvent extends NamedEvent return _oid; } + @Override + public boolean alreadyApplied () + { + return _alreadyApplied; + } + @Override public boolean applyToObject (DObject target) throws ObjectAccessException { - OidList list = (OidList)target.getAttribute(_name); - list.add(_oid); + if (!_alreadyApplied) { + OidList list = (OidList)target.getAttribute(_name); + list.add(_oid); + } return true; } @@ -89,4 +103,5 @@ public class ObjectAddedEvent extends NamedEvent } protected int _oid; + protected transient boolean _alreadyApplied; } diff --git a/src/main/java/com/threerings/presents/dobj/ObjectRemovedEvent.java b/src/main/java/com/threerings/presents/dobj/ObjectRemovedEvent.java index 38162b733..b08a4d9b7 100644 --- a/src/main/java/com/threerings/presents/dobj/ObjectRemovedEvent.java +++ b/src/main/java/com/threerings/presents/dobj/ObjectRemovedEvent.java @@ -43,9 +43,15 @@ public class ObjectRemovedEvent extends NamedEvent * @param oid the oid to remove from the oid list attribute. */ public ObjectRemovedEvent (int targetOid, String name, int oid) + { + this (targetOid, name, oid, false); + } + + protected ObjectRemovedEvent (int targetOid, String name, int oid, boolean alreadyApplied) { super(targetOid, name); _oid = oid; + _alreadyApplied = alreadyApplied; } /** @@ -64,12 +70,20 @@ public class ObjectRemovedEvent extends NamedEvent return _oid; } + @Override + public boolean alreadyApplied () + { + return _alreadyApplied; + } + @Override public boolean applyToObject (DObject target) throws ObjectAccessException { - OidList list = (OidList)target.getAttribute(_name); - list.remove(_oid); + if (!_alreadyApplied) { + OidList list = (OidList)target.getAttribute(_name); + list.remove(_oid); + } return true; } @@ -90,4 +104,5 @@ public class ObjectRemovedEvent extends NamedEvent } protected int _oid; + protected transient boolean _alreadyApplied; } diff --git a/src/main/resources/com/threerings/presents/tools/dobject_oidlist.tmpl b/src/main/resources/com/threerings/presents/tools/dobject_oidlist.tmpl index 3d80486ac..06387d7a3 100644 --- a/src/main/resources/com/threerings/presents/tools/dobject_oidlist.tmpl +++ b/src/main/resources/com/threerings/presents/tools/dobject_oidlist.tmpl @@ -6,7 +6,7 @@ {{generated}} public void addTo{{upfield}} (int oid) { - requestOidAdd({{capfield}}, oid); + requestOidAdd({{capfield}}, {{field}}, oid); } /** @@ -17,5 +17,5 @@ {{generated}} public void removeFrom{{upfield}} (int oid) { - requestOidRemove({{capfield}}, oid); + requestOidRemove({{capfield}}, {{field}}, oid); } diff --git a/src/test/java/com/threerings/presents/data/TestObject.java b/src/test/java/com/threerings/presents/data/TestObject.java index 94dccb3e6..ac9057534 100644 --- a/src/test/java/com/threerings/presents/data/TestObject.java +++ b/src/test/java/com/threerings/presents/data/TestObject.java @@ -183,7 +183,7 @@ public class TestObject extends DObject @Generated(value={"com.threerings.presents.tools.GenDObjectTask"}) public void addToList (int oid) { - requestOidAdd(LIST, oid); + requestOidAdd(LIST, list, oid); } /** @@ -194,7 +194,7 @@ public class TestObject extends DObject @Generated(value={"com.threerings.presents.tools.GenDObjectTask"}) public void removeFromList (int oid) { - requestOidRemove(LIST, oid); + requestOidRemove(LIST, list, oid); } /**