Much work on generalizing the notion of message "transport" and

allowing the use of annotations to customize transport for 
DObject fields and service/receiver methods.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5099 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Andrzej Kapolka
2008-05-16 01:47:33 +00:00
parent e279133868
commit ee74481cad
39 changed files with 864 additions and 123 deletions
@@ -27,6 +27,8 @@ import java.util.HashMap;
import com.samskivert.util.StringUtil;
import com.threerings.presents.net.Transport;
/**
* An attribute changed event is dispatched when a single attribute of a distributed object has
* changed. It can also be constructed to request an attribute change on an object and posted to
@@ -162,7 +164,24 @@ public class AttributeChangedEvent extends NamedEvent
*/
protected AttributeChangedEvent (int targetOid, String name, Object value, Object oldValue)
{
super(targetOid, name);
this(targetOid, name, value, oldValue, Transport.DEFAULT);
}
/**
* Constructs a new attribute changed event on the specified target object with the supplied
* attribute name and value. <em>Do not construct these objects by hand.</em> Use {@link
* DObject#changeAttribute} instead.
*
* @param targetOid the object id of the object whose attribute has changed.
* @param name the name of the attribute (data member) that has changed.
* @param value the new value of the attribute (in the case of primitive types, the
* reflection-defined object-alternative is used).
* @param transport a hint as to the type of transport desired for the event.
*/
protected AttributeChangedEvent (
int targetOid, String name, Object value, Object oldValue, Transport transport)
{
super(targetOid, name, transport);
_value = value;
_oldValue = oldValue;
}
@@ -25,6 +25,8 @@ import java.util.List;
import com.threerings.util.StreamableArrayList;
import com.threerings.presents.net.Transport;
/**
* Used to manage and submit groups of events on a collection of
* distributed objects in a single transaction.
@@ -91,13 +93,18 @@ public class CompoundEvent extends DEvent
// then post this event onto the queue (but only if we actually
// accumulated some events)
switch (_events.size()) {
int size = _events.size();
switch (size) {
case 0: // nothing doing
break;
case 1: // no point in being compound
_omgr.postEvent(_events.get(0));
break;
default: // now we're talking
_transport = _events.get(0).getTransport();
for (int ii = 1; ii < size; ii++) {
_transport = _events.get(ii).getTransport().combine(_transport);
}
_omgr.postEvent(this);
break;
}
@@ -139,6 +146,15 @@ public class CompoundEvent extends DEvent
}
}
@Override // from DEvent
public void setTransport (Transport transport)
{
super.setTransport(transport);
for (int ii = 0, nn = _events.size(); ii < nn; ii++) {
_events.get(ii).setTransport(transport);
}
}
@Override // from DEvent
public boolean applyToObject (DObject target)
throws ObjectAccessException
@@ -23,6 +23,8 @@ package com.threerings.presents.dobj;
import com.threerings.io.Streamable;
import com.threerings.presents.net.Transport;
/**
* A distributed object event is dispatched whenever any modification is made to a distributed
* object. It can also be dispatched purely for notification purposes, without making any
@@ -45,8 +47,19 @@ public abstract class DEvent implements Streamable
* Constructs a new distributed object event that pertains to the specified distributed object.
*/
public DEvent (int targetOid)
{
this(targetOid, Transport.DEFAULT);
}
/**
* Constructs a new distributed object event that pertains to the specified distributed object.
*
* @param transport a hint as to the type of transport desired for the event.
*/
public DEvent (int targetOid, Transport transport)
{
_toid = targetOid;
_transport = transport;
}
/**
@@ -121,6 +134,24 @@ public abstract class DEvent implements Streamable
_soid = sourceOid;
}
/**
* Sets the transport parameters. For events received over the network, these indicate the
* mode of transport over which the event was received. When an event is sent over the
* network, these act as a hint as to the type of transport desired.
*/
public void setTransport (Transport transport)
{
_transport = transport;
}
/**
* Returns the transport parameters.
*/
public Transport getTransport ()
{
return _transport;
}
/**
* 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
@@ -152,6 +183,9 @@ public abstract class DEvent implements Streamable
{
buf.append("targetOid=").append(_toid);
buf.append(", sourceOid=").append(_soid);
if (_transport != Transport.DEFAULT) {
buf.append(", transport=").append(_transport);
}
}
/** The oid of the object that is the target of this event. */
@@ -160,6 +194,9 @@ public abstract class DEvent implements Streamable
/** The oid of the client that generated this event. */
protected transient int _soid = -1;
/** The transport parameters. */
protected transient Transport _transport = Transport.DEFAULT;
/** Used to differentiate between null meaning we haven't initialized our old value and null
* being the actual old value. */
protected static final Object UNSET_OLD_VALUE = new Object();
@@ -37,6 +37,7 @@ import com.threerings.io.Streamable;
import com.threerings.util.TrackedObject;
import com.threerings.presents.Log;
import com.threerings.presents.net.Transport;
/**
* The distributed object forms the foundation of the Presents system. All information shared among
@@ -250,7 +251,7 @@ public class DObject
public void setAccessController (AccessController controller)
{
_controller = controller;
}
}
/**
* Returns a reference to the access controller in use by this object or null if none has been
@@ -524,11 +525,21 @@ public class DObject
}
/**
* Posts a message event on this distrubuted object.
* Posts a message event on this distributed object.
*/
public void postMessage (String name, Object... args)
{
postEvent(new MessageEvent(_oid, name, args));
postMessage(Transport.DEFAULT, name, args);
}
/**
* Posts a message event on this distributed object.
*
* @param transport a hint as to the type of transport desired for the message.
*/
public void postMessage (Transport transport, String name, Object... args)
{
postEvent(new MessageEvent(_oid, name, args, transport));
}
/**
@@ -683,7 +694,7 @@ public class DObject
_tevent.commit();
}
}
}
}
/**
* Returns true if this object is in the middle of a transaction or false if it is not.
@@ -714,7 +725,7 @@ public class DObject
} else {
_tevent.cancel();
}
}
}
/**
* Removes this object from participation in any transaction in which it might be taking part.
@@ -736,19 +747,37 @@ public class DObject
* Called by derived instances when an attribute setter method was called.
*/
protected void requestAttributeChange (String name, Object value, Object oldValue)
{
requestAttributeChange(name, value, oldValue, Transport.DEFAULT);
}
/**
* Called by derived instances when an attribute setter method was called.
*/
protected void requestAttributeChange (
String name, Object value, Object oldValue, Transport transport)
{
// dispatch an attribute changed event
postEvent(new AttributeChangedEvent(_oid, name, value, oldValue));
postEvent(new AttributeChangedEvent(_oid, name, value, oldValue, transport));
}
/**
* Called by derived instances when an element updater method was called.
*/
protected void requestElementUpdate (String name, int index, Object value, Object oldValue)
{
requestElementUpdate(name, index, value, oldValue, Transport.DEFAULT);
}
/**
* Called by derived instances when an element updater method was called.
*/
protected void requestElementUpdate (
String name, int index, Object value, Object oldValue, Transport transport)
{
// dispatch an attribute changed event
postEvent(new ElementUpdatedEvent(
_oid, name, value, oldValue, index));
_oid, name, value, oldValue, index, transport));
}
/**
@@ -810,6 +839,15 @@ public class DObject
* Calls by derived instances when a set updater method was called.
*/
protected <T extends DSet.Entry> void requestEntryUpdate (String name, DSet<T> set, T entry)
{
requestEntryUpdate(name, set, entry, Transport.DEFAULT);
}
/**
* Calls by derived instances when a set updater method was called.
*/
protected <T extends DSet.Entry> void requestEntryUpdate (
String name, DSet<T> set, T entry, Transport transport)
{
// if we're on the authoritative server, we update the set immediately
T oldEntry = null;
@@ -820,7 +858,7 @@ public class DObject
}
}
// dispatch an entry updated event
postEvent(new EntryUpdatedEvent<T>(_oid, name, entry, oldEntry));
postEvent(new EntryUpdatedEvent<T>(_oid, name, entry, oldEntry, transport));
}
/**
@@ -26,6 +26,8 @@ import java.lang.reflect.Field;
import com.samskivert.util.StringUtil;
import com.threerings.presents.net.Transport;
/**
* An element updated event is dispatched when an element of an array field in a distributed object
* is updated. It can also be constructed to request the update of an entry and posted to the
@@ -49,7 +51,26 @@ public class ElementUpdatedEvent extends NamedEvent
*/
public ElementUpdatedEvent (int targetOid, String name, Object value, Object ovalue, int index)
{
super(targetOid, name);
this(targetOid, name, value, ovalue, index, Transport.DEFAULT);
}
/**
* Constructs a new element updated event on the specified target object with the supplied
* attribute name, element and index.
*
* @param targetOid the object id of the object whose attribute has changed.
* @param name the name of the attribute (data member) for which an element has changed.
* @param value the new value of the element (in the case of primitive types, the
* reflection-defined object-alternative is used).
* @param oldValue the previous value of the element (in the case of primitive types, the
* reflection-defined object-alternative is used).
* @param index the index in the array of the updated element.
* @param transport a hint as to the type of transport desired for the event.
*/
public ElementUpdatedEvent (
int targetOid, String name, Object value, Object ovalue, int index, Transport transport)
{
super(targetOid, name, transport);
_value = value;
_oldValue = ovalue;
_index = index;
@@ -95,7 +95,8 @@ public class EntryAddedEvent<T extends DSet.Entry> extends NamedEvent
protected void notifyListener (Object listener)
{
if (listener instanceof SetListener) {
((SetListener)listener).entryAdded(this);
@SuppressWarnings("unchecked") SetListener<T> setlist = (SetListener<T>)listener;
setlist.entryAdded(this);
}
}
@@ -99,7 +99,8 @@ public class EntryRemovedEvent<T extends DSet.Entry> extends NamedEvent
protected void notifyListener (Object listener)
{
if (listener instanceof SetListener) {
((SetListener)listener).entryRemoved(this);
@SuppressWarnings("unchecked") SetListener<T> setlist = (SetListener<T>)listener;
setlist.entryRemoved(this);
}
}
@@ -25,6 +25,8 @@ import com.samskivert.util.StringUtil;
import com.threerings.presents.Log;
import com.threerings.presents.net.Transport;
/**
* An entry updated event is dispatched when an entry of a {@link DSet} is updated. It can also be
* constructed to request the update of an entry and posted to the dobjmgr.
@@ -44,7 +46,22 @@ public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
*/
public EntryUpdatedEvent (int targetOid, String name, T entry, T oldEntry)
{
super(targetOid, name);
this(targetOid, name, entry, oldEntry, Transport.DEFAULT);
}
/**
* Constructs a new entry updated event on the specified target object for the specified set
* name and with the supplied updated entry.
*
* @param targetOid the object id of the object to whose set we will add an entry.
* @param name the name of the attribute in which to update the specified entry.
* @param entry the entry to update.
* @param oldEntry the previous value of the entry.
* @param transport a hint as to the type of transport desired for the event.
*/
public EntryUpdatedEvent (int targetOid, String name, T entry, T oldEntry, Transport transport)
{
super(targetOid, name, transport);
_entry = entry;
_oldEntry = oldEntry;
}
@@ -101,7 +118,8 @@ public class EntryUpdatedEvent<T extends DSet.Entry> extends NamedEvent
protected void notifyListener (Object listener)
{
if (listener instanceof SetListener) {
((SetListener)listener).entryUpdated(this);
@SuppressWarnings("unchecked") SetListener<T> setlist = (SetListener<T>)listener;
setlist.entryUpdated(this);
}
}
@@ -23,6 +23,8 @@ package com.threerings.presents.dobj;
import com.samskivert.util.StringUtil;
import com.threerings.presents.net.Transport;
/**
* Used to dispatch an invocation notification from the server to a
* client.
@@ -47,7 +49,27 @@ public class InvocationNotificationEvent extends DEvent
public InvocationNotificationEvent (
int targetOid, short receiverId, int methodId, Object[] args)
{
super(targetOid);
this(targetOid, receiverId, methodId, args, Transport.DEFAULT);
}
/**
* Constructs a new invocation notification event on the specified
* target object with the supplied receiver id, method id and
* arguments.
*
* @param targetOid the object id of the object on which the event is
* to be dispatched.
* @param receiverId identifies the receiver to which this notification
* is being dispatched.
* @param methodId the id of the method to be invoked.
* @param args the arguments for the method. This array should contain
* only values of valid distributed object types.
* @param transport a hint as to the type of transport desired for the event.
*/
public InvocationNotificationEvent (
int targetOid, short receiverId, int methodId, Object[] args, Transport transport)
{
super(targetOid, transport);
_receiverId = receiverId;
_methodId = (byte)methodId;
_args = args;
@@ -23,6 +23,8 @@ package com.threerings.presents.dobj;
import com.samskivert.util.StringUtil;
import com.threerings.presents.net.Transport;
/**
* Used to dispatch an invocation request from the client to the server.
*
@@ -44,7 +46,25 @@ public class InvocationRequestEvent extends DEvent
public InvocationRequestEvent (
int targetOid, int invCode, int methodId, Object[] args)
{
super(targetOid);
this(targetOid, invCode, methodId, args, Transport.DEFAULT);
}
/**
* Constructs a new invocation request event on the specified target
* object with the supplied code, method and arguments.
*
* @param targetOid the object id of the object on which the event is
* to be dispatched.
* @param invCode the invocation provider identification code.
* @param methodId the id of the method to be invoked.
* @param args the arguments for the method. This array should contain
* only values of valid distributed object types.
* @param transport a hint as to the type of transport desired for the event.
*/
public InvocationRequestEvent (
int targetOid, int invCode, int methodId, Object[] args, Transport transport)
{
super(targetOid, transport);
_invCode = invCode;
_methodId = (byte)methodId;
_args = args;
@@ -23,6 +23,8 @@ package com.threerings.presents.dobj;
import com.samskivert.util.StringUtil;
import com.threerings.presents.net.Transport;
/**
* Used to dispatch an invocation response from the server to the client.
*
@@ -44,7 +46,25 @@ public class InvocationResponseEvent extends DEvent
public InvocationResponseEvent (
int targetOid, int requestId, int methodId, Object[] args)
{
super(targetOid);
this(targetOid, requestId, methodId, args, Transport.DEFAULT);
}
/**
* Constructs a new invocation response event on the specified target
* object with the supplied code, method and arguments.
*
* @param targetOid the object id of the object on which the event is
* to be dispatched.
* @param requestId the id of the request to which we are responding.
* @param methodId the method to be invoked.
* @param args the arguments for the method. This array should contain
* only values of valid distributed object types.
* @param transport a hint as to the type of transport desired for the event.
*/
public InvocationResponseEvent (
int targetOid, int requestId, int methodId, Object[] args, Transport transport)
{
super(targetOid, transport);
_requestId = (short)requestId;
_methodId = (byte)methodId;
_args = args;
@@ -23,6 +23,8 @@ package com.threerings.presents.dobj;
import com.samskivert.util.StringUtil;
import com.threerings.presents.net.Transport;
/**
* A message event is used to dispatch a message to all subscribers of a
* distributed object without actually changing any of the fields of the
@@ -46,7 +48,23 @@ public class MessageEvent extends NamedEvent
*/
public MessageEvent (int targetOid, String name, Object[] args)
{
super(targetOid, name);
this(targetOid, name, args, Transport.DEFAULT);
}
/**
* Constructs a new message event on the specified target object with
* the supplied name and arguments.
*
* @param targetOid the object id of the object whose attribute has
* changed.
* @param name the name of the message event.
* @param args the arguments for this message. This array should
* contain only values of valid distributed object types.
* @param transport a hint as to the type of transport desired for the event.
*/
public MessageEvent (int targetOid, String name, Object[] args, Transport transport)
{
super(targetOid, name, transport);
_args = args;
}
@@ -21,6 +21,8 @@
package com.threerings.presents.dobj;
import com.threerings.presents.net.Transport;
/**
* A common parent class for all events that are associated with a name
* (in some cases a field name, in other cases just an identifying name).
@@ -36,7 +38,20 @@ public abstract class NamedEvent extends DEvent
*/
public NamedEvent (int targetOid, String name)
{
super(targetOid);
this(targetOid, name, Transport.DEFAULT);
}
/**
* Constructs a new named event for the specified target object with
* the supplied attribute name.
*
* @param targetOid the object id of the object in question.
* @param name the name associated with this event.
* @param transport a hint as to the type of transport desired for the event.
*/
public NamedEvent (int targetOid, String name, Transport transport)
{
super(targetOid, transport);
_name = name;
}