Finally got around to making compound events actually stick together until

they arrive at the client. Mmm... network efficiency++.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@2396 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2003-04-10 17:48:42 +00:00
parent 2a554f1569
commit 36624d96ac
6 changed files with 177 additions and 144 deletions
@@ -1,5 +1,5 @@
//
// $Id: PresentsClient.java,v 1.53 2003/03/30 21:04:18 mdb Exp $
// $Id: PresentsClient.java,v 1.54 2003/04/10 17:48:42 mdb Exp $
package com.threerings.presents.server;
@@ -15,9 +15,8 @@ import com.threerings.presents.data.ClientObject;
import com.threerings.presents.dobj.DEvent;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.EventListener;
import com.threerings.presents.dobj.ObjectAccessException;
import com.threerings.presents.dobj.Subscriber;
import com.threerings.presents.dobj.ProxySubscriber;
import com.threerings.presents.net.BootstrapData;
import com.threerings.presents.net.BootstrapNotification;
@@ -54,8 +53,7 @@ import com.threerings.presents.server.net.MessageHandler;
* conmgr thread and therefore also need not be synchronized.
*/
public class PresentsClient
implements Subscriber, EventListener, MessageHandler,
ClientResolutionListener
implements ProxySubscriber, MessageHandler, ClientResolutionListener
{
/** Used by {@link #setUsername} to report success or failure. */
public static interface UserChangeListener
@@ -416,7 +414,6 @@ public class PresentsClient
{
DObject object = (DObject)_subscrips.remove(oid);
if (object != null) {
object.removeListener(this);
object.removeSubscriber(this);
} else {
Log.warning("Requested to unmap non-existent subscription " +
@@ -435,7 +432,6 @@ public class PresentsClient
DObject object = (DObject)enum.next();
// Log.info("Clearing subscription [client=" + this +
// ", obj=" + object.getOid() + "].");
object.removeListener(this);
object.removeSubscriber(this);
}
}
@@ -649,8 +645,6 @@ public class PresentsClient
// queue up an object response
Connection conn = getConnection();
if (conn != null) {
// add ourselves as an event listener
object.addListener(this);
// pass the successful subscrip on to the client
conn.postMessage(new ObjectResponse(object));
// make a note of this new subscription
@@ -1,5 +1,5 @@
//
// $Id: PresentsDObjectMgr.java,v 1.30 2003/03/31 04:11:24 mdb Exp $
// $Id: PresentsDObjectMgr.java,v 1.31 2003/04/10 17:48:42 mdb Exp $
package com.threerings.presents.server;
@@ -23,7 +23,7 @@ import com.threerings.presents.dobj.*;
* server. By virtue of running on the server, it manages its objects
* directly rather than managing proxies of objects which is what is done
* on the client. Thus it simply queues up events and dispatches them to
* subscribers.
* listeners.
*
* <p> The server object manager is meant to run on the main thread of the
* server application and thus provides a method to be invoked by the
@@ -180,18 +180,9 @@ public class PresentsDObjectMgr
}
} else if (unit instanceof CompoundEvent) {
// if this is a compound event, we need to apply each
// event indivdually
CompoundEvent event = (CompoundEvent)unit;
List events = event.getEvents();
int ecount = events.size();
for (int i = 0; i < ecount; i++) {
processEvent((DEvent)events.get(i));
}
processCompoundEvent((CompoundEvent)unit);
} else {
// otherwise it's a regular event, so do the standard
// processing
processEvent((DEvent)unit);
}
@@ -217,9 +208,45 @@ public class PresentsDObjectMgr
Log.info("DOMGR exited.");
}
/**
* Performs the processing associated with a compound event, notifying
* listeners and the like.
*/
protected void processCompoundEvent (CompoundEvent event)
{
List events = event.getEvents();
int ecount = events.size();
// look up the target object
DObject target = (DObject)_objects.get(event.getTargetOid());
if (target == null) {
Log.debug("Compound event target no longer exists " +
"[event=" + event + "].");
return;
}
// check the permissions on all of the events
for (int ii = 0; ii < ecount; ii++) {
DEvent sevent = (DEvent)events.get(ii);
if (!target.checkPermissions(sevent)) {
Log.warning("Event failed permissions check " +
"[event=" + sevent + ", target=" + target + "].");
return;
}
}
// dispatch the events
for (int ii = 0; ii < ecount; ii++) {
dispatchEvent((DEvent)events.get(ii), target);
}
// always notify proxies of compound events
target.notifyProxies(event);
}
/**
* Performs the processing associated with an event, notifying
* subscribers and the like.
* listeners and the like.
*/
protected void processEvent (DEvent event)
{
@@ -244,22 +271,36 @@ public class PresentsDObjectMgr
return;
}
if (dispatchEvent(event, target)) {
// unless requested not to, notify any proxies
target.notifyProxies(event);
}
}
/**
* Dispatches an event after the target object has been resolved and
* the permissions have been checked. This is used by {@link
* #processEvent} and {@link #processCompoundEvent}.
*
* @return the value returned by {@link DEvent#applyToObject}.
*/
protected boolean dispatchEvent (DEvent event, DObject target)
{
boolean notify = true; // assume always notify
try {
// do any internal management necessary based on this
// event
// do any internal management necessary based on this event
Method helper = (Method)_helpers.get(event.getClass());
if (helper != null) {
// invoke the helper method
Object rv =
helper.invoke(this, new Object[] { event, target });
Object rv = helper.invoke(this, new Object[] { event, target });
// if helper returns false, we abort event processing
if (!((Boolean)rv).booleanValue()) {
return;
return false;
}
}
// everything's good so far, apply the event to the object
boolean notify = event.applyToObject(target);
notify = event.applyToObject(target);
// if the event returns false from applyToObject, this
// means it's a silent event and we shouldn't notify the
@@ -276,6 +317,7 @@ public class PresentsDObjectMgr
// track the number of events dispatched
++_eventCount;
return true;
}
/**