diff --git a/src/java/com/threerings/crowd/chat/client/ChatDirector.java b/src/java/com/threerings/crowd/chat/client/ChatDirector.java index 566e46dec..8a47dd74d 100644 --- a/src/java/com/threerings/crowd/chat/client/ChatDirector.java +++ b/src/java/com/threerings/crowd/chat/client/ChatDirector.java @@ -1,5 +1,5 @@ // -// $Id: ChatDirector.java,v 1.10 2001/10/11 04:07:51 mdb Exp $ +// $Id: ChatDirector.java,v 1.11 2001/10/12 00:03:02 mdb Exp $ package com.threerings.crowd.chat; @@ -19,7 +19,8 @@ import com.threerings.crowd.util.CrowdContext; * messaging. */ public class ChatDirector - implements LocationObserver, Subscriber, InvocationReceiver, ChatCodes + implements LocationObserver, MessageListener, InvocationReceiver, + ChatCodes { /** * Creates a chat director and initializes it with the supplied @@ -110,54 +111,39 @@ public class ChatDirector return ChatService.tell(_ctx.getClient(), target, message, this); } + // documentation inherited public boolean locationMayChange (int placeId) { // we accept all location change requests return true; } + // documentation inherited public void locationDidChange (PlaceObject place) { if (_place != null) { - // unsubscribe from our old object - _place.removeSubscriber(this); + // unlisten to our old object + _place.removeListener(this); } - // subscribe to the new object + // listen to the new object _place = place; - _place.addSubscriber(this); + _place.addListener(this); } + // documentation inherited public void locationChangeFailed (int placeId, String reason) { // nothing we care about } - public void objectAvailable (DObject object) + // documentation inherited + public void messageReceived (MessageEvent event) { - // nothing to do here - } - - public void requestFailed (int oid, ObjectAccessException cause) - { - // nothing to do here - } - - public boolean handleEvent (DEvent event, DObject target) - { - // we only care about message events - if (!(event instanceof MessageEvent)) { - return true; - } - - // and only those of proper name - MessageEvent mevt = (MessageEvent)event; - String name = mevt.getName(); + String name = event.getName(); if (name.equals(ChatService.SPEAK_NOTIFICATION)) { - handleSpeakMessage(mevt.getArgs()); + handleSpeakMessage(event.getArgs()); } - - return true; } /** @@ -216,6 +202,5 @@ public class ChatDirector protected CrowdContext _ctx; protected PlaceObject _place; - protected ArrayList _displays = new ArrayList(); } diff --git a/src/java/com/threerings/crowd/client/LocationDirector.java b/src/java/com/threerings/crowd/client/LocationDirector.java index cdd28bf49..9294ead09 100644 --- a/src/java/com/threerings/crowd/client/LocationDirector.java +++ b/src/java/com/threerings/crowd/client/LocationDirector.java @@ -1,5 +1,5 @@ // -// $Id: LocationDirector.java,v 1.11 2001/10/11 04:07:51 mdb Exp $ +// $Id: LocationDirector.java,v 1.12 2001/10/12 00:03:02 mdb Exp $ package com.threerings.crowd.client; @@ -201,11 +201,6 @@ public class LocationDirector "object; all has gone horribly wrong" + "[cause=" + cause + "]."); } - - public boolean handleEvent (DEvent event, DObject target) - { - return false; - } }; int cloid = client.getClientOid(); client.getDObjectManager().subscribeToObject(cloid, sub); @@ -326,12 +321,6 @@ public class LocationDirector } } - public boolean handleEvent (DEvent event, DObject target) - { - // nothing to do here, but remain subscribed - return true; - } - protected void notifyFailure (int placeId, String reason) { for (int i = 0; i < _observers.size(); i++) { diff --git a/src/java/com/threerings/crowd/client/OccupantManager.java b/src/java/com/threerings/crowd/client/OccupantManager.java index be222d25d..5c7d06bcb 100644 --- a/src/java/com/threerings/crowd/client/OccupantManager.java +++ b/src/java/com/threerings/crowd/client/OccupantManager.java @@ -1,5 +1,5 @@ // -// $Id: OccupantManager.java,v 1.6 2001/10/11 04:07:51 mdb Exp $ +// $Id: OccupantManager.java,v 1.7 2001/10/12 00:03:02 mdb Exp $ package com.threerings.crowd.client; @@ -36,7 +36,7 @@ import com.threerings.crowd.util.CrowdContext; * what's in the cache. */ public class OccupantManager - implements LocationObserver, Subscriber + implements LocationObserver, OidListListener { /** * Constructs a new occupant manager with the supplied context. @@ -73,16 +73,16 @@ public class OccupantManager // inherit documentation public void locationDidChange (PlaceObject place) { - // unsubscribe from the old place object if there was one + // unlisten to the old place object if there was one if (_place != null) { - _place.removeSubscriber(this); + _place.removeListener(this); // clear out the occupant cache for the previous location _ocache.clear(); } - // subscribe to the new one + // listen to the new one _place = place; - _place.addSubscriber(this); + _place.addListener(this); // cache the occupant info for the occupants in this room Iterator iter = _place.occupantInfo.elements(); @@ -98,43 +98,17 @@ public class OccupantManager // nothing to do here either } - // inherit documentation - public void objectAvailable (DObject object) - { - // nothing doing - } - - // inherit documentation - public void requestFailed (int oid, ObjectAccessException cause) - { - // nothing doing - } - - // inherit documentation - public boolean handleEvent (DEvent event, DObject target) - { - // we care about occupant added and removed events only - if (event instanceof ObjectAddedEvent) { - ObjectAddedEvent oe = (ObjectAddedEvent)event; - if (oe.getName().equals(PlaceObject.OCCUPANTS)) { - handleOccupantAdded(oe.getOid()); - } - - } else if (event instanceof ObjectRemovedEvent) { - ObjectRemovedEvent oe = (ObjectRemovedEvent)event; - if (oe.getName().equals(PlaceObject.OCCUPANTS)) { - handleOccupantRemoved(oe.getOid()); - } - } - - return true; - } - /** * Deals with all of the processing when an occupant shows up. */ - protected void handleOccupantAdded (int bodyOid) + public void objectAdded (ObjectAddedEvent event) { + // bail if this isn't for the OCCUPANTS field + if (!event.getName().equals(PlaceObject.OCCUPANTS)) { + return; + } + + int bodyOid = event.getOid(); Object key = new Integer(bodyOid); // get the occupant info from the place object @@ -158,8 +132,14 @@ public class OccupantManager /** * Deals with all of the processing when an occupant leaves. */ - protected void handleOccupantRemoved (int bodyOid) + public void objectRemoved (ObjectRemovedEvent event) { + // bail if this isn't for the OCCUPANTS field + if (!event.getName().equals(PlaceObject.OCCUPANTS)) { + return; + } + + int bodyOid = event.getOid(); // see if we have an occupant object for this body OccupantInfo info = (OccupantInfo)_ocache.get(bodyOid); if (info == null) { diff --git a/src/java/com/threerings/crowd/server/PlaceManager.java b/src/java/com/threerings/crowd/server/PlaceManager.java index 51cc0670c..a5db947a9 100644 --- a/src/java/com/threerings/crowd/server/PlaceManager.java +++ b/src/java/com/threerings/crowd/server/PlaceManager.java @@ -1,5 +1,5 @@ // -// $Id: PlaceManager.java,v 1.17 2001/10/11 04:07:51 mdb Exp $ +// $Id: PlaceManager.java,v 1.18 2001/10/12 00:03:02 mdb Exp $ package com.threerings.crowd.server; @@ -28,9 +28,10 @@ import com.threerings.crowd.data.*; *

A derived class is expected to handle initialization, cleanup and * operational functionality via the calldown functions {@link * #didStartup}, {@link #willShutdown}, and {@link #didShutdown} as well - * as through additions to {@link #handleEvent}. + * as through event listeners. */ -public class PlaceManager implements Subscriber +public class PlaceManager + implements MessageListener, OidListListener { /** * Returns a reference to our place configuration object. @@ -101,11 +102,8 @@ public class PlaceManager implements Subscriber // configure the occupant info set plobj.occupantInfo.setElementType(getOccupantInfoClass()); - // we'll want to be included among the place object's subscribers; - // we know that we can call addSubscriber() directly because the - // place manager is doing all of our initialization on the dobjmgr - // thread - plobj.addSubscriber(this); + // we'll need to hear about place object events + plobj.addListener(this); // let our derived classes do their thang didStartup(); @@ -225,47 +223,48 @@ public class PlaceManager implements Subscriber _msghandlers.put(name, handler); } - // nothing doing - public void objectAvailable (DObject object) - { - } - - // nothing doing - public void requestFailed (int oid, ObjectAccessException cause) + /** + * Dispatches message events to registered message handlers. Derived + * classes should probably register message handlers rather than + * override this method directly. + */ + public void messageReceived (MessageEvent event) { + MessageHandler handler = null; + if (_msghandlers != null) { + handler = (MessageHandler)_msghandlers.get(event.getName()); + } + if (handler != null) { + handler.handleEvent(event, _plobj); + } } /** - * Derived classes can override this to handle events, but they must - * be sure to pass unknown events up to their super class. + * Handles occupant arrival into the place. Derived classes may need + * to override this method to handle other oid lists in their derived + * place objects. They should be sure to call + * super.objectAdded if the event is one they don't + * explicitly handle. */ - public boolean handleEvent (DEvent event, DObject target) + public void objectAdded (ObjectAddedEvent event) { - // if this is a message event, see if we have a handler for it - if (event instanceof MessageEvent) { - MessageEvent mevt = (MessageEvent)event; - MessageHandler handler = null; - if (_msghandlers != null) { - handler = (MessageHandler)_msghandlers.get(mevt.getName()); - } - if (handler != null) { - handler.handleEvent(mevt, (PlaceObject)target); - } - - } else if (event instanceof ObjectAddedEvent) { - ObjectAddedEvent oae = (ObjectAddedEvent)event; - if (oae.getName().equals(PlaceObject.OCCUPANTS)) { - bodyEntered(oae.getOid()); - } - - } else if (event instanceof ObjectRemovedEvent) { - ObjectRemovedEvent ore = (ObjectRemovedEvent)event; - if (ore.getName().equals(PlaceObject.OCCUPANTS)) { - bodyLeft(ore.getOid()); - } + if (event.getName().equals(PlaceObject.OCCUPANTS)) { + bodyEntered(event.getOid()); } + } - return true; + /** + * Handles occupant departure from the place. Derived classes may need + * to override this method to handle other oid lists in their derived + * place objects. They should be sure to call + * super.objectRemoved if the event is one they don't + * explicitly handle. + */ + public void objectRemoved (ObjectRemovedEvent event) + { + if (event.getName().equals(PlaceObject.OCCUPANTS)) { + bodyLeft(event.getOid()); + } } /** diff --git a/src/java/com/threerings/crowd/server/PlaceRegistry.java b/src/java/com/threerings/crowd/server/PlaceRegistry.java index d81f1fe9a..ae8da093b 100644 --- a/src/java/com/threerings/crowd/server/PlaceRegistry.java +++ b/src/java/com/threerings/crowd/server/PlaceRegistry.java @@ -1,5 +1,5 @@ // -// $Id: PlaceRegistry.java,v 1.11 2001/10/11 04:07:51 mdb Exp $ +// $Id: PlaceRegistry.java,v 1.12 2001/10/12 00:03:02 mdb Exp $ package com.threerings.crowd.server; @@ -173,13 +173,6 @@ public class PlaceRegistry implements Subscriber ", cause=" + cause + "]."); } - public boolean handleEvent (DEvent event, DObject target) - { - // this shouldn't be called because we don't subscribe to - // anything, we just want to hear about object creation - return false; - } - protected Queue _createq = new Queue(); protected HashIntMap _pmgrs = new HashIntMap(); } diff --git a/src/java/com/threerings/parlor/game/GameController.java b/src/java/com/threerings/parlor/game/GameController.java index d3fb4e0bc..b2fe34dce 100644 --- a/src/java/com/threerings/parlor/game/GameController.java +++ b/src/java/com/threerings/parlor/game/GameController.java @@ -1,5 +1,5 @@ // -// $Id: GameController.java,v 1.7 2001/10/11 21:08:21 mdb Exp $ +// $Id: GameController.java,v 1.8 2001/10/12 00:03:03 mdb Exp $ package com.threerings.parlor.game; @@ -27,7 +27,8 @@ import com.threerings.parlor.util.ParlorContext; * distributed object events. */ public abstract class GameController - extends PlaceController implements Subscriber, GameCodes + extends PlaceController + implements AttributeChangeListener, GameCodes { /** * Initializes this game controller with the game configuration that @@ -51,7 +52,11 @@ public abstract class GameController super.init(ctx, config); } - // documentation inherited + /** + * Adds this controller as a listener to the game object (thus derived + * classes need not do so) and lets the game manager know that we are + * now ready to go. + */ public void willEnterPlace (PlaceObject plobj) { super.willEnterPlace(plobj); @@ -59,8 +64,8 @@ public abstract class GameController // obtain a casted reference _gobj = (GameObject)plobj; - // and add ourselves as a subscriber - _gobj.addSubscriber(this); + // and add ourselves as a listener + _gobj.addListener(this); // finally let the game manager know that we're ready to roll MessageEvent mevt = new MessageEvent( @@ -68,13 +73,16 @@ public abstract class GameController _ctx.getDObjectManager().postEvent(mevt); } - // documentation inherited + /** + * Removes our listener registration from the game object and cleans + * house. + */ public void didLeavePlace (PlaceObject plobj) { - super.willEnterPlace(plobj); + super.didLeavePlace(plobj); - // unsubscribe from the game object - _gobj.removeSubscriber(this); + // unlisten to the game object + _gobj.removeListener(this); _gobj = null; } @@ -89,47 +97,27 @@ public abstract class GameController } // documentation inherited - public void objectAvailable (DObject object) + public void attributeChanged (AttributeChangedEvent event) { - Log.warning("Got call to objectAvailable()?! " + - "[object=" + object + "]."); - } - - // documentation inherited - public void requestFailed (int oid, ObjectAccessException cause) - { - Log.warning("Got call to requestFailed()?! " + - "[oid=" + oid + ", cause=" + cause + "]."); - } - - // documentation inherited - public boolean handleEvent (DEvent event, DObject target) - { - if (event instanceof AttributeChangedEvent) { - AttributeChangedEvent ace = (AttributeChangedEvent)event; - - // deal with game state changes - if (ace.getName().equals(GameObject.STATE)) { - switch (ace.getIntValue()) { - case GameObject.IN_PLAY: - gameDidStart(); - break; - case GameObject.GAME_OVER: - gameDidEnd(); - break; - case GameObject.CANCELLED: - gameWasCancelled(); - break; - default: - Log.warning("Game transitioned to unknown state " + - "[gobj=" + _gobj + - ", state=" + ace.getIntValue() + "]."); - break; - } + // deal with game state changes + if (event.getName().equals(GameObject.STATE)) { + switch (event.getIntValue()) { + case GameObject.IN_PLAY: + gameDidStart(); + break; + case GameObject.GAME_OVER: + gameDidEnd(); + break; + case GameObject.CANCELLED: + gameWasCancelled(); + break; + default: + Log.warning("Game transitioned to unknown state " + + "[gobj=" + _gobj + + ", state=" + event.getIntValue() + "]."); + break; } } - - return true; } /** diff --git a/src/java/com/threerings/parlor/game/GameManager.java b/src/java/com/threerings/parlor/game/GameManager.java index 488b81523..413fda5b4 100644 --- a/src/java/com/threerings/parlor/game/GameManager.java +++ b/src/java/com/threerings/parlor/game/GameManager.java @@ -1,5 +1,5 @@ // -// $Id: GameManager.java,v 1.8 2001/10/11 21:08:21 mdb Exp $ +// $Id: GameManager.java,v 1.9 2001/10/12 00:03:03 mdb Exp $ package com.threerings.parlor.game; @@ -65,6 +65,8 @@ public class GameManager // documentation inherited protected void didStartup () { + super.didStartup(); + // obtain a casted reference to our game object _gameobj = (GameObject)_plobj; diff --git a/src/java/com/threerings/parlor/util/MathUtil.java b/src/java/com/threerings/parlor/util/MathUtil.java new file mode 100644 index 000000000..2ac2f07a7 --- /dev/null +++ b/src/java/com/threerings/parlor/util/MathUtil.java @@ -0,0 +1,27 @@ +// +// $Id: MathUtil.java,v 1.1 2001/10/12 00:03:03 mdb Exp $ + +package com.threerings.parlor.util; + +import java.util.Random; + +/** + * Contains math-related utility functions that are pertinent to game + * development. + */ +public class MathUtil +{ + /** + * Returns a pseudo-random integer in the range from zero (inclusive) + * to maxValue (exclusive). This presently uses an + * instance of {@link Random} which uses a 48-bit seed, which is + * modified using a linear congruential formula. (See Donald Knuth, + * The Art of Computer Programming, Volume 2, Section 3.2.1.) + */ + public static int random (int maxValue) + { + return _random.nextInt(maxValue); + } + + protected static Random _random = new Random(); +} diff --git a/src/java/com/threerings/presents/client/ClientDObjectMgr.java b/src/java/com/threerings/presents/client/ClientDObjectMgr.java index a985198df..843de563b 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.7 2001/10/11 04:07:52 mdb Exp $ +// $Id: ClientDObjectMgr.java,v 1.8 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.client; @@ -173,10 +173,9 @@ public class ClientDObjectMgr _ocache.remove(target.getOid()); } - // have the object pass this event on to its subscribers if - // desired + // have the object pass this event on to its listeners if (notify) { - target.notifySubscribers(event); + target.notifyListeners(event); } } catch (Exception e) { diff --git a/src/java/com/threerings/presents/client/InvocationDirector.java b/src/java/com/threerings/presents/client/InvocationDirector.java index d10c7df2d..cfc94661a 100644 --- a/src/java/com/threerings/presents/client/InvocationDirector.java +++ b/src/java/com/threerings/presents/client/InvocationDirector.java @@ -1,5 +1,5 @@ // -// $Id: InvocationDirector.java,v 1.13 2001/10/11 04:07:52 mdb Exp $ +// $Id: InvocationDirector.java,v 1.14 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.client; @@ -35,7 +35,7 @@ import com.threerings.presents.util.ClassUtil; * notifications at any time from the server. */ public class InvocationDirector - implements Subscriber + implements Subscriber, MessageListener { /** * Initializes the invocation director with the specified invocation @@ -121,13 +121,18 @@ public class InvocationDirector _receivers.put(module, receiver); } + // documentation inherited public void objectAvailable (DObject object) { + // add ourselves as a message listener + object.addListener(this); + // let the client know that we're ready to go now that we've got // our subscription to the client object _client.invocationDirectorReady((ClientObject)object); } + // documentation inherited public void requestFailed (int oid, ObjectAccessException cause) { // aiya! we were unable to subscribe to the client object. we're @@ -139,23 +144,14 @@ public class InvocationDirector /** * Process incoming message requests on user object. */ - public boolean handleEvent (DEvent event, DObject target) + public void messageReceived (MessageEvent event) { - // we only care about message events - if (!(event instanceof MessageEvent)) { - return true; - } - - // and only those of proper name - MessageEvent mevt = (MessageEvent)event; - String name = mevt.getName(); + String name = event.getName(); if (name.equals(InvocationObject.RESPONSE_NAME)) { - handleInvocationResponse(mevt.getArgs()); + handleInvocationResponse(event.getArgs()); } else if (name.equals(InvocationObject.NOTIFICATION_NAME)) { - handleInvocationNotification(mevt.getArgs()); + handleInvocationNotification(event.getArgs()); } - - return true; } /** diff --git a/src/java/com/threerings/presents/dobj/AttributeChangeListener.java b/src/java/com/threerings/presents/dobj/AttributeChangeListener.java new file mode 100644 index 000000000..c4cb3be09 --- /dev/null +++ b/src/java/com/threerings/presents/dobj/AttributeChangeListener.java @@ -0,0 +1,23 @@ +// +// $Id: AttributeChangeListener.java,v 1.1 2001/10/12 00:03:03 mdb Exp $ + +package com.threerings.presents.dobj; + +/** + * Implemented by entites which wish to hear about attribute changes that + * take place for a particular distributed object. + * + * @see DObject#addListener + */ +public interface AttributeChangeListener +{ + /** + * Called when an attribute changed event has been dispatched on an + * object. This will be called after the event has been + * applied to the object. So fetching the attribute during this call + * will provide the new value for the attribute. + * + * @param event The event that was dispatched on the object. + */ + public void attributeChanged (AttributeChangedEvent event); +} diff --git a/src/java/com/threerings/presents/dobj/AttributeChangedEvent.java b/src/java/com/threerings/presents/dobj/AttributeChangedEvent.java index f3f3d0a6d..e0b037658 100644 --- a/src/java/com/threerings/presents/dobj/AttributeChangedEvent.java +++ b/src/java/com/threerings/presents/dobj/AttributeChangedEvent.java @@ -1,5 +1,5 @@ // -// $Id: AttributeChangedEvent.java,v 1.9 2001/10/11 04:07:52 mdb Exp $ +// $Id: AttributeChangedEvent.java,v 1.10 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -121,11 +121,13 @@ public class AttributeChangedEvent extends TypedEvent return true; } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -134,6 +136,7 @@ public class AttributeChangedEvent extends TypedEvent ValueMarshaller.writeTo(out, _value); } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -142,6 +145,15 @@ public class AttributeChangedEvent extends TypedEvent _value = ValueMarshaller.readFrom(in); } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof AttributeChangeListener) { + ((AttributeChangeListener)listener).attributeChanged(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("CHANGE:"); diff --git a/src/java/com/threerings/presents/dobj/DEvent.java b/src/java/com/threerings/presents/dobj/DEvent.java index bcfdf01ee..c97dae21f 100644 --- a/src/java/com/threerings/presents/dobj/DEvent.java +++ b/src/java/com/threerings/presents/dobj/DEvent.java @@ -1,5 +1,5 @@ // -// $Id: DEvent.java,v 1.6 2001/10/11 04:07:52 mdb Exp $ +// $Id: DEvent.java,v 1.7 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -63,6 +63,18 @@ public abstract class DEvent _toid = targetOid; } + /** + * Events with associated listener interfaces should implement this + * function and notify the supplied listener if it implements their + * event listening interface. For example, the {@link + * AttributeChangedEvent} will notify listeners that implement + * {@AttributeChangeListener}. + */ + protected void notifyListener (Object listener) + { + // the default is to do nothing + } + /** * Constructs and returns a string representation of this event. */ diff --git a/src/java/com/threerings/presents/dobj/DObject.java b/src/java/com/threerings/presents/dobj/DObject.java index e0ad8b93e..c2a5f164e 100644 --- a/src/java/com/threerings/presents/dobj/DObject.java +++ b/src/java/com/threerings/presents/dobj/DObject.java @@ -1,5 +1,5 @@ // -// $Id: DObject.java,v 1.27 2001/10/11 04:07:52 mdb Exp $ +// $Id: DObject.java,v 1.28 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -99,7 +99,7 @@ public class DObject * instead to ensure that everything is done on the proper thread. * This function can only safely be called directly when you know you * are operating on the omgr thread (you are in the middle of a call - * to objectAvailable or handleEvent). + * to objectAvailable or to a listener callback). * * @see DObjectManager#subscribeToObject */ @@ -118,7 +118,7 @@ public class DObject * instead to ensure that everything is done on the proper thread. * This function can only safely be called directly when you know you * are operating on the omgr thread (you are in the middle of a call - * to objectAvailable or handleEvent). + * to objectAvailable or to a listener callback). * * @see DObjectManager#unsubscribeFromObject */ @@ -135,6 +135,38 @@ public class DObject } } + /** + * Adds an event listener to this object. The listener will be + * notified when any events are dispatched on this object that match + * their particular listener interface. + * + * @param listener the listener to be added. + * + * @see EventListener + * @see AttributeChangeListener + * @see SetListener + * @see OidListListener + */ + public void addListener (Object listener) + { + // only add the listener if they're not already there + Object[] els = ListUtil.testAndAdd(_listeners, listener); + if (els != null) { + _listeners = els; + } + } + + /** + * Removes an event listener from this object. The listener will no + * longer be notified when events are dispatched on this object. + * + * @param listener the listener to be removed. + */ + public void removeListener (Object listener) + { + ListUtil.clear(_listeners, listener); + } + /** * At times, an entity on the server may need to ensure that events it * has queued up have made it through the event queue and are applied @@ -257,36 +289,33 @@ public class DObject * * @param event the event that was just applied. */ - public void notifySubscribers (DEvent event) + public void notifyListeners (DEvent event) { - // Log.info("Dispatching event to " + _scount + - // " subscribers: " + event); + // iterate over the listener list, performing the necessary + // notifications + int llength = _listeners.length; + for (int i = 0; i < llength; i++) { + Object listener = _listeners[i]; - // nothing to do if we've no subscribers - if (_subs == null) { - return; - } - - // otherwise iterate over the subscribers array and notify - int slength = _subs.length; - for (int i = 0; i < slength; i++) { - Subscriber sub = (Subscriber)_subs[i]; - // skip empty spots - if (sub == null) { + // skip empty slots + if (listener == null) { continue; } - // notify the subscriber - if (!sub.handleEvent(event, this)) { - // if they return false, we need to remove them from the - // subscriber list - _subs[i] = null; + try { + // do any event specific notifications + event.notifyListener(listener); - // if we just removed our last subscriber, we need to let - // the omgr know about it - if (--_scount == 0) { - _mgr.removedLastSubscriber(this); + // and notify them if they are listening for all events + if (listener instanceof EventListener) { + ((EventListener)listener).eventReceived(event); } + + } catch (Exception e) { + Log.warning("Listener choked during notification " + + "[listener=" + listener + + ", event=" + event + "]."); + Log.logStackTrace(e); } } } @@ -469,6 +498,9 @@ public class DObject /** Our subscribers list. */ protected Object[] _subs; + /** Our event listeners list. */ + protected Object[] _listeners; + /** Our subscriber count. */ protected int _scount; } diff --git a/src/java/com/threerings/presents/dobj/EntryAddedEvent.java b/src/java/com/threerings/presents/dobj/EntryAddedEvent.java index 7fa425c0a..b43bfc316 100644 --- a/src/java/com/threerings/presents/dobj/EntryAddedEvent.java +++ b/src/java/com/threerings/presents/dobj/EntryAddedEvent.java @@ -1,5 +1,5 @@ // -// $Id: EntryAddedEvent.java,v 1.4 2001/10/11 04:07:52 mdb Exp $ +// $Id: EntryAddedEvent.java,v 1.5 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -89,11 +89,13 @@ public class ElementAddedEvent extends TypedEvent return true; } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -102,6 +104,7 @@ public class ElementAddedEvent extends TypedEvent ElementUtil.flatten(out, _elem); } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -116,6 +119,15 @@ public class ElementAddedEvent extends TypedEvent in.readFully(_bytes, 0, bcount); } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof SetListener) { + ((SetListener)listener).elementAdded(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("ELADD:"); diff --git a/src/java/com/threerings/presents/dobj/EntryRemovedEvent.java b/src/java/com/threerings/presents/dobj/EntryRemovedEvent.java index 3dd583336..c75691de5 100644 --- a/src/java/com/threerings/presents/dobj/EntryRemovedEvent.java +++ b/src/java/com/threerings/presents/dobj/EntryRemovedEvent.java @@ -1,5 +1,5 @@ // -// $Id: EntryRemovedEvent.java,v 1.5 2001/10/11 04:07:52 mdb Exp $ +// $Id: EntryRemovedEvent.java,v 1.6 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -77,11 +77,13 @@ public class ElementRemovedEvent extends TypedEvent } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -90,6 +92,7 @@ public class ElementRemovedEvent extends TypedEvent ValueMarshaller.writeTo(out, _key); } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -98,6 +101,15 @@ public class ElementRemovedEvent extends TypedEvent _key = ValueMarshaller.readFrom(in); } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof SetListener) { + ((SetListener)listener).elementRemoved(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("ELREM:"); diff --git a/src/java/com/threerings/presents/dobj/EntryUpdatedEvent.java b/src/java/com/threerings/presents/dobj/EntryUpdatedEvent.java index ba913eb6c..c6400e33a 100644 --- a/src/java/com/threerings/presents/dobj/EntryUpdatedEvent.java +++ b/src/java/com/threerings/presents/dobj/EntryUpdatedEvent.java @@ -1,5 +1,5 @@ // -// $Id: EntryUpdatedEvent.java,v 1.2 2001/10/11 04:07:52 mdb Exp $ +// $Id: EntryUpdatedEvent.java,v 1.3 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -95,11 +95,13 @@ public class ElementUpdatedEvent extends TypedEvent return true; } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -108,6 +110,7 @@ public class ElementUpdatedEvent extends TypedEvent ElementUtil.flatten(out, _elem); } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -122,6 +125,15 @@ public class ElementUpdatedEvent extends TypedEvent in.readFully(_bytes, 0, bcount); } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof SetListener) { + ((SetListener)listener).elementUpdated(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("ELUPD:"); diff --git a/src/java/com/threerings/presents/dobj/EventListener.java b/src/java/com/threerings/presents/dobj/EventListener.java new file mode 100644 index 000000000..82339d801 --- /dev/null +++ b/src/java/com/threerings/presents/dobj/EventListener.java @@ -0,0 +1,25 @@ +// +// $Id: EventListener.java,v 1.1 2001/10/12 00:03:03 mdb Exp $ + +package com.threerings.presents.dobj; + +/** + * Implemented by entites which wish to hear about all events being + * dispatched on a particular distributed object. + * + * @see DObject#addListener + */ +public interface EventListener +{ + /** + * Called when any event has been dispatched on an object. The event + * will be of the derived class that corresponds to the kind of event + * that occurred on the object. This will be called after the + * event has been applied to the object. So fetching an attribute upon + * receiving an attribute changed event will provide the new value for + * the attribute. + * + * @param event The event that was dispatched on the object. + */ + public void eventReceived (DEvent event); +} diff --git a/src/java/com/threerings/presents/dobj/MessageEvent.java b/src/java/com/threerings/presents/dobj/MessageEvent.java index f32222fa5..5f945f642 100644 --- a/src/java/com/threerings/presents/dobj/MessageEvent.java +++ b/src/java/com/threerings/presents/dobj/MessageEvent.java @@ -1,5 +1,5 @@ // -// $Id: MessageEvent.java,v 1.6 2001/10/11 04:07:52 mdb Exp $ +// $Id: MessageEvent.java,v 1.7 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -86,11 +86,13 @@ public class MessageEvent extends TypedEvent return true; } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -106,6 +108,7 @@ public class MessageEvent extends TypedEvent } } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -120,6 +123,15 @@ public class MessageEvent extends TypedEvent } } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof MessageListener) { + ((MessageListener)listener).messageReceived(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("MSG:"); diff --git a/src/java/com/threerings/presents/dobj/MessageListener.java b/src/java/com/threerings/presents/dobj/MessageListener.java new file mode 100644 index 000000000..2a610e28b --- /dev/null +++ b/src/java/com/threerings/presents/dobj/MessageListener.java @@ -0,0 +1,20 @@ +// +// $Id: MessageListener.java,v 1.1 2001/10/12 00:03:03 mdb Exp $ + +package com.threerings.presents.dobj; + +/** + * Implemented by entites which wish to hear about message events that are + * dispatched on a particular distributed object. + * + * @see DObject#addListener + */ +public interface MessageListener +{ + /** + * Called when an message event has been dispatched on an object. + * + * @param event The event that was dispatched on the object. + */ + public void messageReceived (MessageEvent event); +} diff --git a/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java b/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java index 0956a5b25..db058ea1f 100644 --- a/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java +++ b/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java @@ -1,5 +1,5 @@ // -// $Id: ObjectAddedEvent.java,v 1.5 2001/10/11 04:07:52 mdb Exp $ +// $Id: ObjectAddedEvent.java,v 1.6 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -73,11 +73,13 @@ public class ObjectAddedEvent extends TypedEvent return true; } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -86,6 +88,7 @@ public class ObjectAddedEvent extends TypedEvent out.writeInt(_oid); } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -94,6 +97,15 @@ public class ObjectAddedEvent extends TypedEvent _oid = in.readInt(); } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof OidListListener) { + ((OidListListener)listener).objectAdded(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("OBJADD:"); diff --git a/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java b/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java index 5daa4ff1d..76b2c12ae 100644 --- a/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java +++ b/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java @@ -1,5 +1,5 @@ // -// $Id: ObjectRemovedEvent.java,v 1.5 2001/10/11 04:07:52 mdb Exp $ +// $Id: ObjectRemovedEvent.java,v 1.6 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -74,11 +74,13 @@ public class ObjectRemovedEvent extends TypedEvent return true; } + // documentation inherited public short getType () { return TYPE; } + // documentation inherited public void writeTo (DataOutputStream out) throws IOException { @@ -87,6 +89,7 @@ public class ObjectRemovedEvent extends TypedEvent out.writeInt(_oid); } + // documentation inherited public void readFrom (DataInputStream in) throws IOException { @@ -95,6 +98,15 @@ public class ObjectRemovedEvent extends TypedEvent _oid = in.readInt(); } + // documentation inherited + protected void notifyListener (Object listener) + { + if (listener instanceof OidListListener) { + ((OidListListener)listener).objectRemoved(this); + } + } + + // documentation inherited protected void toString (StringBuffer buf) { buf.append("OBJREM:"); diff --git a/src/java/com/threerings/presents/dobj/OidListListener.java b/src/java/com/threerings/presents/dobj/OidListListener.java new file mode 100644 index 000000000..de5394f85 --- /dev/null +++ b/src/java/com/threerings/presents/dobj/OidListListener.java @@ -0,0 +1,31 @@ +// +// $Id: OidListListener.java,v 1.1 2001/10/12 00:03:03 mdb Exp $ + +package com.threerings.presents.dobj; + +/** + * Implemented by entites which wish to hear about changes that occur to + * oid list attributes of a particular distributed object. + * + * @see DObject#addListener + */ +public interface OidListListener +{ + /** + * Called when an object added event has been dispatched on an + * object. This will be called after the event has been + * applied to the object. + * + * @param event The event that was dispatched on the object. + */ + public void objectAdded (ObjectAddedEvent event); + + /** + * Called when an object removed event has been dispatched on an + * object. This will be called after the event has been + * applied to the object. + * + * @param event The event that was dispatched on the object. + */ + public void objectRemoved (ObjectRemovedEvent event); +} diff --git a/src/java/com/threerings/presents/dobj/SetListener.java b/src/java/com/threerings/presents/dobj/SetListener.java new file mode 100644 index 000000000..48800ad7f --- /dev/null +++ b/src/java/com/threerings/presents/dobj/SetListener.java @@ -0,0 +1,40 @@ +// +// $Id: SetListener.java,v 1.1 2001/10/12 00:03:03 mdb Exp $ + +package com.threerings.presents.dobj; + +/** + * Implemented by entites which wish to hear about changes that occur to + * set attributes of a particular distributed object. + * + * @see DObject#addListener + */ +public interface SetListener +{ + /** + * Called when an element added event has been dispatched on an + * object. This will be called after the event has been + * applied to the object. + * + * @param event The event that was dispatched on the object. + */ + public void elementAdded (ElementAddedEvent event); + + /** + * Called when an element updated event has been dispatched on an + * object. This will be called after the event has been + * applied to the object. + * + * @param event The event that was dispatched on the object. + */ + public void elementUpdated (ElementUpdatedEvent event); + + /** + * Called when an element removed event has been dispatched on an + * object. This will be called after the event has been + * applied to the object. + * + * @param event The event that was dispatched on the object. + */ + public void elementRemoved (ElementRemovedEvent event); +} diff --git a/src/java/com/threerings/presents/dobj/Subscriber.java b/src/java/com/threerings/presents/dobj/Subscriber.java index 9b6583197..a9ddb7979 100644 --- a/src/java/com/threerings/presents/dobj/Subscriber.java +++ b/src/java/com/threerings/presents/dobj/Subscriber.java @@ -1,5 +1,5 @@ // -// $Id: Subscriber.java,v 1.6 2001/10/11 04:07:52 mdb Exp $ +// $Id: Subscriber.java,v 1.7 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.dobj; @@ -10,16 +10,24 @@ package com.threerings.presents.dobj; * registering as a subscriber to an object, an entity can react to * changes made to an object and ensure that their object is kept up to * date. + * + *

To actually receive callbacks when events are dispatched on a + * distributed object, an entity should register itself as a listener on + * the object once it has received its object reference. + * + * @see EventListener + * @see AttributeChangeListener + * @see SetListener + * @see OidListListener */ public interface Subscriber { /** * Called when a subscription request has succeeded and the object is * available. If the object was requested for subscription, the - * subscriber will subsequently receive notifications via - * handleEvent. If the object was requested as a one-time - * read-only copy, these updates will not occur and the subscriber - * should not attempt to modify the object. + * subscriber can subsequently receive notifications by registering + * itself as a listener of some sort (see {@link + * DObject#addListener}). * * @see DObjectManager#subscribeToObject */ @@ -33,23 +41,4 @@ public interface Subscriber * @see DObjectManager#subscribeToObject */ public void requestFailed (int oid, ObjectAccessException cause); - - /** - * Called when an event has been dispatched on an object. The event - * will be of the derived class that corresponds to the kind of event - * that occurred on the object. handleEvent will be - * called after the event has been applied to the object. So - * fetching an attribute upon receiving an attribute changed event - * will provide the new value for the attribute. - * - *

A subscriber should return true from handleEvent - * unless they wish their subscription to be terminated. - * - * @param event The event dispatched on the object. - * @param target The object on which the event was dispatched. - * - * @return true if the subscriber wishes to remain subscribed to the - * target object, false if they do not. - */ - public boolean handleEvent (DEvent event, DObject target); } diff --git a/src/java/com/threerings/presents/server/InvocationManager.java b/src/java/com/threerings/presents/server/InvocationManager.java index 37b5d5c9c..905d825d6 100644 --- a/src/java/com/threerings/presents/server/InvocationManager.java +++ b/src/java/com/threerings/presents/server/InvocationManager.java @@ -1,5 +1,5 @@ // -// $Id: InvocationManager.java,v 1.8 2001/10/11 04:07:53 mdb Exp $ +// $Id: InvocationManager.java,v 1.9 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server; @@ -32,7 +32,7 @@ import com.threerings.presents.util.ClassUtil; * the client. */ public class InvocationManager - implements Subscriber + implements Subscriber, MessageListener { public InvocationManager (DObjectManager omgr) { @@ -93,6 +93,9 @@ public class InvocationManager { // this must be our invocation object _invoid = object.getOid(); + + // add ourselves as a message listener + object.addListener(this); } public void requestFailed (int oid, ObjectAccessException cause) @@ -104,23 +107,15 @@ public class InvocationManager _invoid = -1; } - public boolean handleEvent (DEvent event, DObject target) + public void messageReceived (MessageEvent event) { - // we shouldn't be getting non-message events, but check just to - // be sure - if (!(event instanceof MessageEvent)) { - Log.warning("Got non-message event!? [evt=" + event + "]."); - return true; - } - // make sure the name is proper just for sanity's sake - MessageEvent mevt = (MessageEvent)event; - if (!mevt.getName().equals(InvocationObject.REQUEST_NAME)) { - return true; + if (!event.getName().equals(InvocationObject.REQUEST_NAME)) { + return; } // we've got an invocation request, so we process it - Object[] args = mevt.getArgs(); + Object[] args = event.getArgs(); String module = (String)args[0]; String procedure = (String)args[1]; Integer invid = (Integer)args[2]; @@ -130,20 +125,20 @@ public class InvocationManager (InvocationProvider)_providers.get(module); if (provider == null) { Log.warning("No provider registered for invocation request " + - "[evt=" + mevt + "]."); - return true; + "[evt=" + event + "]."); + return; } // prune the method arguments from the full message arguments Object[] margs = new Object[args.length-1]; - int cloid = mevt.getSourceOid(); + int cloid = event.getSourceOid(); margs[0] = PresentsServer.omgr.getObject(cloid); // make sure the client is still around if (margs[0] == null) { Log.warning("Client no longer around for invocation provider " + "request [module=" + module + ", proc=" + procedure + ", cloid=" + cloid + "]."); - return true; + return; } System.arraycopy(args, 2, margs, 1, args.length-2); @@ -154,7 +149,7 @@ public class InvocationManager Log.warning("Unable to resolve provider procedure " + "[provider=" + provider.getClass().getName() + ", method=" + mname + "]."); - return true; + return; } // and invoke it @@ -166,8 +161,6 @@ public class InvocationManager ", method=" + procmeth + "]."); Log.logStackTrace(e); } - - return true; } protected DObjectManager _omgr; diff --git a/src/java/com/threerings/presents/server/PresentsClient.java b/src/java/com/threerings/presents/server/PresentsClient.java index 9c71e8307..fba802fc1 100644 --- a/src/java/com/threerings/presents/server/PresentsClient.java +++ b/src/java/com/threerings/presents/server/PresentsClient.java @@ -1,5 +1,5 @@ // -// $Id: PresentsClient.java,v 1.20 2001/10/11 04:07:53 mdb Exp $ +// $Id: PresentsClient.java,v 1.21 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server; @@ -75,11 +75,6 @@ public class PresentsClient implements Subscriber, MessageHandler "[client=" + PresentsClient.this + ", error=" + cause + "]."); } - - public boolean handleEvent (DEvent event, DObject target) - { - return false; - } }; Class clobjClass = _cmgr.getClientObjectClass(); PresentsServer.omgr.createObject(clobjClass, sub, false); @@ -204,7 +199,13 @@ public class PresentsClient implements Subscriber, MessageHandler */ public synchronized void unmapSubscrip (int oid) { - _subscrips.remove(oid); + DObject object = (DObject)_subscrips.remove(oid); + if (object != null) { + object.removeListener(this); + } else { + Log.warning("Requested to unmap non-existent subscription " + + "[oid=" + oid + "]."); + } } /** @@ -409,6 +410,8 @@ public class PresentsClient implements Subscriber, MessageHandler // 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 @@ -434,7 +437,7 @@ public class PresentsClient implements Subscriber, MessageHandler } // documentation inherited from interface - public boolean handleEvent (DEvent event, DObject target) + public void eventReceived (DEvent event) { // forward the event to the client Connection conn = getConnection(); @@ -447,8 +450,6 @@ public class PresentsClient implements Subscriber, MessageHandler Log.info("Dropped event forward notification " + "[client=" + this + ", event=" + event + "]."); } - - return true; } public String toString () diff --git a/src/java/com/threerings/presents/server/PresentsDObjectMgr.java b/src/java/com/threerings/presents/server/PresentsDObjectMgr.java index 4ebc84edb..6d18e33a0 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.17 2001/10/11 04:07:53 mdb Exp $ +// $Id: PresentsDObjectMgr.java,v 1.18 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server; @@ -173,9 +173,9 @@ public class PresentsDObjectMgr implements DObjectManager // if the event returns false from applyToObject, this // means it's a silent event and we shouldn't notify the - // subscribers + // listeners if (notify) { - target.notifySubscribers(event); + target.notifyListeners(event); } } catch (Exception e) { diff --git a/tests/bin/testserver b/tests/bin/testserver index ccec3f5c3..0b0b67e55 100755 --- a/tests/bin/testserver +++ b/tests/bin/testserver @@ -1,4 +1,4 @@ #!/bin/sh bindir=`dirname $0` -$bindir/runjava $* com.threerings.parlor.test.TestServer +$bindir/runjava $* com.threerings.presents.server.PresentsServer diff --git a/tests/src/java/com/threerings/presents/client/TestClient.java b/tests/src/java/com/threerings/presents/client/TestClient.java index 7130ab814..7b18dcfda 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.10 2001/10/11 04:07:52 mdb Exp $ +// $Id: TestClient.java,v 1.11 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.client.test; @@ -16,7 +16,7 @@ import com.threerings.presents.server.test.TestObject; * A standalone test client. */ public class TestClient - implements Client.Invoker, ClientObserver, Subscriber + implements Client.Invoker, ClientObserver, Subscriber, EventListener { public void setClient (Client client) { @@ -74,6 +74,7 @@ public class TestClient public void objectAvailable (DObject object) { + object.addListener(this); Log.info("Object available: " + object); ((TestObject)object).setBar("lawl!"); } @@ -86,17 +87,18 @@ public class TestClient _client.logoff(true); } - public boolean handleEvent (DEvent event, DObject target) + public void eventReceived (DEvent event) { - Log.info("Got event [event=" + event + ", target=" + target + "]."); + Log.info("Got event [event=" + event + "]."); + if (event instanceof AttributeChangedEvent) { // request to destroy the object - target.destroy(); + _client.getDObjectManager().destroyObject(event.getTargetOid()); + } else { // request that we log off _client.logoff(true); } - return true; } public void handleTestSucceeded (int invid, String one, int two) diff --git a/tests/src/java/com/threerings/presents/server/DOMTest.java b/tests/src/java/com/threerings/presents/server/DOMTest.java index 4c1e656c4..3b595ecd7 100644 --- a/tests/src/java/com/threerings/presents/server/DOMTest.java +++ b/tests/src/java/com/threerings/presents/server/DOMTest.java @@ -1,5 +1,5 @@ // -// $Id: DOMTest.java,v 1.2 2001/10/11 04:07:53 mdb Exp $ +// $Id: DOMTest.java,v 1.3 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server.test; @@ -10,10 +10,13 @@ import com.threerings.presents.server.*; /** * A simple test case for the dobjmgr. */ -public class DOMTest implements Subscriber +public class DOMTest implements Subscriber, AttributeChangeListener { public void objectAvailable (DObject object) { + // add ourselves as a listener + object.addListener(this); + Log.info("Object available: " + object); // set some values TestObject to = (TestObject)object; @@ -27,17 +30,14 @@ public class DOMTest implements Subscriber omgr.shutdown(); } - public boolean handleEvent (DEvent event, DObject target) + public void attributeChanged (AttributeChangedEvent event) { - Log.info("Got event [event=" + event + ", target=" + target + "]."); + Log.info("Got event [event=" + event + "]."); // if this is the second event, request a shutdown - AttributeChangedEvent ace = (AttributeChangedEvent)event; - if (ace.getName().equals(TestObject.BAR)) { + if (event.getName().equals(TestObject.BAR)) { omgr.shutdown(); } - - return true; } public static PresentsDObjectMgr omgr = new PresentsDObjectMgr(); diff --git a/tests/src/java/com/threerings/presents/server/DestroyedRefTest.java b/tests/src/java/com/threerings/presents/server/DestroyedRefTest.java index 055c2732f..d4bc429f2 100644 --- a/tests/src/java/com/threerings/presents/server/DestroyedRefTest.java +++ b/tests/src/java/com/threerings/presents/server/DestroyedRefTest.java @@ -1,5 +1,5 @@ // -// $Id: DestroyedRefTest.java,v 1.2 2001/10/11 04:07:53 mdb Exp $ +// $Id: DestroyedRefTest.java,v 1.3 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server.test; @@ -12,7 +12,7 @@ import com.threerings.presents.server.PresentsServer; * an oid list. */ public class DestroyedRefTest - implements Runnable, Subscriber + implements Runnable, Subscriber, EventListener { public void run () { @@ -23,6 +23,9 @@ public class DestroyedRefTest public void objectAvailable (DObject object) { + // add ourselves as an event listener + object.addListener(this); + // keep references to our test objects if (_objone == null) { _objone = (TestObject)object; @@ -51,14 +54,16 @@ public class DestroyedRefTest Log.warning("Ack. Unable to create object [cause=" + cause + "]."); } - public boolean handleEvent (DEvent event, DObject target) + public void eventReceived (DEvent event) { + int toid = event.getTargetOid(); + // when we get the attribute change, we can exit if (event instanceof ObjectDestroyedEvent) { Log.info("The upcoming object added event should be rejected."); } else if (event instanceof ObjectAddedEvent && - target == _objtwo) { + toid == _objtwo.getOid()) { Log.info("list should contain only one oid: " + _objtwo.list); } else if (event instanceof AttributeChangedEvent) { @@ -68,8 +73,6 @@ public class DestroyedRefTest } else { Log.info("Got unexpected event: " + event); } - - return true; } protected TestObject _objone; diff --git a/tests/src/java/com/threerings/presents/server/RefTest.java b/tests/src/java/com/threerings/presents/server/RefTest.java index 3d30d21f1..08ac44bd7 100644 --- a/tests/src/java/com/threerings/presents/server/RefTest.java +++ b/tests/src/java/com/threerings/presents/server/RefTest.java @@ -1,5 +1,5 @@ // -// $Id: RefTest.java,v 1.2 2001/10/11 04:07:53 mdb Exp $ +// $Id: RefTest.java,v 1.3 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server.test; @@ -11,7 +11,7 @@ import com.threerings.presents.server.PresentsServer; * Tests the oid list reference tracking code. */ public class RefTest - implements Runnable, Subscriber + implements Runnable, Subscriber, EventListener { public void run () { @@ -22,6 +22,9 @@ public class RefTest public void objectAvailable (DObject object) { + // add ourselves as an event listener to our subscribed object + object.addListener(this); + // keep references to our test objects if (_objone == null) { _objone = (TestObject)object; @@ -40,18 +43,20 @@ public class RefTest Log.warning("Ack. Unable to create object [cause=" + cause + "]."); } - public boolean handleEvent (DEvent event, DObject target) + public void eventReceived (DEvent event) { // Log.info("Got event: " + event); + int toid = event.getTargetOid(); // once we receive the second object added we can destroy the // target object to see if the reference is cleaned up - if (event instanceof ObjectAddedEvent && target == _objtwo) { + if (event instanceof ObjectAddedEvent && + toid == _objtwo.getOid()) { Log.info("Destroying object two " + _objtwo + "."); _objtwo.destroy(); } else if (event instanceof ObjectDestroyedEvent) { - if (target == _objtwo) { + if (toid == _objtwo.getOid()) { Log.info("List won't yet be empty: " + _objone.list); } else { Log.info("Other object destroyed."); @@ -64,8 +69,6 @@ public class RefTest // finally destroy the other object to complete the circle _objone.destroy(); } - - return true; } protected TestObject _objone; diff --git a/tests/src/java/com/threerings/presents/server/TestServer.java b/tests/src/java/com/threerings/presents/server/TestServer.java index 8fc271cba..26017a83b 100644 --- a/tests/src/java/com/threerings/presents/server/TestServer.java +++ b/tests/src/java/com/threerings/presents/server/TestServer.java @@ -1,5 +1,5 @@ // -// $Id: TestServer.java,v 1.4 2001/10/11 04:07:53 mdb Exp $ +// $Id: TestServer.java,v 1.5 2001/10/12 00:03:03 mdb Exp $ package com.threerings.presents.server.test; @@ -38,11 +38,6 @@ public class TestServer extends PresentsServer Log.warning("Unable to create test object " + "[error=" + cause + "]."); } - - public boolean handleEvent (DEvent event, DObject target) - { - return false; - } }; omgr.createObject(TestObject.class, sub, false); }