diff --git a/src/java/com/threerings/presents/io/FieldMarshallerRegistry.java b/src/java/com/threerings/presents/io/FieldMarshallerRegistry.java index 28916abed..b6fa6e760 100644 --- a/src/java/com/threerings/presents/io/FieldMarshallerRegistry.java +++ b/src/java/com/threerings/presents/io/FieldMarshallerRegistry.java @@ -1,11 +1,13 @@ // -// $Id: FieldMarshallerRegistry.java,v 1.6 2001/10/11 04:07:52 mdb Exp $ +// $Id: FieldMarshallerRegistry.java,v 1.7 2001/10/12 19:28:43 mdb Exp $ package com.threerings.presents.dobj.io; import java.lang.reflect.Field; import java.util.Hashtable; + import com.threerings.presents.Log; +import com.threerings.presents.io.Streamable; /** * Field marshaller instances are registered for each type of field that @@ -24,11 +26,25 @@ public class FieldMarshallerRegistry { Class clazz = field.getType(); FieldMarshaller marsh = (FieldMarshaller)_registry.get(clazz); + + // if we don't have a marshaller registered for this specific + // class, see if the class is an instance of streamable in which + // case we stick the streamable marshaller into the registry for + // this class + if (marsh == null) { + if (clazz.isAssignableFrom(Streamable.class)) { + marsh = _streamableMarsh; + _registry.put(clazz, marsh); + } + } + + // if we still don't have a marshaller, we're out of luck if (marsh == null) { String errmsg = "No field marshaller registered for fields " + "of type " + clazz.getName() + "."; throw new IllegalArgumentException(errmsg); } + return marsh; } @@ -52,8 +68,13 @@ public class FieldMarshallerRegistry } } + /** A mapping of classes to marshallers. */ protected static Hashtable _registry = new Hashtable(); + /** Used for marshalling instances of {@link Streamable}. */ + protected static FieldMarshaller _streamableMarsh = + new StreamableFieldMarshaller(); + static { // register our field marshallers registerMarshaller(BooleanFieldMarshaller.class); diff --git a/src/java/com/threerings/presents/io/StreamableFieldMarshaller.java b/src/java/com/threerings/presents/io/StreamableFieldMarshaller.java new file mode 100644 index 000000000..c149b5708 --- /dev/null +++ b/src/java/com/threerings/presents/io/StreamableFieldMarshaller.java @@ -0,0 +1,45 @@ +// +// $Id: StreamableFieldMarshaller.java,v 1.1 2001/10/12 19:28:43 mdb Exp $ + +package com.threerings.presents.dobj.io; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; + +import com.threerings.presents.dobj.DObject; +import com.threerings.presents.io.Streamable; + +public class StreamableFieldMarshaller implements FieldMarshaller +{ + public void writeTo (DataOutputStream out, Field field, DObject dobj) + throws IOException, IllegalAccessException + { + Streamable value = (Streamable)field.get(dobj); + // we freak out if our streamable is null + if (value == null) { + throw new IllegalAccessException( + "No streamable instance to marshall!"); + } + value.writeTo(out); + } + + public void readFrom (DataInputStream in, Field field, DObject dobj) + throws IOException, IllegalAccessException + { + try { + // create a new instance into which to unmarshall the field + Streamable value = (Streamable)field.getType().newInstance(); + // unserialize it + value.readFrom(in); + // and set the value in the object + field.set(dobj, value); + + } catch (InstantiationException ie) { + throw new IOException("Unable to instantiate streamable " + + "[field=" + field + ", object=" + dobj + + ", error=" + ie + "]"); + } + } +}