Apply additions and removals to OidList fields on DObjects immediately on the server to make it

match DSets and setting attributes.  With the old behvaior, if a client subscribed to a DObject and
modified an OidList on it in a single pass, it could miss the modification.  The DObject is
serialized immediately when the server gets the subscription request, but events aren't sent for
that subscription till it's processed the next time the omgr queue comes round.



git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6420 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Charlie Groves
2011-01-06 09:15:47 +00:00
parent b4af8a0384
commit 8f8a50c9e8
6 changed files with 64 additions and 21 deletions
@@ -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 <T extends DSet.Entry> void requestEntryAdd (String name, DSet<T> 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<T>(_oid, name, entry, alreadyApplied));
postEvent(new EntryAddedEvent<T>(_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<T>(_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}.