Brought code into line with the new streaming world order.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1606 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2002-07-23 05:52:49 +00:00
parent 2330afc3cd
commit c3191b9170
42 changed files with 805 additions and 1232 deletions
@@ -1,5 +1,5 @@
//
// $Id: ClientDObjectMgr.java,v 1.15 2002/07/17 01:54:16 mdb Exp $
// $Id: ClientDObjectMgr.java,v 1.16 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.client;
@@ -77,13 +77,8 @@ public class ClientDObjectMgr
// inherit documentation from the interface
public void postEvent (DEvent event)
{
// we can cast the event to a typed event because only typed
// events will be kicking around on the client; bare DEvent
// instances are only used for internal messages on the server
TypedEvent tevent = (TypedEvent)event;
// send a forward event request to the server
_comm.postMessage(new ForwardEventRequest(tevent));
_comm.postMessage(new ForwardEventRequest(event));
}
// inherit documentation from the interface
@@ -1,19 +1,28 @@
//
// $Id: Communicator.java,v 1.20 2002/07/12 03:49:02 mdb Exp $
// $Id: Communicator.java,v 1.21 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.client;
import java.io.*;
import java.net.Socket;
import java.net.InetAddress;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import com.samskivert.io.NestableIOException;
import com.samskivert.util.LoopingThread;
import com.samskivert.util.Queue;
import com.threerings.io.FramedInputStream;
import com.threerings.io.FramingOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.dobj.DObjectManager;
import com.threerings.presents.io.*;
import com.threerings.presents.io.ObjectStreamException;
import com.threerings.presents.net.*;
/**
@@ -166,6 +175,7 @@ public class Communicator
}
Log.info("Connection failed: " + ioe);
Log.logStackTrace(ioe);
// let the client know that things went south
_client.notifyObservers(Client.CLIENT_CONNECTION_FAILED, ioe);
@@ -226,6 +236,10 @@ public class Communicator
}
_socket = null;
// clear these out because they are probably large and in charge
_oin = null;
_oout = null;
// let the client observers know that we're logged off
_client.notifyObservers(Client.CLIENT_DID_LOGOFF, null);
@@ -241,8 +255,12 @@ public class Communicator
protected void sendMessage (UpstreamMessage msg)
throws IOException
{
// first we flatten the message so that we can measure it's length
TypedObjectFactory.writeTo(_dout, msg);
// Log.info("Sending message " + msg + ".");
// first we write the message so that we can measure it's length
_oout.writeObject(msg);
_oout.flush();
// then write the framed message to actual output stream
_fout.writeFrameAndReset(_out);
}
@@ -261,9 +279,15 @@ public class Communicator
// hits EOF or if something goes awry)
while (!_fin.readFrame(_in));
// then use the typed object factory to read and decode the
// proper downstream message instance
return (DownstreamMessage)TypedObjectFactory.readFrom(_din);
try {
DownstreamMessage msg = (DownstreamMessage)_oin.readObject();
// Log.info("Received message " + msg + ".");
return msg;
} catch (ClassNotFoundException cnfe) {
throw new NestableIOException(
"Unable to decode incoming message.", cnfe);
}
}
/**
@@ -328,9 +352,11 @@ public class Communicator
// our messages are framed (preceded by their length), so we
// use these helper streams to manage the framing
_fin = new FramedInputStream();
_din = new DataInputStream(_fin);
_fout = new FramingOutputStream();
_dout = new DataOutputStream(_fout);
// create our object input and output streams
_oin = new ObjectInputStream(_fin);
_oout = new ObjectOutputStream(_fout);
}
protected void logon ()
@@ -370,10 +396,6 @@ public class Communicator
// process the message
processMessage(msg);
} catch (ObjectStreamException ose) {
Log.warning("Error decoding message: " + ose);
Log.logStackTrace(ose);
} catch (InterruptedIOException iioe) {
// somebody set up us the bomb! we've been interrupted
// which means that we're being shut down, so we just
@@ -474,10 +496,6 @@ public class Communicator
/** This is used to terminate the writer thread. */
protected static class TerminationMessage extends UpstreamMessage
{
public short getType ()
{
return -1;
}
}
protected Client _client;
@@ -491,11 +509,11 @@ public class Communicator
/** We use this to frame our upstream messages. */
protected FramingOutputStream _fout;
protected DataOutputStream _dout;
protected ObjectOutputStream _oout;
/** We use this to frame our downstream messages. */
protected FramedInputStream _fin;
protected DataInputStream _din;
protected ObjectInputStream _oin;
protected ClientDObjectMgr _omgr;
}
@@ -1,14 +1,15 @@
//
// $Id: AttributeChangedEvent.java,v 1.11 2002/02/01 23:32:37 mdb Exp $
// $Id: AttributeChangedEvent.java,v 1.12 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import com.threerings.presents.io.ValueMarshaller;
import com.samskivert.util.StringUtil;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* An attribute changed event is dispatched when a single attribute of a
@@ -17,11 +18,8 @@ import com.threerings.presents.io.ValueMarshaller;
*
* @see DObjectManager#postEvent
*/
public class AttributeChangedEvent extends TypedEvent
public class AttributeChangedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 1;
/**
* Constructs a new attribute changed event on the specified target
* object with the supplied attribute name and value.
@@ -121,28 +119,26 @@ public class AttributeChangedEvent extends TypedEvent
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
ValueMarshaller.writeTo(out, _value);
out.writeObject(_value);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
_value = ValueMarshaller.readFrom(in);
_value = in.readObject();
}
// documentation inherited
@@ -159,7 +155,8 @@ public class AttributeChangedEvent extends TypedEvent
buf.append("CHANGE:");
super.toString(buf);
buf.append(", name=").append(_name);
buf.append(", value=").append(_value);
buf.append(", value=");
StringUtil.toString(buf, _value);
}
protected String _name;
@@ -1,14 +1,14 @@
//
// $Id: AttributesChangedEvent.java,v 1.9 2002/02/01 23:32:37 mdb Exp $
// $Id: AttributesChangedEvent.java,v 1.10 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.samskivert.util.StringUtil;
import com.threerings.presents.io.ValueMarshaller;
/**
* An attribute<em>s</em> changed event is dispatched when multiple
@@ -17,11 +17,8 @@ import com.threerings.presents.io.ValueMarshaller;
*
* @see DObjectManager#postEvent
*/
public class AttributesChangedEvent extends TypedEvent
public class AttributesChangedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 2;
/**
* Constructs a new attribute changed event on the specified target
* object with the supplied attribute name and value.
@@ -170,32 +167,33 @@ public class AttributesChangedEvent extends TypedEvent
return true;
}
public short getType ()
{
return TYPE;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeInt(_count);
for (int i = 0; i < _count; i++) {
out.writeUTF(_names[i]);
ValueMarshaller.writeTo(out, _values[i]);
for (int ii = 0; ii < _count; ii++) {
out.writeUTF(_names[ii]);
out.writeObject(_values[ii]);
}
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_count = in.readInt();
_names = new String[_count];
_values = new Object[_count];
for (int i = 0; i < _count; i++) {
_names[i] = in.readUTF();
_values[i] = ValueMarshaller.readFrom(in);
for (int ii = 0; ii < _count; ii++) {
_names[ii] = in.readUTF();
_values[ii] = in.readObject();
}
}
@@ -203,8 +201,10 @@ public class AttributesChangedEvent extends TypedEvent
{
buf.append("CHANGES:");
super.toString(buf);
buf.append(", names=").append(StringUtil.toString(_names));
buf.append(", values=").append(StringUtil.toString(_values));
buf.append(", names=");
StringUtil.toString(buf, _names);
buf.append(", values=");
StringUtil.toString(buf, _values);
}
protected int _count;
@@ -1,16 +1,15 @@
//
// $Id: CompoundEvent.java,v 1.4 2002/03/21 01:58:10 mdb Exp $
// $Id: CompoundEvent.java,v 1.5 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.util.StreamableArrayList;
/**
* Used to manage and submit groups of events on a collection of
@@ -18,11 +17,8 @@ import com.threerings.presents.io.TypedObjectFactory;
*
* @see DObject#startTransaction
*/
public class CompoundEvent extends TypedEvent
public class CompoundEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 50;
/**
* Constructs a blank compound event in preparation for
* unserialization.
@@ -38,6 +34,7 @@ public class CompoundEvent extends TypedEvent
{
super(0); // we don't have a single target object oid
_omgr = omgr;
_events = new StreamableArrayList();
}
/**
@@ -58,7 +55,7 @@ public class CompoundEvent extends TypedEvent
* part of the entire transaction if it is committed or discarded if
* the transaction is cancelled.
*/
public void postEvent (TypedEvent event)
public void postEvent (DEvent event)
{
_events.add(event);
}
@@ -123,34 +120,24 @@ public class CompoundEvent extends TypedEvent
return false;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
int ecount = _events.size();
out.writeInt(ecount);
for (int i = 0; i < ecount; i++) {
TypedEvent event = (TypedEvent)_events.get(i);
TypedObjectFactory.writeTo(out, event);
}
super.writeObject(out);
out.writeObject(_events);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
int ecount = in.readInt();
for (int i = 0; i < ecount; i++) {
_events.add(TypedObjectFactory.readFrom(in));
}
super.readObject(in);
_events = (StreamableArrayList)in.readObject();
}
/**
@@ -181,13 +168,13 @@ public class CompoundEvent extends TypedEvent
/** The object manager that we'll post ourselves to when we're
* committed. */
protected DObjectManager _omgr;
/** A list of the events associated with this compound event. */
protected ArrayList _events = new ArrayList();
protected transient DObjectManager _omgr;
/** A list of the dobject participants in this transaction. They will
* be notified when we are committed or cancelled so that they can
* stop posting their events to us. */
protected ArrayList _participants;
protected transient ArrayList _participants;
/** A list of the events associated with this compound event. */
protected StreamableArrayList _events;
}
@@ -1,16 +1,38 @@
//
// $Id: DEvent.java,v 1.10 2002/03/20 19:06:55 mdb Exp $
// $Id: DEvent.java,v 1.11 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.IOException;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
/**
* 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 modifications to the object
* that defines the delivery group (the object's subscribers).
*/
public abstract class DEvent
public abstract class DEvent implements Streamable
{
/**
* A zero argument constructor for unserialization from yon network.
*/
public DEvent ()
{
}
/**
* Constructs a new distributed object event that pertains to the
* specified distributed object.
*/
public DEvent (int targetOid)
{
_toid = targetOid;
}
/**
* Returns the oid of the object that is the target of this event.
*/
@@ -57,15 +79,6 @@ public abstract class DEvent
_soid = sourceOid;
}
/**
* Constructs a new distributed object event that pertains to the
* specified distributed object.
*/
protected DEvent (int targetOid)
{
_toid = targetOid;
}
/**
* Events with associated listener interfaces should implement this
* function and notify the supplied listener if it implements their
@@ -78,6 +91,26 @@ public abstract class DEvent
// the default is to do nothing
}
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
out.defaultWriteObject();
out.writeInt(_toid);
}
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
_toid = in.readInt();
}
/**
* Constructs and returns a string representation of this event.
*/
@@ -105,5 +138,5 @@ public abstract class DEvent
protected int _toid;
/** The oid of the client that generated this event. */
protected int _soid = -1;
protected transient int _soid = -1;
}
@@ -1,13 +1,19 @@
//
// $Id: DObject.java,v 1.45 2002/07/18 00:41:59 mdb Exp $
// $Id: DObject.java,v 1.46 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import com.samskivert.util.ListUtil;
import com.samskivert.util.StringUtil;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
import com.threerings.presents.Log;
/**
@@ -84,7 +90,7 @@ import com.threerings.presents.Log;
* byte[], short[], int[], long[], float[], double[], String[]
* </pre></code>
*/
public class DObject
public class DObject implements Streamable
{
/**
* Returns the object id of this object. All objects in the system
@@ -473,8 +479,12 @@ public class DObject
public String toString ()
{
StringBuffer buf = new StringBuffer();
buf.append("[oid=").append(_oid).append(", ");
StringUtil.fieldsToString(buf, this);
if (buf.length() > 0) {
buf.insert(0, ", ");
}
buf.insert(0, _oid);
buf.insert(0, "[oid=");
return buf.append("]").toString();
}
@@ -482,7 +492,7 @@ public class DObject
* Posts the specified event either to our dobject manager or to the
* compound event for which we are currently transacting.
*/
public void postEvent (TypedEvent event)
public void postEvent (DEvent event)
{
if (_tevent != null) {
_tevent.postEvent(event);
@@ -592,6 +602,26 @@ public class DObject
_tevent.cancel();
}
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
out.defaultWriteObject();
out.writeInt(_oid);
}
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
_oid = in.readInt();
}
/**
* Removes this object from participation in any transaction in which
* it might be taking part.
@@ -647,8 +677,7 @@ public class DObject
try {
DSet set = (DSet)getAttribute(name);
// dispatch an entry added event
postEvent(new EntryAddedEvent(
_oid, name, entry, !set.homogenous()));
postEvent(new EntryAddedEvent(_oid, name, entry));
} catch (ObjectAccessException oae) {
Log.warning("Unable to request entryAdd [name=" + name +
@@ -673,8 +702,7 @@ public class DObject
try {
DSet set = (DSet)getAttribute(name);
// dispatch an entry updated event
postEvent(new EntryUpdatedEvent(
_oid, name, entry, !set.homogenous()));
postEvent(new EntryUpdatedEvent(_oid, name, entry));
} catch (ObjectAccessException oae) {
Log.warning("Unable to request entryUpdate [name=" + name +
@@ -683,7 +711,7 @@ public class DObject
}
/** Our object id. */
protected transient int _oid;
protected int _oid;
/** A reference to our object manager. */
protected transient DObjectManager _omgr;
+47 -171
View File
@@ -1,17 +1,18 @@
//
// $Id: DSet.java,v 1.16 2002/03/18 23:21:26 mdb Exp $
// $Id: DSet.java,v 1.17 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Iterator;
import com.samskivert.util.StringUtil;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
import com.threerings.presents.Log;
import com.threerings.presents.io.Streamable;
/**
* The distributed set class provides a means by which an unordered set of
@@ -19,24 +20,17 @@ import com.threerings.presents.io.Streamable;
* added to and removed from the set, requests for which will generate
* events much like other distributed object fields.
*
* <p> A set can be either homogenous, whereby the type of object to be
* contained in the set is configured before the set is used and does not
* change; or heterogenous, whereby a set can contain any type of entry as
* long as it implements {@link Entry}. Homogenous sets take advantage of
* their homogeneity by not transfering the classname of each entry as it
* is sent over the wire.
*
* <p> Classes that wish to act as set entries must implement the {@link
* Entry} interface which extends {@link Streamable} and adds the
* requirement that the object provide a key which will be used to
* identify entry equality. Thus an entry is declared to be in a set of
* the object returned by that entry's <code>geyKey()</code> method is
* equal (using <code>equal()</code>) to the entry returned by the
* <code>getKey()</code> method of some other entry in the set.
* Additionally, in the case of entry removal, only the key for the entry
* to be removed will be transmitted with the removal event to save
* network bandwidth. Lastly, the object returned by <code>getKey()</code>
* must be a valid distributed object type.
* the object returned by that entry's {@link Entry#getKey} method is
* equal (using {@link Object#equal}) to the entry returned by the {@link
* Entry#getKey} method of some other entry in the set. Additionally, in
* the case of entry removal, only the key for the entry to be removed
* will be transmitted with the removal event to save network
* bandwidth. Lastly, the object returned by {@link Entry#getKey} must be
* a {@link Streamable} type.
*/
public class DSet
implements Streamable, Cloneable
@@ -54,35 +48,6 @@ public class DSet
public Object getKey ();
}
/**
* Constructs a distributed set that will contain the specified entry
* type.
*/
public DSet (Class entryType)
{
setEntryType(entryType);
}
/**
* Creates a distributed set and populates it with values from the
* supplied iterator. This should be done before the set is unleashed
* into the wild distributed object world because no associated entry
* added events will be generated. Additionally, this operation does
* not check for duplicates when adding entries, so one should be sure
* that the iterator contains only unique entries.
*
* @param entryType the type of entries that will be stored in this
* set. <em>Only</em> entries of this <em>exact</em> type may be
* stored in the set.
* @param source an iterator from which we will initially populate the
* set.
*/
public DSet (Class entryType, Iterator source)
{
this(source);
setEntryType(entryType);
}
/**
* Creates a distributed set and populates it with values from the
* supplied iterator. This should be done before the set is unleashed
@@ -111,39 +76,12 @@ public class DSet
}
/**
* Constructs a distributed set without specifying the entry type. The
* set will assume that it is heterogenous, unless a homogenous class
* type is otherwise specified via {@link #setEntryType}.
* Constructs an empty distributed set.
*/
public DSet ()
{
}
/**
* Returns true if this set contains only entries of exactly the same
* type, false if not.
*/
public boolean homogenous ()
{
return _entryType != null;
}
/**
* Indicates what type of entries will be stored in this set. This can
* be called multiple times before the set is used (in the event that
* one wishes to further specialize the contents of a set that has
* already been configured to use a particular entry type), but once
* the set goes into use, it must not be changed. Also bear in mind
* that the class of entries added to the set are not checked at
* runtime, and adding entries of invalid class will simply result in
* the serialization mechanism failing when an event is dispatched to
* broadcast the addition of an entry.
*/
public void setEntryType (Class entryType)
{
_entryType = entryType;
}
/**
* Returns the number of entries in this set.
*/
@@ -341,113 +279,54 @@ public class DSet
return false;
}
/**
* Serializes this instance to the supplied output stream.
*/
public void writeTo (DataOutputStream out)
throws IOException
{
if (_entryType == null) {
out.writeUTF("");
} else {
out.writeUTF(_entryType.getName());
}
out.writeInt(_size);
int elength = _entries.length;
for (int i = 0; i < elength; i++) {
Entry elem = _entries[i];
if (elem != null) {
if (_entryType == null) {
out.writeUTF(elem.getClass().getName());
}
elem.writeTo(out);
}
}
}
/**
* Unserializes this instance from the supplied input stream.
*/
public void readFrom (DataInputStream in)
throws IOException
{
// read our entry class and forName() it (if we read an entry
// class, we're a homogenous set; otherwise we're heterogenous)
String eclass = in.readUTF();
try {
if (!StringUtil.blank(eclass)) {
_entryType = Class.forName(eclass);
}
} catch (Exception e) {
String err = "Unable to instantiate entry class [err=" + e + "]";
throw new IOException(err);
}
// find out how many entries we'll be reading
_size = in.readInt();
// make sure we can fit _size entries
expand(_size);
for (int i = 0; i < _size; i++) {
_entries[i] = readEntry(in);
}
}
/**
* Reads an entry from the wire and unserializes it. Takes into
* account whether or not we're a homogenous set.
*/
public Entry readEntry (DataInputStream in)
throws IOException
{
try {
Entry elem = null;
// instantiate the appropriate entry instance
if (_entryType != null) {
elem = (Entry)_entryType.newInstance();
} else {
elem = (Entry)Class.forName(in.readUTF()).newInstance();
}
// unserialize it and return it
elem.readFrom(in);
return elem;
} catch (Exception e) {
Log.warning("Unable to unserialize set entry " +
"[set=" + this + "].");
Log.logStackTrace(e);
return null;
}
}
/**
* Generates a shallow copy of this object.
*/
public Object clone ()
{
DSet nset = new DSet(_entryType);
DSet nset = new DSet();
nset._entries = new Entry[_entries.length];
System.arraycopy(_entries, 0, nset._entries, 0, _entries.length);
nset._size = _size;
return nset;
}
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
out.defaultWriteObject();
out.writeInt(_size);
int ecount = _entries.length;
for (int ii = 0; ii < ecount; ii++) {
if (_entries[ii] != null) {
out.writeObject(_entries[ii]);
}
}
}
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
_size = in.readInt();
_entries = new Entry[Math.max(_size, INITIAL_CAPACITY)];
for (int ii = 0; ii < _size; ii++) {
_entries[ii] = (Entry)in.readObject();
}
}
/**
* Generates a string representation of this set instance.
*/
public String toString ()
{
StringBuffer buf = new StringBuffer("[");
if (_entryType == null) {
buf.append("etype=NONE");
} else {
buf.append("etype=").append(_entryType.getName());
}
buf.append(", elems=(");
StringBuffer buf = new StringBuffer("(");
String prefix = "";
for (int i = 0; i < _entries.length; i++) {
Entry elem = _entries[i];
@@ -457,14 +336,14 @@ public class DSet
buf.append(elem);
}
}
buf.append(")]");
buf.append(")");
return buf.toString();
}
protected void expand (int index)
{
// sanity check
if (index < 0) {
if (index < 0 || index > Short.MAX_VALUE) {
Log.warning("Requested to expand to accomodate bogus index! " +
"[index=" + index + "].");
Thread.dumpStack();
@@ -490,9 +369,6 @@ public class DSet
_entries = elems;
}
/** The type of entry this set holds. */
protected Class _entryType;
/** The entries of the set (in a sparse array). */
protected Entry[] _entries = new Entry[INITIAL_CAPACITY];
@@ -1,17 +1,18 @@
//
// $Id: ElementUpdatedEvent.java,v 1.1 2002/03/19 01:10:03 mdb Exp $
// $Id: ElementUpdatedEvent.java,v 1.2 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import com.samskivert.util.StringUtil;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.io.ValueMarshaller;
/**
* An element updated event is dispatched when an element of an array
@@ -20,11 +21,8 @@ import com.threerings.presents.io.ValueMarshaller;
*
* @see DObjectManager#postEvent
*/
public class ElementUpdatedEvent extends TypedEvent
public class ElementUpdatedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 11;
/**
* Constructs a new element updated event on the specified target
* object with the supplied attribute name, element and index.
@@ -153,30 +151,28 @@ public class ElementUpdatedEvent extends TypedEvent
}
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
out.writeObject(_value);
out.writeInt(_index);
ValueMarshaller.writeTo(out, _value);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
_value = in.readObject();
_index = in.readInt();
_value = ValueMarshaller.readFrom(in);
}
// documentation inherited
@@ -193,7 +189,8 @@ public class ElementUpdatedEvent extends TypedEvent
buf.append("UPDATE:");
super.toString(buf);
buf.append(", name=").append(_name);
buf.append(", value=").append(_value);
buf.append(", value=");
StringUtil.toString(buf, _value);
buf.append(", index=").append(_index);
}
@@ -1,14 +1,16 @@
//
// $Id: EntryAddedEvent.java,v 1.7 2002/03/18 23:21:26 mdb Exp $
// $Id: EntryAddedEvent.java,v 1.8 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.samskivert.util.StringUtil;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.dobj.io.EntryUtil;
/**
* An entry added event is dispatched when an entry is added to a {@link
@@ -17,11 +19,8 @@ import com.threerings.presents.dobj.io.EntryUtil;
*
* @see DObjectManager#postEvent
*/
public class EntryAddedEvent extends TypedEvent
public class EntryAddedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 8;
/**
* Constructs a new entry added event on the specified target object
* with the supplied set attribute name and entry to add.
@@ -31,17 +30,12 @@ public class EntryAddedEvent extends TypedEvent
* @param name the name of the attribute to which to add the specified
* entry.
* @param entry the entry to add to the set attribute.
* @param qualified whether or not the entry need be qualified with
* its class when serializing (true for heterogenous sets, false for
* homogenous sets).
*/
public EntryAddedEvent (int targetOid, String name, DSet.Entry entry,
boolean qualified)
public EntryAddedEvent (int targetOid, String name, DSet.Entry entry)
{
super(targetOid);
_name = name;
_entry = entry;
_qualified = qualified;
}
/**
@@ -76,51 +70,30 @@ public class EntryAddedEvent extends TypedEvent
throws ObjectAccessException
{
DSet set = (DSet)target.getAttribute(_name);
// now that we have access to our target set, we can unflatten our
// entry (if need be)
if (_entry == null) {
try {
_entry = EntryUtil.unflatten(set, _bytes);
} catch (Exception e) {
Log.warning("Error unflattening entry " + this + ".");
Log.logStackTrace(e);
return false;
}
}
set.add(_entry);
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
EntryUtil.flatten(out, _entry, _qualified);
out.writeObject(_entry);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
// we read in the raw entry data now and decode it later when we
// have access to the object and the DSet instance that knows what
// type of entry we need to decode
int bcount = in.readInt();
_bytes = new byte[bcount];
in.readFully(_bytes, 0, bcount);
_entry = (DSet.Entry)in.readObject();
}
// documentation inherited
@@ -137,11 +110,10 @@ public class EntryAddedEvent extends TypedEvent
buf.append("ELADD:");
super.toString(buf);
buf.append(", name=").append(_name);
buf.append(", entry=").append(_entry);
buf.append(", entry=");
StringUtil.toString(buf, _entry);
}
protected String _name;
protected byte[] _bytes;
protected DSet.Entry _entry;
protected boolean _qualified;
}
@@ -1,13 +1,12 @@
//
// $Id: EntryRemovedEvent.java,v 1.8 2002/03/18 23:21:26 mdb Exp $
// $Id: EntryRemovedEvent.java,v 1.9 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.presents.io.ValueMarshaller;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* An entry removed event is dispatched when an entry is removed from a
@@ -17,11 +16,8 @@ import com.threerings.presents.io.ValueMarshaller;
*
* @see DObjectManager#postEvent
*/
public class EntryRemovedEvent extends TypedEvent
public class EntryRemovedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 9;
/**
* Constructs a new entry removed event on the specified target object
* with the supplied set attribute name and entry key to remove.
@@ -76,28 +72,26 @@ public class EntryRemovedEvent extends TypedEvent
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
ValueMarshaller.writeTo(out, _key);
out.writeObject(_key);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
_key = ValueMarshaller.readFrom(in);
_key = in.readObject();
}
// documentation inherited
@@ -1,14 +1,16 @@
//
// $Id: EntryUpdatedEvent.java,v 1.6 2002/04/18 00:31:26 mdb Exp $
// $Id: EntryUpdatedEvent.java,v 1.7 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.samskivert.util.StringUtil;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.dobj.io.EntryUtil;
/**
* An entry updated event is dispatched when an entry of a {@link DSet} is
@@ -17,11 +19,8 @@ import com.threerings.presents.dobj.io.EntryUtil;
*
* @see DObjectManager#postEvent
*/
public class EntryUpdatedEvent extends TypedEvent
public class EntryUpdatedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 10;
/**
* Constructs a new entry updated event on the specified target object
* for the specified set name and with the supplied updated entry.
@@ -31,17 +30,12 @@ public class EntryUpdatedEvent extends TypedEvent
* @param name the name of the attribute in which to update the
* specified entry.
* @param entry the entry to update.
* @param qualified whether or not the entry need be qualified with
* its class when serializing (true for heterogenous sets, false for
* homogenous sets).
*/
public EntryUpdatedEvent (int targetOid, String name, DSet.Entry entry,
boolean qualified)
public EntryUpdatedEvent (int targetOid, String name, DSet.Entry entry)
{
super(targetOid);
_name = name;
_entry = entry;
_qualified = qualified;
}
/**
@@ -77,18 +71,6 @@ public class EntryUpdatedEvent extends TypedEvent
{
DSet set = (DSet)target.getAttribute(_name);
// now that we have access to our target set, we can unflatten our
// entry (if need be)
if (_entry == null) {
try {
_entry = EntryUtil.unflatten(set, _bytes);
} catch (Exception e) {
Log.warning("Error unflattening entry " + this + ".");
Log.logStackTrace(e);
return false;
}
}
// update the entry
if (!set.update(_entry)) {
// complain if we didn't update anything
@@ -100,34 +82,26 @@ public class EntryUpdatedEvent extends TypedEvent
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
EntryUtil.flatten(out, _entry, _qualified);
out.writeObject(_entry);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
// we read in the raw entry data now and decode it later when we
// have access to the object and the DSet instance that knows what
// type of entry we need to decode
int bcount = in.readInt();
_bytes = new byte[bcount];
in.readFully(_bytes, 0, bcount);
_entry = (DSet.Entry)in.readObject();
}
// documentation inherited
@@ -144,11 +118,10 @@ public class EntryUpdatedEvent extends TypedEvent
buf.append("ELUPD:");
super.toString(buf);
buf.append(", name=").append(_name);
buf.append(", entry=").append(_entry);
buf.append(", entry=");
StringUtil.toString(buf, _entry);
}
protected String _name;
protected byte[] _bytes;
protected DSet.Entry _entry;
protected boolean _qualified;
}
@@ -1,15 +1,15 @@
//
// $Id: MessageEvent.java,v 1.8 2002/02/01 23:32:37 mdb Exp $
// $Id: MessageEvent.java,v 1.9 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import com.samskivert.util.StringUtil;
import com.threerings.presents.io.ValueMarshaller;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* A message event is used to dispatch a message to all subscribers of a
@@ -20,11 +20,8 @@ import com.threerings.presents.io.ValueMarshaller;
*
* @see DObjectManager#postEvent
*/
public class MessageEvent extends TypedEvent
public class MessageEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 3;
/**
* Constructs a new message event on the specified target object with
* the supplied name and arguments.
@@ -86,41 +83,26 @@ public class MessageEvent extends TypedEvent
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
if (_args != null) {
out.writeInt(_args.length);
for (int i = 0; i < _args.length; i++) {
ValueMarshaller.writeTo(out, _args[i]);
}
} else {
out.writeInt(0);
}
out.writeObject(_args);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
int args = in.readInt();
if (args > 0) {
_args = new Object[args];
for (int i = 0; i < args; i++) {
_args[i] = ValueMarshaller.readFrom(in);
}
}
_args = (Object[])in.readObject();
}
// documentation inherited
@@ -1,12 +1,13 @@
//
// $Id: ObjectAddedEvent.java,v 1.6 2001/10/12 00:03:03 mdb Exp $
// $Id: ObjectAddedEvent.java,v 1.7 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* An object added event is dispatched when an object is added to an
* <code>OidList</code> attribute of a distributed object. It can also be
@@ -15,11 +16,8 @@ import java.io.IOException;
*
* @see DObjectManager#postEvent
*/
public class ObjectAddedEvent extends TypedEvent
public class ObjectAddedEvent extends DEvent
{
/** 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.
@@ -73,26 +71,24 @@ public class ObjectAddedEvent extends TypedEvent
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
out.writeInt(_oid);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
_oid = in.readInt();
}
@@ -1,13 +1,14 @@
//
// $Id: ObjectDestroyedEvent.java,v 1.3 2001/10/23 23:56:12 mdb Exp $
// $Id: ObjectDestroyedEvent.java,v 1.4 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* An object destroyed event is dispatched when an object has been removed
* from the distributed object system. It can also be constructed to
@@ -15,11 +16,8 @@ import java.lang.reflect.Method;
*
* @see DObjectManager#postEvent
*/
public class ObjectDestroyedEvent extends TypedEvent
public class ObjectDestroyedEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 7;
/**
* Constructs a new object destroyed event for the specified
* distributed object.
@@ -48,12 +46,6 @@ public class ObjectDestroyedEvent extends TypedEvent
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
protected void notifyListener (Object listener)
{
@@ -1,12 +1,13 @@
//
// $Id: ObjectRemovedEvent.java,v 1.6 2001/10/12 00:03:03 mdb Exp $
// $Id: ObjectRemovedEvent.java,v 1.7 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* An object removed event is dispatched when an object is removed from an
* <code>OidList</code> attribute of a distributed object. It can also be
@@ -15,11 +16,8 @@ import java.io.IOException;
*
* @see DObjectManager#postEvent
*/
public class ObjectRemovedEvent extends TypedEvent
public class ObjectRemovedEvent extends DEvent
{
/** 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
@@ -74,30 +72,6 @@ public class ObjectRemovedEvent extends TypedEvent
return true;
}
// documentation inherited
public short getType ()
{
return TYPE;
}
// documentation inherited
public void writeTo (DataOutputStream out)
throws IOException
{
super.writeTo(out);
out.writeUTF(_name);
out.writeInt(_oid);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
{
super.readFrom(in);
_name = in.readUTF();
_oid = in.readInt();
}
// documentation inherited
protected void notifyListener (Object listener)
{
@@ -106,6 +80,28 @@ public class ObjectRemovedEvent extends TypedEvent
}
}
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeObject(out);
out.writeUTF(_name);
out.writeInt(_oid);
}
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readObject(in);
_name = in.readUTF();
_oid = in.readInt();
}
// documentation inherited
protected void toString (StringBuffer buf)
{
@@ -1,19 +1,21 @@
//
// $Id: OidList.java,v 1.4 2001/10/11 04:07:52 mdb Exp $
// $Id: OidList.java,v 1.5 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
/**
* 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
public class OidList implements Streamable
{
/**
* Creates an empty oid list.
@@ -111,6 +113,28 @@ public class OidList
return _oids[index];
}
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
out.defaultWriteObject();
out.writeInt(_size);
out.writeObject(_oids);
}
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
_size = in.readInt();
_oids = (int[])in.readObject();
}
public String toString ()
{
StringBuffer buf = new StringBuffer();
@@ -132,25 +156,6 @@ public class OidList
_oids = oids;
}
public void writeTo (DataOutputStream out)
throws IOException
{
out.writeInt(_size);
for (int i = 0; i < _size; i++) {
out.writeInt(_oids[i]);
}
}
public void readFrom (DataInputStream in)
throws IOException
{
_size = in.readInt();
_oids = new int[Math.max(DEFAULT_SIZE, _size*2)];
for (int i = 0; i < _size; i++) {
_oids[i] = in.readInt();
}
}
private int[] _oids;
private int _size;
@@ -1,13 +1,14 @@
//
// $Id: ReleaseLockEvent.java,v 1.5 2002/02/01 23:32:37 mdb Exp $
// $Id: ReleaseLockEvent.java,v 1.6 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* A release lock event is dispatched at the end of a chain of events to
* release a lock that is intended to prevent some application defined
@@ -19,11 +20,8 @@ import java.lang.reflect.Method;
*
* @see DObjectManager#postEvent
*/
public class ReleaseLockEvent extends TypedEvent
public class ReleaseLockEvent extends DEvent
{
/** The typed object code for this event. */
public static final short TYPE = TYPE_BASE + 6;
/**
* Constructs a new release lock event for the specified target object
* with the supplied lock name.
@@ -65,22 +63,23 @@ public class ReleaseLockEvent extends TypedEvent
return false;
}
public short getType ()
{
return TYPE;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_name);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_name = in.readUTF();
}
@@ -1,65 +0,0 @@
//
// $Id: TypedEvent.java,v 1.2 2001/10/11 04:07:52 mdb Exp $
package com.threerings.presents.dobj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.presents.io.TypedObject;
/**
* A typed event is one that can be transmitted over the network. All
* event classes that will be shared between the client and server should
* derive from this class and be registered with the typed object factory
* so that they can be serialized and unserialized.
*/
public abstract class TypedEvent extends DEvent implements TypedObject
{
/**
* All event derived classes should base their typed object code on
* this base value.
*/
public static final short TYPE_BASE = 400;
/**
* Constructs a typed event, passing the target object id on to the
* <code>DEvent</code> constructor.
*/
public TypedEvent (int targetOid)
{
super(targetOid);
}
/**
* Constructs a blank typed event instance that will be unserialized
* from the network.
*/
public TypedEvent ()
{
super(0);
}
/**
* Derived classes should override this function to write their fields
* out to the supplied data output stream. They <em>must</em> be sure
* to first call <code>super.writeTo()</code>.
*/
public void writeTo (DataOutputStream out)
throws IOException
{
out.writeInt(_toid);
}
/**
* Derived classes should override this function to read their fields
* from the supplied data input stream. They <em>must</em> be sure to
* first call <code>super.readFrom()</code>.
*/
public void readFrom (DataInputStream in)
throws IOException
{
_toid = in.readInt();
}
}
@@ -1,65 +0,0 @@
//
// $Id: DObjectFactory.java,v 1.12 2002/07/18 00:42:30 mdb Exp $
package com.threerings.presents.dobj.io;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.io.Marshaller;
import com.threerings.presents.io.ObjectStreamException;
/**
* The distributed object factory is responsible for marshalling and
* unmarshalling distributed objects to and from streams so that they can
* be communicated between the client and server.
*/
public class DObjectFactory
{
/**
* Writes the supplied distributed object out to the specified data
* output stream.
*/
public static void writeTo (DataOutputStream out, DObject dobj)
throws IOException
{
// Log.info("Marshalling object: " + dobj);
// write the class of the object to the stream
out.writeUTF(dobj.getClass().getName());
// write out the oid
out.writeInt(dobj.getOid());
// then use the marshaller to write the object itself
Marshaller.writeObject(out, dobj);
}
/**
* Reads a distributed object from the specified input stream.
*/
public static DObject readFrom (DataInputStream in)
throws IOException
{
try {
// read in the class name and create an instance of that class
Class clazz = Class.forName(in.readUTF());
DObject dobj = (DObject)clazz.newInstance();
dobj.setOid(in.readInt()); // read and set the oid
// Log.info("Unmarshalling object " +
// "[class=" + dobj.getClass().getName() +
// ", object=" + dobj + "].");
// use a marshaller to reconstitute the object from the stream
Marshaller.readObject(in, dobj);
return dobj;
} catch (Exception e) {
String errmsg = "Failure unserializing dobj";
throw new ObjectStreamException(errmsg, e);
}
}
}
@@ -1,89 +0,0 @@
//
// $Id: EntryUtil.java,v 1.5 2002/03/18 23:21:26 mdb Exp $
package com.threerings.presents.dobj.io;
import java.io.*;
import com.threerings.presents.Log;
import com.threerings.presents.dobj.DSet;
/**
* Routines to simplify the process of moving set entries over the wire.
* Because we don't know the type of the entry when the event is
* unserialized (we only know later when the event is applied to the
* object and the event has access to the target set object), then we need
* to do some jockeying.
*/
public class EntryUtil
{
/**
* Flattens the supplied entry into a byte array, counts the number of
* bytes in the array and writes the count followed by the bytes to
* the supplied data output stream. This method should really only be
* called by the conmgr thread, but we synchronize just in case
* someone decides to write an event out in some other peculiar
* context; uncontested syncs are pretty fast.
*/
public static synchronized void flatten (
DataOutputStream out, DSet.Entry entry, boolean qualified)
throws IOException
{
// write the entry classname out if requested
if (qualified) {
_dout.writeUTF(entry.getClass().getName());
}
entry.writeTo(_dout);
_dout.flush();
out.writeInt(_bout.size());
_bout.writeTo(out);
_bout.reset();
}
/**
* Unflattens an entry given the serialized entry data. We know
* this will always be called on the dobjmgr thread, so we need not
* synchronize.
*/
public static DSet.Entry unflatten (DSet set, byte[] data)
throws IOException
{
_bin.setBytes(data);
return set.readEntry(_din);
}
/**
* We extend byte array input stream to avoid having to create a new
* input stream every time we unserialize an entry. Our extensions
* allow us to repurpose this input stream to read from a new byte
* array each time we unserialize.
*/
protected static class ReByteArrayInputStream extends ByteArrayInputStream
{
public ReByteArrayInputStream ()
{
super(new byte[0]);
}
public void setBytes (byte[] bytes)
{
buf = bytes;
pos = 0;
count = buf.length;
mark = 0;
}
}
/** Used when serializing entries. */
protected static ByteArrayOutputStream _bout = new ByteArrayOutputStream();
/** Used when serializing entries. */
protected static DataOutputStream _dout = new DataOutputStream(_bout);
/** Used when unserializing entries. */
protected static ReByteArrayInputStream _bin =
new ReByteArrayInputStream();
/** Used when unserializing entries. */
protected static DataInputStream _din = new DataInputStream(_bin);
}
@@ -1,19 +1,15 @@
//
// $Id: AuthRequest.java,v 1.7 2001/10/11 04:07:53 mdb Exp $
// $Id: AuthRequest.java,v 1.8 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
public class AuthRequest extends UpstreamMessage
{
/** The code for an auth request. */
public static final short TYPE = TYPE_BASE + 0;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -30,28 +26,29 @@ public class AuthRequest extends UpstreamMessage
_creds = creds;
}
public short getType ()
{
return TYPE;
}
public Credentials getCredentials ()
{
return _creds;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
TypedObjectFactory.writeTo(out, _creds);
super.writeObject(out);
out.writeObject(_creds);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
_creds = (Credentials)TypedObjectFactory.readFrom(in);
super.readObject(in);
_creds = (Credentials)in.readObject();
}
public String toString ()
@@ -1,13 +1,12 @@
//
// $Id: AuthResponse.java,v 1.11 2002/03/05 05:39:52 mdb Exp $
// $Id: AuthResponse.java,v 1.12 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.dobj.io.DObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* The auth response communicates authentication success or failure as
@@ -18,9 +17,6 @@ import com.threerings.presents.dobj.io.DObjectFactory;
*/
public class AuthResponse extends DownstreamMessage
{
/** The code for an auth response. */
public static final short TYPE = TYPE_BASE + 0;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -42,23 +38,24 @@ public class AuthResponse extends DownstreamMessage
return _data;
}
public short getType ()
{
return TYPE;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
DObjectFactory.writeTo(out, _data);
super.writeObject(out);
out.writeObject(_data);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
_data = (AuthResponseData)DObjectFactory.readFrom(in);
super.readObject(in);
_data = (AuthResponseData)in.readObject();
}
public String toString ()
@@ -1,13 +1,12 @@
//
// $Id: BootstrapNotification.java,v 1.3 2001/10/11 04:07:53 mdb Exp $
// $Id: BootstrapNotification.java,v 1.4 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.dobj.io.DObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
/**
* A bootstrap notification is delivered to the client once the server has
@@ -19,9 +18,6 @@ import com.threerings.presents.dobj.io.DObjectFactory;
*/
public class BootstrapNotification extends DownstreamMessage
{
/** The code for a bootstrap notification. */
public static final short TYPE = TYPE_BASE + 1;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -38,28 +34,29 @@ public class BootstrapNotification extends DownstreamMessage
_data = data;
}
public short getType ()
{
return TYPE;
}
public BootstrapData getData ()
{
return _data;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
DObjectFactory.writeTo(out, _data);
super.writeObject(out);
out.writeObject(_data);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
_data = (BootstrapData)DObjectFactory.readFrom(in);
super.readObject(in);
_data = (BootstrapData)in.readObject();
}
public String toString ()
@@ -1,14 +1,13 @@
//
// $Id: Credentials.java,v 1.7 2001/10/11 04:07:53 mdb Exp $
// $Id: Credentials.java,v 1.8 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.io.TypedObject;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.Streamable;
/**
* Credentials are supplied by the client implementation and sent along to
@@ -24,14 +23,8 @@ import com.threerings.presents.io.TypedObjectFactory;
* that they can be instantiated prior to reconstruction from a data input
* stream.
*/
public abstract class Credentials implements TypedObject
public abstract class Credentials implements Streamable
{
/**
* All credential derived classes should base their typed object code
* on this base value.
*/
public static final short TYPE_BASE = 300;
/**
* Constructs a credentials instance with the specified username.
*/
@@ -54,24 +47,22 @@ public abstract class Credentials implements TypedObject
}
/**
* Derived classes should override this function to write their fields
* out to the supplied data output stream. They <em>must</em> be sure
* to first call <code>super.writeTo()</code>.
* Writes our custom streamable fields.
*/
public void writeTo (DataOutputStream out)
public void writeObject (ObjectOutputStream out)
throws IOException
{
out.defaultWriteObject();
out.writeUTF(_username);
}
/**
* Derived classes should override this function to read their fields
* from the supplied data input stream. They <em>must</em> be sure to
* first call <code>super.readFrom()</code>.
* Reads our custom streamable fields.
*/
public void readFrom (DataInputStream in)
throws IOException
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
in.defaultReadObject();
_username = in.readUTF();
}
@@ -1,71 +1,49 @@
//
// $Id: DownstreamMessage.java,v 1.8 2001/10/11 04:07:53 mdb Exp $
// $Id: DownstreamMessage.java,v 1.9 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.io.TypedObject;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.SimpleStreamableObject;
/**
* The <code>DownstreamMessage</code> class encapsulates a message in the
* Distributed Object Protocol that flows from the server to the
* client. Downstream messages include object subscription, event
* forwarding and session management.
* This class encapsulates a message in the distributed object protocol
* that flows from the server to the client. Downstream messages include
* object subscription, event forwarding and session management.
*/
public abstract class DownstreamMessage implements TypedObject
public abstract class DownstreamMessage extends SimpleStreamableObject
{
/**
* All downstream message derived classes should base their typed
* object code on this base value.
*/
public static final short TYPE_BASE = 200;
/**
* The message id of the upstream message with which this downstream
* message is associated (or -1 if it is not associated with any
* upstream message). Because not every downstream message class cares
* to provide an upstream message id, this field is not serialized
* when the base downstream message class is serialized. Thus derived
* classes that care about message id should take care to initialize,
* serialize and unserialize the value theirselves.
* upstream message).
*/
public short messageId = -1;
/**
* Each downstream message derived class must provide a zero argument
* constructor so that the <code>TypedObjectFactory</code> can create
* a new instance of said class prior to unserializing it.
* Writes our custom streamable fields.
*/
public DownstreamMessage ()
public void writeObject (ObjectOutputStream out)
throws IOException
{
// nothing to do...
out.defaultWriteObject();
}
/**
* Derived classes should override this function to write their fields
* out to the supplied data output stream. They <em>must</em> be sure
* to first call <code>super.writeTo()</code>.
* Reads our custom streamable fields.
*/
public void writeTo (DataOutputStream out)
throws IOException
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
// we don't do anything here, but we may want to some day
in.defaultReadObject();
}
/**
* Derived classes should override this function to read their fields
* from the supplied data input stream. They <em>must</em> be sure to
* first call <code>super.readFrom()</code>.
* Generates a string representation of this instance.
*/
public void readFrom (DataInputStream in)
throws IOException
{
// we don't do anything here, but we may want to some day
}
public String toString ()
{
return "[msgid=" + messageId + "]";
@@ -1,20 +1,17 @@
//
// $Id: EventNotification.java,v 1.10 2001/10/11 04:07:53 mdb Exp $
// $Id: EventNotification.java,v 1.11 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.dobj.TypedEvent;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.dobj.DEvent;
public class EventNotification extends DownstreamMessage
{
/** The code for an event notification. */
public static final short TYPE = TYPE_BASE + 2;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -26,42 +23,41 @@ public class EventNotification extends DownstreamMessage
/**
* Constructs an event notification for the supplied event.
*/
public EventNotification (TypedEvent event)
public EventNotification (DEvent event)
{
_event = event;
}
public short getType ()
{
return TYPE;
}
public TypedEvent getEvent ()
public DEvent getEvent ()
{
return _event;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
// write the event out to the stream
TypedObjectFactory.writeTo(out, _event);
super.writeObject(out);
out.writeObject(_event);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
// read the event in from the stream
_event = (TypedEvent)TypedObjectFactory.readFrom(in);
super.readObject(in);
_event = (DEvent)in.readObject();
}
public String toString ()
{
return "[type=EVT, msgid=" + messageId + ", evt=" + _event + "]";
return "[type=EVT, evt=" + _event + "]";
}
/** The event which we are forwarding. */
protected TypedEvent _event;
protected DEvent _event;
}
@@ -1,17 +1,15 @@
//
// $Id: FailureResponse.java,v 1.7 2001/10/11 04:07:53 mdb Exp $
// $Id: FailureResponse.java,v 1.8 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
public class FailureResponse extends DownstreamMessage
{
/** The code for a failure notification. */
public static final short TYPE = TYPE_BASE + 4;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -29,27 +27,28 @@ public class FailureResponse extends DownstreamMessage
_oid = oid;
}
public short getType ()
{
return TYPE;
}
public int getOid ()
{
return _oid;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeInt(_oid);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_oid = in.readInt();
}
@@ -1,20 +1,17 @@
//
// $Id: ForwardEventRequest.java,v 1.9 2001/10/11 04:07:53 mdb Exp $
// $Id: ForwardEventRequest.java,v 1.10 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.dobj.TypedEvent;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.dobj.DEvent;
public class ForwardEventRequest extends UpstreamMessage
{
/** The code for a forward event request. */
public static final short TYPE = TYPE_BASE + 4;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -26,45 +23,44 @@ public class ForwardEventRequest extends UpstreamMessage
/**
* Constructs a forward event request for the supplied event.
*/
public ForwardEventRequest (TypedEvent event)
public ForwardEventRequest (DEvent event)
{
_event = event;
}
public short getType ()
{
return TYPE;
}
/**
* Returns the event that we wish to have forwarded.
*/
public TypedEvent getEvent ()
public DEvent getEvent ()
{
return _event;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
// write the event out to the stream
TypedObjectFactory.writeTo(out, _event);
super.writeObject(out);
out.writeObject(_event);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
// read the event in from the stream
_event = (TypedEvent)TypedObjectFactory.readFrom(in);
super.readObject(in);
_event = (DEvent)in.readObject();
}
public String toString ()
{
return "[type=FWD, msgid=" + messageId + ", evt=" + _event + "]";
return "[type=FWD, evt=" + _event + "]";
}
/** The event which we are forwarding. */
protected TypedEvent _event;
protected DEvent _event;
}
@@ -1,13 +1,10 @@
//
// $Id: LogoffRequest.java,v 1.5 2001/10/11 04:07:53 mdb Exp $
// $Id: LogoffRequest.java,v 1.6 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
public class LogoffRequest extends UpstreamMessage
{
/** The code for a logoff request. */
public static final short TYPE = TYPE_BASE + 6;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -16,11 +13,6 @@ public class LogoffRequest extends UpstreamMessage
super();
}
public short getType ()
{
return TYPE;
}
public String toString ()
{
return "[type=LOGOFF, msgid=" + messageId + "]";
@@ -1,20 +1,17 @@
//
// $Id: ObjectResponse.java,v 1.11 2001/10/11 04:07:53 mdb Exp $
// $Id: ObjectResponse.java,v 1.12 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.io.DObjectFactory;
public class ObjectResponse extends DownstreamMessage
{
/** The code for an object repsonse. */
public static final short TYPE = TYPE_BASE + 3;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -31,28 +28,29 @@ public class ObjectResponse extends DownstreamMessage
_dobj = dobj;
}
public short getType ()
{
return TYPE;
}
public DObject getObject ()
{
return _dobj;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
DObjectFactory.writeTo(out, _dobj);
super.writeObject(out);
out.writeObject(_dobj);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
_dobj = (DObject)DObjectFactory.readFrom(in);
super.readObject(in);
_dobj = (DObject)in.readObject();
}
public String toString ()
@@ -1,17 +1,15 @@
//
// $Id: PingRequest.java,v 1.6 2002/05/28 21:56:38 mdb Exp $
// $Id: PingRequest.java,v 1.7 2002/07/23 05:52:48 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
public class PingRequest extends UpstreamMessage
{
/** The code for a ping request. */
public static final short TYPE = TYPE_BASE + 5;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -38,33 +36,32 @@ public class PingRequest extends UpstreamMessage
return _unpackStamp;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
// grab a timestamp noting when we were encoded into a raw buffer
// for delivery over the network
_packStamp = System.currentTimeMillis();
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
// grab a timestamp noting when we were decoded from a raw buffer
// after being received over the network
_unpackStamp = System.currentTimeMillis();
}
public short getType ()
{
return TYPE;
}
public String toString ()
{
return "[type=PING, msgid=" + messageId + "]";
@@ -1,19 +1,17 @@
//
// $Id: PongResponse.java,v 1.7 2002/05/28 21:56:38 mdb Exp $
// $Id: PongResponse.java,v 1.8 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
public class PongResponse extends DownstreamMessage
{
/** The code for a pong response. */
public static final short TYPE = TYPE_BASE + 5;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -61,11 +59,13 @@ public class PongResponse extends DownstreamMessage
return _unpackStamp;
}
// documentation inherited
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
// make a note of the time at which we were packed
_packStamp = System.currentTimeMillis();
@@ -83,11 +83,13 @@ public class PongResponse extends DownstreamMessage
out.writeInt(_processDelay);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
// grab a timestamp noting when we were decoded from a raw buffer
// after being received over the network
@@ -98,11 +100,6 @@ public class PongResponse extends DownstreamMessage
_processDelay = in.readInt();
}
public short getType ()
{
return TYPE;
}
public String toString ()
{
return "[type=PONG, msgid=" + messageId + "]";
@@ -1,17 +1,15 @@
//
// $Id: SubscribeRequest.java,v 1.5 2001/10/11 04:07:53 mdb Exp $
// $Id: SubscribeRequest.java,v 1.6 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
public class SubscribeRequest extends UpstreamMessage
{
/** The code for an object subscription request. */
public static final short TYPE = TYPE_BASE + 1;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -29,11 +27,6 @@ public class SubscribeRequest extends UpstreamMessage
_oid = oid;
}
public short getType ()
{
return TYPE;
}
/**
* Returns the oid of the object to which we desire subscription.
*/
@@ -42,17 +35,23 @@ public class SubscribeRequest extends UpstreamMessage
return _oid;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeInt(_oid);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_oid = in.readInt();
}
@@ -1,17 +1,15 @@
//
// $Id: UnsubscribeRequest.java,v 1.6 2001/10/11 04:07:53 mdb Exp $
// $Id: UnsubscribeRequest.java,v 1.7 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
public class UnsubscribeRequest extends UpstreamMessage
{
/** The code for an unsubscribe request. */
public static final short TYPE = TYPE_BASE + 3;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -29,11 +27,6 @@ public class UnsubscribeRequest extends UpstreamMessage
_oid = oid;
}
public short getType ()
{
return TYPE;
}
/**
* Returns the oid of the object from which we are unsubscribing.
*/
@@ -42,17 +35,23 @@ public class UnsubscribeRequest extends UpstreamMessage
return _oid;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeInt(_oid);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_oid = in.readInt();
}
@@ -1,28 +1,21 @@
//
// $Id: UpstreamMessage.java,v 1.8 2001/10/11 04:07:53 mdb Exp $
// $Id: UpstreamMessage.java,v 1.9 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.net;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import com.threerings.presents.io.TypedObject;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.io.SimpleStreamableObject;
/**
* The <code>UpstreamMessage</code> class encapsulates a message in the
* Distributed Object Protocol that flows from the client to the server.
* Upstream messages include object subscription, event forwarding and
* session management.
* This class encapsulates a message in the distributed object protocol
* that flows from the client to the server. Upstream messages include
* object subscription, event forwarding and session management.
*/
public abstract class UpstreamMessage implements TypedObject
public abstract class UpstreamMessage extends SimpleStreamableObject
{
/**
* All upstream message derived classes should base their typed object
* code on this base value.
*/
public static final short TYPE_BASE = 100;
/**
* This is a unique (within the context of a reasonable period of
* time) identifier assigned to each upstream message. The message ids
@@ -33,8 +26,8 @@ public abstract class UpstreamMessage implements TypedObject
/**
* Each upstream message derived class must provide a zero argument
* constructor so that the <code>TypedObjectFactory</code> can create
* a new instance of said class prior to unserializing it.
* constructor so that it can be unserialized when read from the
* network.
*/
public UpstreamMessage ()
{
@@ -45,25 +38,21 @@ public abstract class UpstreamMessage implements TypedObject
}
/**
* Derived classes should override this function to write their fields
* out to the supplied data output stream. They <em>must</em> be sure
* to first call <code>super.writeTo()</code>.
* Writes our custom streamable fields.
*/
public void writeTo (DataOutputStream out)
public void writeObject (ObjectOutputStream out)
throws IOException
{
out.writeShort(messageId);
out.defaultWriteObject();
}
/**
* Derived classes should override this function to read their fields
* from the supplied data input stream. They <em>must</em> be sure to
* first call <code>super.readFrom()</code>.
* Reads our custom streamable fields.
*/
public void readFrom (DataInputStream in)
throws IOException
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
messageId = in.readShort();
in.defaultReadObject();
}
public String toString ()
@@ -1,16 +1,15 @@
//
// $Id: UsernamePasswordCreds.java,v 1.6 2001/10/11 04:07:53 mdb Exp $
// $Id: UsernamePasswordCreds.java,v 1.7 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.net;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
public class UsernamePasswordCreds extends Credentials
{
public static final short TYPE = TYPE_BASE + 0;
/**
* Zero argument constructor used when unserializing an instance.
*/
@@ -28,27 +27,28 @@ public class UsernamePasswordCreds extends Credentials
_password = password;
}
public short getType ()
{
return TYPE;
}
public String getPassword ()
{
return _password;
}
public void writeTo (DataOutputStream out)
/**
* Writes our custom streamable fields.
*/
public void writeObject (ObjectOutputStream out)
throws IOException
{
super.writeTo(out);
super.writeObject(out);
out.writeUTF(_password);
}
public void readFrom (DataInputStream in)
throws IOException
/**
* Reads our custom streamable fields.
*/
public void readObject (ObjectInputStream in)
throws IOException, ClassNotFoundException
{
super.readFrom(in);
super.readObject(in);
_password = in.readUTF();
}
@@ -1,5 +1,5 @@
//
// $Id: ClientManager.java,v 1.20 2002/07/10 01:26:21 mdb Exp $
// $Id: ClientManager.java,v 1.21 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.server;
@@ -273,6 +273,7 @@ public class ClientManager implements ConnectionObserver
if (client != null) {
Log.info("Unmapped failed client [client=" + client +
", conn=" + conn + ", fault=" + fault + "].");
Log.logStackTrace(fault);
// let the client know the connection went away
client.wasUnmapped();
// and let the client know things went haywire
@@ -297,6 +298,8 @@ public class ClientManager implements ConnectionObserver
client.wasUnmapped();
} else {
// TODO: possibly remove this log message, can this happen
// normally?
Log.info("Closed unmapped connection? [conn=" + conn + "].");
Thread.dumpStack();
}
@@ -1,5 +1,5 @@
//
// $Id: PresentsClient.java,v 1.33 2002/07/10 01:25:11 mdb Exp $
// $Id: PresentsClient.java,v 1.34 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.server;
@@ -17,7 +17,6 @@ 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.TypedEvent;
import com.threerings.presents.net.BootstrapData;
import com.threerings.presents.net.BootstrapNotification;
@@ -450,10 +449,7 @@ public class PresentsClient
// forward the event to the client
Connection conn = getConnection();
if (conn != null) {
// only typed events will be forwarded to the client, so we
// need not worry that a non-typed event would make it here
TypedEvent tevent = (TypedEvent)event;
conn.postMessage(new EventNotification(tevent));
conn.postMessage(new EventNotification(event));
} else {
Log.info("Dropped event forward notification " +
"[client=" + this + ", event=" + event + "].");
@@ -1,16 +1,25 @@
//
// $Id: Connection.java,v 1.7 2002/07/10 01:23:45 mdb Exp $
// $Id: Connection.java,v 1.8 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.server.net;
import java.io.*;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import ninja2.core.io_core.nbio.*;
import com.samskivert.io.NestableIOException;
import com.threerings.io.FramedInputStream;
import com.threerings.io.FramingOutputStream;
import com.threerings.io.ObjectInputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.io.FramedInputStream;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.presents.net.UpstreamMessage;
import com.threerings.presents.net.DownstreamMessage;
import com.threerings.presents.net.UpstreamMessage;
/**
* The base connection class implements the net event handler interface
@@ -27,6 +36,8 @@ public abstract class Connection implements NetEventHandler
* @param cmgr The connection manager with which this connection is
* associated.
* @param socket The socket from which we'll be reading messages.
* @param fout The framing output stream via which we'll write
* serialized messages to the client.
*/
public Connection (ConnectionManager cmgr, NonblockingSocket socket)
throws IOException
@@ -38,11 +49,9 @@ public abstract class Connection implements NetEventHandler
// the main event polling loop
_selitem = new SelectItem(_socket, this, Selectable.READ_READY);
// create our input streams
// get a handle on our socket streams
_in = _socket.getInputStream();
_out = _socket.getOutputStream();
_fin = new FramedInputStream();
_din = new DataInputStream(_fin);
}
/**
@@ -63,15 +72,6 @@ public abstract class Connection implements NetEventHandler
return _selitem;
}
/**
* Returns the output stream associated with this connection. This
* should only be used by the connection manager.
*/
public OutputStream getOutputStream ()
{
return _out;
}
/**
* Returns the non-blocking socket object used to construct this
* connection.
@@ -130,6 +130,63 @@ public abstract class Connection implements NetEventHandler
closeSocket();
}
/**
* Returns the output stream associated with this connection. This
* should only be used by the connection manager.
*/
protected OutputStream getOutputStream ()
{
return _out;
}
/**
* Returns the object input stream associated with this connection.
* This should only be used by the connection manager.
*/
protected ObjectInputStream getObjectInputStream ()
{
return _oin;
}
/**
* Instructs this connection to inherit its streams from the supplied
* connection object. This is called by the connection manager when
* the time comes to pass streams from the authing connection to the
* running connection.
*/
protected void inheritStreams (Connection other)
{
_fin = other._fin;
_oin = other._oin;
_oout = other._oout;
}
/**
* Returns the object output stream associated with this connection
* (creating it if necessary). This should only be used by the
* connection manager.
*/
protected ObjectOutputStream getObjectOutputStream (
FramingOutputStream fout)
{
// we're lazy about creating our output stream because we may be
// inheriting it from our authing connection and we don't want to
// unnecessarily create it in that case
if (_oout == null) {
_oout = new ObjectOutputStream(fout);
}
return _oout;
}
/**
* Sets the object output stream used by this connection. This should
* obly be called by the connection manager.
*/
protected void setObjectOutputStream (ObjectOutputStream oout)
{
_oout = oout;
}
/**
* Closes the socket associated with this connection. This happens
* when we receive EOF, are requested to close down or when our
@@ -156,17 +213,33 @@ public abstract class Connection implements NetEventHandler
public void handleEvent (Selectable source, short events)
{
try {
// we're lazy about creating our input streams because we may
// be inheriting them from our authing connection and we don't
// want to unnecessarily create them in that case
if (_fin == null) {
_fin = new FramedInputStream();
_oin = new ObjectInputStream(_fin);
}
// read the available data and see if we have a whole frame
if (_fin.readFrame(_in)) {
// parse the message and pass it on
_handler.handleMessage((UpstreamMessage)
TypedObjectFactory.readFrom(_din));
UpstreamMessage msg = (UpstreamMessage)_oin.readObject();
// Log.info("Read message " + msg + ".");
_handler.handleMessage(msg);
}
} catch (EOFException eofe) {
// close down the socket gracefully
close();
} catch (ClassNotFoundException cnfe) {
Log.warning("Error reading message from socket " +
"[socket=" + _socket + ", error=" + cnfe + "].");
// deal with the failure
handleFailure(new NestableIOException(
"Unable to decode incoming message.", cnfe));
} catch (IOException ioe) {
Log.warning("Error reading message from socket " +
"[socket=" + _socket + ", error=" + ioe + "].");
@@ -191,9 +264,11 @@ public abstract class Connection implements NetEventHandler
protected SelectItem _selitem;
protected InputStream _in;
protected OutputStream _out;
protected FramedInputStream _fin;
protected DataInputStream _din;
protected ObjectInputStream _oin;
protected OutputStream _out;
protected ObjectOutputStream _oout;
protected MessageHandler _handler;
}
@@ -1,21 +1,20 @@
//
// $Id: ConnectionManager.java,v 1.19 2002/07/10 01:23:45 mdb Exp $
// $Id: ConnectionManager.java,v 1.20 2002/07/23 05:52:49 mdb Exp $
package com.threerings.presents.server.net;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import ninja2.core.io_core.nbio.*;
import com.samskivert.util.*;
import com.threerings.io.FramingOutputStream;
import com.threerings.io.ObjectOutputStream;
import com.threerings.presents.Log;
import com.threerings.presents.client.Client;
import com.threerings.presents.io.FramingOutputStream;
import com.threerings.presents.io.TypedObjectFactory;
import com.threerings.presents.net.AuthRequest;
import com.threerings.presents.net.AuthResponse;
import com.threerings.presents.net.DownstreamMessage;
@@ -61,9 +60,8 @@ public class ConnectionManager extends LoopingThread
};
_selset.add(_litem);
// we'll use these for sending messages to clients
// we'll use this for sending messages to clients
_framer = new FramingOutputStream();
_dout = new DataOutputStream(_framer);
}
/**
@@ -196,8 +194,14 @@ public class ConnectionManager extends LoopingThread
DownstreamMessage outmsg = (DownstreamMessage)tup.right;
try {
// first flatten the message (and frame it)
TypedObjectFactory.writeTo(_dout, outmsg);
// write the message via the connection's object output
// stream (which is configured to write data to our
// framing output stream)
ObjectOutputStream oout = conn.getObjectOutputStream(_framer);
// Log.info("Sending " + outmsg + ".");
oout.writeObject(outmsg);
oout.flush();
// then write framed message to real output stream
_framer.writeFrameAndReset(conn.getOutputStream());
@@ -218,6 +222,10 @@ public class ConnectionManager extends LoopingThread
try {
RunningConnection rconn =
new RunningConnection(this, conn.getSocket());
// we need to keep using the same object input and output
// streams from the beginning of the session because they
// have contextual state that needs to be preserved
rconn.inheritStreams(conn);
// wire this connection up to receive network events
_selset.add(rconn.getSelectItem());
@@ -357,7 +365,6 @@ public class ConnectionManager extends LoopingThread
protected Queue _outq = new Queue();
protected FramingOutputStream _framer;
protected DataOutputStream _dout;
protected Queue _authq = new Queue();
@@ -1,51 +0,0 @@
//
// $Id: StreamableArrayList.java,v 1.4 2002/03/20 22:58:26 mdb Exp $
package com.threerings.presents.util;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import com.threerings.presents.dobj.DSet;
import com.threerings.presents.io.Streamable;
import com.threerings.presents.io.StreamableUtil;
/**
* Provides a means by which an ordered collection of streamable instances
* (of potentially heterogenous derived classes) can be delivered over the
* network. A streamable array list can be supplied anywhere that a
* distributed object value can be supplied, but bear in mind that once
* the list is created, it's elements cannot be changed without
* rebroadcasting the entire list. It is not like a {@link DSet} which
* allows individual elements to be added or removed, or
* <code>Streamable[]</code> distributed object fields for which elements
* can be individually updated.
*/
public class StreamableArrayList
extends ArrayList implements Streamable
{
// documentation inherited
public void writeTo (DataOutputStream out)
throws IOException
{
// convert ourselves into an array and use streamable util to
// write it out
Streamable[] values = new Streamable[size()];
toArray(values);
StreamableUtil.writeStreamables(out, values);
}
// documentation inherited
public void readFrom (DataInputStream in)
throws IOException
{
// use streamable util to read in our values
Streamable[] values = StreamableUtil.readStreamables(in);
int vcount = values.length;
for (int i = 0; i < vcount; i++) {
add(values[i]);
}
}
}