diff --git a/src/java/com/threerings/presents/dobj/DObject.java b/src/java/com/threerings/presents/dobj/DObject.java
index a85a6205f..cb7f1513e 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.13 2001/07/19 19:30:14 mdb Exp $
+// $Id: DObject.java,v 1.14 2001/07/21 01:06:48 mdb Exp $
package com.threerings.cocktail.cher.dobj;
@@ -201,8 +201,7 @@ public class DObject
throws ObjectAccessException
{
try {
- Field field = getClass().getField(name);
- field.set(this, value);
+ getClass().getField(name).set(this, value);
} catch (Exception e) {
String errmsg = "Attribute setting failure [name=" + name +
@@ -211,6 +210,25 @@ public class DObject
}
}
+ /**
+ * Looks up the named attribute and returns a reference to it. This
+ * should only be used by the internals of the event dispatch
+ * mechanism and should not be called directly by users. Use the
+ * generated attribute getter methods instead.
+ */
+ public Object getAttribute (String name)
+ throws ObjectAccessException
+ {
+ try {
+ return getClass().getField(name).get(this);
+
+ } catch (Exception e) {
+ String errmsg = "Attribute getting failure [name=" + name +
+ ", error=" + e + "].";
+ throw new ObjectAccessException(errmsg);
+ }
+ }
+
/**
* Don't call this function! It initializes this distributed object
* with the supplied distributed object manager. This is called by the
diff --git a/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java b/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java
new file mode 100644
index 000000000..c57920c7f
--- /dev/null
+++ b/src/java/com/threerings/presents/dobj/ObjectAddedEvent.java
@@ -0,0 +1,108 @@
+//
+// $Id: ObjectAddedEvent.java,v 1.1 2001/07/21 01:06:48 mdb Exp $
+
+package com.threerings.cocktail.cher.dobj;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import com.threerings.cocktail.cher.dobj.io.ValueMarshaller;
+
+/**
+ * An object added event is dispatched when an object is added to an
+ * OidList attribute of a distributed object. It can also be
+ * constructed to request the addition of an oid to an
+ * OidList attribute of an object and posted to the dobjmgr.
+ *
+ * @see DObjectManager.postEvent
+ */
+public class ObjectAddedEvent extends TypedEvent
+{
+ /** The typed object code for this event. */
+ public static final short TYPE = TYPE_BASE + 4;
+
+ /**
+ * Constructs a new object added event on the specified target object
+ * with the supplied oid list attribute name and object id to add.
+ *
+ * @param targetOid the object id of the object to whose oid list we
+ * will add an oid.
+ * @param name the name of the attribute (data member) to which to add
+ * the specified oid.
+ * @param oid the oid to add to the oid list attribute.
+ */
+ public ObjectAddedEvent (int targetOid, String name, int oid)
+ {
+ super(targetOid);
+ _name = name;
+ _oid = oid;
+ }
+
+ /**
+ * Constructs a blank instance of this event in preparation for
+ * unserialization from the network.
+ */
+ public ObjectAddedEvent ()
+ {
+ }
+
+ /**
+ * Returns the name of the oid list attribute to which an oid has been
+ * added.
+ */
+ public String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the oid that has been added.
+ */
+ public int getOid ()
+ {
+ return _oid;
+ }
+
+ /**
+ * Applies this event to the object.
+ */
+ public boolean applyToObject (DObject target)
+ throws ObjectAccessException
+ {
+ OidList list = (OidList)target.getAttribute(_name);
+ list.add(_oid);
+ return true;
+ }
+
+ public short getType ()
+ {
+ return TYPE;
+ }
+
+ public void writeTo (DataOutputStream out)
+ throws IOException
+ {
+ super.writeTo(out);
+ out.writeUTF(_name);
+ out.writeInt(_oid);
+ }
+
+ public void readFrom (DataInputStream in)
+ throws IOException
+ {
+ super.readFrom(in);
+ _name = in.readUTF();
+ _oid = in.readInt();
+ }
+
+ public String toString ()
+ {
+ return "[OBJADD:targetOid=" + _toid + ", name=" + _name +
+ ", oid=" + _oid + "]";
+ }
+
+ protected String _name;
+ protected int _oid;
+}
diff --git a/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java b/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java
new file mode 100644
index 000000000..7306f56f4
--- /dev/null
+++ b/src/java/com/threerings/presents/dobj/ObjectRemovedEvent.java
@@ -0,0 +1,109 @@
+//
+// $Id: ObjectRemovedEvent.java,v 1.1 2001/07/21 01:06:48 mdb Exp $
+
+package com.threerings.cocktail.cher.dobj;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import com.threerings.cocktail.cher.dobj.io.ValueMarshaller;
+
+/**
+ * An object removed event is dispatched when an object is removed from an
+ * OidList attribute of a distributed object. It can also be
+ * constructed to request the removal of an oid from an
+ * OidList attribute of an object and posted to the dobjmgr.
+ *
+ * @see DObjectManager.postEvent
+ */
+public class ObjectRemovedEvent extends TypedEvent
+{
+ /** The typed object code for this event. */
+ public static final short TYPE = TYPE_BASE + 5;
+
+ /**
+ * Constructs a new object removed event on the specified target
+ * object with the supplied oid list attribute name and object id to
+ * remove.
+ *
+ * @param targetOid the object id of the object from whose oid list we
+ * will remove an oid.
+ * @param name the name of the attribute (data member) from which to
+ * remove the specified oid.
+ * @param oid the oid to remove from the oid list attribute.
+ */
+ public ObjectRemovedEvent (int targetOid, String name, int oid)
+ {
+ super(targetOid);
+ _name = name;
+ _oid = oid;
+ }
+
+ /**
+ * Constructs a blank instance of this event in preparation for
+ * unserialization from the network.
+ */
+ public ObjectRemovedEvent ()
+ {
+ }
+
+ /**
+ * Returns the name of the oid list attribute from which an oid has
+ * been removed.
+ */
+ public String getName ()
+ {
+ return _name;
+ }
+
+ /**
+ * Returns the oid that has been removed.
+ */
+ public int getOid ()
+ {
+ return _oid;
+ }
+
+ /**
+ * Applies this event to the object.
+ */
+ public boolean applyToObject (DObject target)
+ throws ObjectAccessException
+ {
+ OidList list = (OidList)target.getAttribute(_name);
+ list.remove(_oid);
+ return true;
+ }
+
+ public short getType ()
+ {
+ return TYPE;
+ }
+
+ public void writeTo (DataOutputStream out)
+ throws IOException
+ {
+ super.writeTo(out);
+ out.writeUTF(_name);
+ out.writeInt(_oid);
+ }
+
+ public void readFrom (DataInputStream in)
+ throws IOException
+ {
+ super.readFrom(in);
+ _name = in.readUTF();
+ _oid = in.readInt();
+ }
+
+ public String toString ()
+ {
+ return "[OBJREM:targetOid=" + _toid + ", name=" + _name +
+ ", oid=" + _oid + "]";
+ }
+
+ protected String _name;
+ protected int _oid;
+}
diff --git a/src/java/com/threerings/presents/dobj/OidList.java b/src/java/com/threerings/presents/dobj/OidList.java
new file mode 100644
index 000000000..d3a2ceba1
--- /dev/null
+++ b/src/java/com/threerings/presents/dobj/OidList.java
@@ -0,0 +1,135 @@
+//
+// $Id: OidList.java,v 1.1 2001/07/21 01:06:48 mdb Exp $
+
+package com.threerings.cocktail.cher.dobj;
+
+/**
+ * An oid list is used to store lists of object ids. The list will not
+ * allow duplicate ids. This class is not synchronized, with the
+ * expectation that all modifications of instances will take place on the
+ * dobjmgr thread.
+ */
+public class OidList
+{
+ /**
+ * Creates an empty oid list.
+ */
+ public OidList ()
+ {
+ this(DEFAULT_SIZE);
+ }
+
+ /**
+ * Creates an empty oid list with space for at least
+ * initialSize object ids before it will need to expand.
+ */
+ public OidList (int initialSize)
+ {
+ // ensure that we have at least two slots or the expansion code
+ // won't work
+ _oids = new int[Math.max(initialSize, 2)];
+ }
+
+ /**
+ * Returns the number of object ids in the list.
+ */
+ public int size ()
+ {
+ return _size;
+ }
+
+ /**
+ * Adds the specified object id to the list if it is not already
+ * there.
+ *
+ * @return true if the object was added, false if it was already in
+ * the list.
+ */
+ public boolean add (int oid)
+ {
+ // check for existence
+ for (int i = 0; i < _size; i++) {
+ if (_oids[i] == oid) {
+ return false;
+ }
+ }
+
+ // make room if necessary
+ if (_size+1 >= _oids.length) {
+ expand();
+ }
+
+ // add the oid
+ _oids[_size++] = oid;
+ return true;
+ }
+
+ /**
+ * Removes the specified oid from the list.
+ *
+ * @return true if the oid was in the list and was removed, false
+ * otherwise.
+ */
+ public boolean remove (int oid)
+ {
+ // scan for the oid in question
+ for (int i = 0; i < _size; i++) {
+ if (_oids[oid] == oid) {
+ // shift the rest of the list back one
+ System.arraycopy(_oids, i+1, _oids, i, --_size-i);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns true if the specified oid is in the list, false if not.
+ */
+ public boolean contains (int oid)
+ {
+ for (int i = 0; i < _size; i++) {
+ if (_oids[i] == oid) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the object id at the specified index. This does no boundary
+ * checking.
+ */
+ public int get (int index)
+ {
+ return _oids[index];
+ }
+
+ public String toString ()
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append("{");
+ for (int i = 0; i < _size; i++) {
+ if (i > 0) {
+ buf.append(", ");
+ }
+ buf.append(_oids[i]);
+ }
+ buf.append("}");
+ return buf.toString();
+ }
+
+ private void expand ()
+ {
+ int[] oids = new int[_oids.length*2];
+ System.arraycopy(_oids, 0, oids, 0, _oids.length);
+ _oids = oids;
+ }
+
+ private int[] _oids;
+ private int _size;
+
+ protected static final int DEFAULT_SIZE = 4;
+}
diff --git a/src/java/com/threerings/presents/io/TypedObjectRegistry.java b/src/java/com/threerings/presents/io/TypedObjectRegistry.java
index cf3db0fcb..9335dada1 100644
--- a/src/java/com/threerings/presents/io/TypedObjectRegistry.java
+++ b/src/java/com/threerings/presents/io/TypedObjectRegistry.java
@@ -1,5 +1,5 @@
//
-// $Id: TypedObjectRegistry.java,v 1.2 2001/07/19 07:48:25 mdb Exp $
+// $Id: TypedObjectRegistry.java,v 1.3 2001/07/21 01:06:49 mdb Exp $
package com.threerings.cocktail.cher.io;
@@ -58,5 +58,9 @@ public class TypedObjectRegistry
AttributesChangedEvent.class);
TypedObjectFactory.registerClass(MessageEvent.TYPE,
MessageEvent.class);
+ TypedObjectFactory.registerClass(ObjectAddedEvent.TYPE,
+ ObjectAddedEvent.class);
+ TypedObjectFactory.registerClass(ObjectRemovedEvent.TYPE,
+ ObjectRemovedEvent.class);
}
}