diff --git a/src/java/com/threerings/presents/client/ClientDObjectMgr.java b/src/java/com/threerings/presents/client/ClientDObjectMgr.java index 64413df6c..6c9e3c725 100644 --- a/src/java/com/threerings/presents/client/ClientDObjectMgr.java +++ b/src/java/com/threerings/presents/client/ClientDObjectMgr.java @@ -1,5 +1,5 @@ // -// $Id: ClientDObjectMgr.java,v 1.2 2001/06/11 17:44:04 mdb Exp $ +// $Id: ClientDObjectMgr.java,v 1.3 2001/06/13 05:17:54 mdb Exp $ package com.threerings.cocktail.cher.client; @@ -53,9 +53,6 @@ public class ClientDObjectMgr public void unsubscribeFromObject (int oid, Subscriber target) { queueAction(oid, target, false); - - // forward an unsubscribe request to the server - _comm.postMessage(new UnsubscribeRequest(oid)); } protected void queueAction (int oid, Subscriber target, boolean subscribe) @@ -78,6 +75,17 @@ public class ClientDObjectMgr _comm.postMessage(new ForwardEventRequest(tevent)); } + // inherit documentation from the interface + public void removedLastSubscriber (DObject obj) + { + // if object has no subscribers, we no longer need to proxy it; + // first remove it from the object table + _ocache.remove(obj.getOid()); + + // then ship off an unsubscribe message to the server + _comm.postMessage(new UnsubscribeRequest(obj.getOid())); + } + /** * Called by the communicator when a downstream message arrives from * the network layer. We queue it up for processing and request some @@ -141,6 +149,9 @@ public class ClientDObjectMgr "object [event=" + event + "]."); return; } + + // have the object pass this event on to its subscribers + target.notifySubscribers(event); } /** @@ -165,6 +176,9 @@ public class ClientDObjectMgr for (int i = 0; i < req.targets.size(); i++) { Subscriber target = (Subscriber)req.targets.get(i); + // add them as a subscriber + obj.addSubscriber(target); + // and let them know that the object is in target.objectAvailable(obj); } } diff --git a/src/java/com/threerings/presents/dobj/DObject.java b/src/java/com/threerings/presents/dobj/DObject.java index 11d3a37ac..07fb8ef15 100644 --- a/src/java/com/threerings/presents/dobj/DObject.java +++ b/src/java/com/threerings/presents/dobj/DObject.java @@ -1,11 +1,13 @@ // -// $Id: DObject.java,v 1.10 2001/06/12 02:57:30 mdb Exp $ +// $Id: DObject.java,v 1.11 2001/06/13 05:17:55 mdb Exp $ package com.threerings.cocktail.cher.dobj; import java.lang.reflect.Field; import java.util.ArrayList; +import com.threerings.cocktail.cher.Log; + /** * The distributed object forms the foundation of the cocktail system. All * information shared among users of the system is done via distributed @@ -118,7 +120,13 @@ public class DObject */ public void removeSubscriber (Subscriber sub) { - _subscribers.remove(sub); + if (_subscribers.remove(sub)) { + // if we removed something, check to see if we just removed + // the last subscriber from our list + if (_subscribers.size() == 0) { + _mgr.removedLastSubscriber(this); + } + } } /** @@ -163,6 +171,9 @@ public class DObject */ public void notifySubscribers (DEvent event) { + Log.info("Dispatching event to " + _subscribers.size() + + " subscribers: " + event); + for (int i = 0; i < _subscribers.size(); i++) { Subscriber sub = (Subscriber)_subscribers.get(i); // notify the subscriber @@ -170,6 +181,12 @@ public class DObject // if they return false, we need to remove them from the // subscriber list _subscribers.remove(i--); + + // if we just removed our last subscriber, we need to let + // the omgr know about it + if (_subscribers.size() == 0) { + _mgr.removedLastSubscriber(this); + } } } } diff --git a/src/java/com/threerings/presents/dobj/DObjectManager.java b/src/java/com/threerings/presents/dobj/DObjectManager.java index 425acf633..97ef1b71c 100644 --- a/src/java/com/threerings/presents/dobj/DObjectManager.java +++ b/src/java/com/threerings/presents/dobj/DObjectManager.java @@ -1,5 +1,5 @@ // -// $Id: DObjectManager.java,v 1.5 2001/06/09 23:39:04 mdb Exp $ +// $Id: DObjectManager.java,v 1.6 2001/06/13 05:17:55 mdb Exp $ package com.threerings.cocktail.cher.dobj; @@ -76,4 +76,12 @@ public interface DObjectManager * @param event The event to be dispatched. */ public void postEvent (DEvent event); + + /** + * When a distributed object removes its last subscriber, it will call + * this function to let the object manager know. The manager might + * then choose to flush this object from the system or unregister from + * some upstream manager whose object it was proxying, for example. + */ + public void removedLastSubscriber (DObject obj); } diff --git a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java index fad669009..19838fd3a 100644 --- a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java +++ b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java @@ -1,5 +1,5 @@ // -// $Id: PresentsDObjectMgr.java,v 1.5 2001/06/09 23:39:04 mdb Exp $ +// $Id: PresentsDObjectMgr.java,v 1.6 2001/06/13 05:17:55 mdb Exp $ package com.threerings.cocktail.cher.server; @@ -68,6 +68,12 @@ public class CherDObjectMgr implements DObjectManager _evqueue.append(event); } + // inherit documentation from the interface + public void removedLastSubscriber (DObject obj) + { + // nothing to do here, our objects live forever! + } + /** * Runs the dobjmgr event loop until it is requested to exit. This * should be called from the main application thread. diff --git a/tests/src/java/com/threerings/presents/client/TestClient.java b/tests/src/java/com/threerings/presents/client/TestClient.java index cf5ef812d..19c350b49 100644 --- a/tests/src/java/com/threerings/presents/client/TestClient.java +++ b/tests/src/java/com/threerings/presents/client/TestClient.java @@ -1,5 +1,5 @@ // -// $Id: TestClient.java,v 1.3 2001/06/09 23:39:03 mdb Exp $ +// $Id: TestClient.java,v 1.4 2001/06/13 05:17:55 mdb Exp $ package com.threerings.cocktail.cher.client.test; @@ -79,7 +79,10 @@ public class TestClient public boolean handleEvent (DEvent event, DObject target) { Log.info("Got event [event=" + event + ", target=" + target + "]."); - return true; + // dispatch a second event + ((TestObject)target).setBar("rofl!"); + // unsubscribe to the object to make sure we don't get the event + return false; } public static void main (String[] args)