diff --git a/src/as/com/threerings/io/ObjectOutputStream.as b/src/as/com/threerings/io/ObjectOutputStream.as index ff9de0ae4..d0f00ef30 100644 --- a/src/as/com/threerings/io/ObjectOutputStream.as +++ b/src/as/com/threerings/io/ObjectOutputStream.as @@ -72,7 +72,7 @@ public class ObjectOutputStream } if (ObjectInputStream.DEBUG) { - log.debug("Assigning class code [code=" + cmap.code + ", class=" + cname + "]."); + log.debug("Assigning class code", "code", cmap.code, "class", cname); } writeShort(-cmap.code); diff --git a/src/as/com/threerings/io/Streamer.as b/src/as/com/threerings/io/Streamer.as index 66eae02b7..0ef6933d3 100644 --- a/src/as/com/threerings/io/Streamer.as +++ b/src/as/com/threerings/io/Streamer.as @@ -22,6 +22,7 @@ package com.threerings.io { import flash.utils.ByteArray; +import flash.utils.Dictionary; import com.threerings.util.ClassUtil; import com.threerings.util.Enum; @@ -41,33 +42,11 @@ public class Streamer { public static function getStreamer (obj :Object) :Streamer { - initStreamers(); - - var streamer :Streamer; - for each (streamer in _streamers) { - if (streamer.isStreamerFor(obj)) { - return streamer; - } - } - - // from here on out we're creating new streamers - if (obj is TypedArray) { - streamer = new ArrayStreamer((obj as TypedArray).getJavaType()); - - } else if (obj is Enum) { - streamer = new EnumStreamer(ClassUtil.getClass(obj)); - - } else if (obj is Streamable) { - streamer = new Streamer(ClassUtil.getClass(obj)); - + return getStreamerByJavaName(TypedArray(obj).getJavaType()); } else { - return null; + return getStreamerByClass(ClassUtil.getClass(obj)); } - - // add the new streamer and return it - _streamers.push(streamer); - return streamer; } public static function getStreamerByClass (clazz :Class) :Streamer @@ -78,11 +57,9 @@ public class Streamer throw new Error("Broken, TODO"); } - var streamer :Streamer; - for each (streamer in _streamers) { - if (streamer.isStreamerForClass(clazz)) { - return streamer; - } + var streamer :Streamer = _byClass[clazz] as Streamer; + if (streamer != null) { + return streamer; } if (ClassUtil.isAssignableAs(Enum, clazz)) { @@ -96,7 +73,7 @@ public class Streamer } // add the new streamer and return it - _streamers.push(streamer); + registerStreamer(streamer); return streamer; } @@ -109,11 +86,9 @@ public class Streamer } // see if we have a streamer for it - var streamer :Streamer; - for each (streamer in _streamers) { - if (streamer.getJavaClassName() === jname) { - return streamer; - } + var streamer :Streamer = _byJName[jname] as Streamer; + if (streamer != null) { + return streamer; } // see if it's an array that we unstream using an ArrayStreamer @@ -136,7 +111,7 @@ public class Streamer } // add the good new streamer - _streamers.push(streamer); + registerStreamer(streamer); return streamer; } @@ -148,16 +123,6 @@ public class Streamer _jname = (jname != null) ? jname : Translations.getToServer(ClassUtil.getClassName(targ)); } - public function isStreamerFor (obj :Object) :Boolean - { - return isStreamerForClass(ClassUtil.getClass(obj)); - } - - public function isStreamerForClass (clazz :Class) :Boolean - { - return (clazz == _target); - } - /** * Return the String to use to identify the class that we're streaming. */ @@ -166,6 +131,14 @@ public class Streamer return _jname; } + /** + * Return the Class identifying that which we stream, or null to not be registered. + */ + public function getClass () :Class + { + return _target; + } + public function writeObject (obj :Object, out :ObjectOutputStream) :void //throws IOError { @@ -185,6 +158,16 @@ public class Streamer (obj as Streamable).readObject(ins); } + protected static function registerStreamer (st :Streamer) :void + { + _byJName[st.getJavaClassName()] = st; + trace(": registered " + st.getJavaClassName()); + var c :Class = st.getClass(); + if (c != null) { + _byClass[c] = st; + } + } + /** * Initialize our streamers. This cannot simply be done statically * because we cannot instantiate a subclass when this class is still @@ -192,20 +175,15 @@ public class Streamer */ private static function initStreamers () :void { - if (_streamers == null) { - // Init like this so that _streamers is not null asap. - _streamers = []; - // We could add each one by one, so that any later streamers - // can find and use the earlier ones as delegates. - _streamers.push(new StringStreamer(), - new NumberStreamer(), - new ByteStreamer(), - new ShortStreamer(), - new IntegerStreamer(), - new LongStreamer(), - new FloatStreamer(), - new ArrayStreamer(), - new ByteArrayStreamer()); + if (_byJName != null) { + return; + } + _byJName = new Dictionary(); + _byClass = new Dictionary(); + for each (var c :Class in + [ StringStreamer, NumberStreamer, ByteStreamer, IntegerStreamer, LongStreamer, + FloatStreamer, ArrayStreamer, ByteArrayStreamer ]) { + registerStreamer(Streamer(new c())); } } @@ -213,7 +191,7 @@ public class Streamer protected var _jname :String; - /** Just a list of our standard streamers. */ - protected static var _streamers :Array; + protected static var _byClass :Dictionary; + protected static var _byJName :Dictionary; } } diff --git a/src/as/com/threerings/io/Translations.as b/src/as/com/threerings/io/Translations.as index 6f8b37e01..fcf8edce2 100644 --- a/src/as/com/threerings/io/Translations.as +++ b/src/as/com/threerings/io/Translations.as @@ -56,6 +56,10 @@ public class Translations // initialize some standard classes addTranslation("Object", "java.lang.Object"); addTranslation("String", "java.lang.String"); + addTranslation("flash.utils.ByteArray", "[B"); addTranslation("com.threerings.util.langBoolean", "java.lang.Boolean"); + addTranslation("com.threerings.util.Byte", "java.lang.Byte"); + addTranslation("com.threerings.util.Integer", "java.lang.Integer"); + addTranslation("com.threerings.util.Float", "java.lang.Float"); } } diff --git a/src/as/com/threerings/io/streamers/ArrayStreamer.as b/src/as/com/threerings/io/streamers/ArrayStreamer.as index 962b365ec..b14dab5cd 100644 --- a/src/as/com/threerings/io/streamers/ArrayStreamer.as +++ b/src/as/com/threerings/io/streamers/ArrayStreamer.as @@ -61,35 +61,16 @@ public class ArrayStreamer extends Streamer _elementType = Boolean; } else { - Log.getLog(this).warning("Other array types are " + - "currently not handled yet [jname=" + jname + "]."); + Log.getLog(this).warning("Other array types are not yet handled", "jname", jname); throw new Error("Don't know how to stream '" + jname + "' instances."); } } - override public function isStreamerFor (obj :Object) :Boolean + override public function getClass () :Class { - if (obj is TypedArray) { - // TypedArrays need the same element type - return ((obj as TypedArray).getJavaType() === _jname); - - } else { - // any other array is streamed as Object[] - return (obj is Array) && (_jname === "[Ljava.lang.Object;"); - } - } - - override public function isStreamerForClass (clazz :Class) :Boolean - { - if (clazz == TypedArray) { - return false; // TODO: we're kinda fucked for finding a streamer - // by class for TypedArrays here. The caller should be passing - // the java name. - - } else { - return ClassUtil.isAssignableAs(Array, clazz) && - (_jname === "[Ljava.lang.Object;"); - } + // this is a little weird, but basically, we don't want to be registered for Array + // unless we're the basic Object array streamer. + return (_jname == "[Ljava.lang.Object;") ? Array : null; } override public function createObject (ins :ObjectInputStream) :Object diff --git a/src/as/com/threerings/io/streamers/LongStreamer.as b/src/as/com/threerings/io/streamers/LongStreamer.as index 7334bcd75..876fa83a4 100644 --- a/src/as/com/threerings/io/streamers/LongStreamer.as +++ b/src/as/com/threerings/io/streamers/LongStreamer.as @@ -37,11 +37,6 @@ public class LongStreamer extends Streamer super(Long, "java.lang.Long"); } - override public function createObject (ins :ObjectInputStream) :Object - { - return new Long(); - } - override public function writeObject (obj :Object, out :ObjectOutputStream) :void { var longy :Long = (obj as Long);