From 16a28de8bcd004f23daaf434ec1ea6f57310d097 Mon Sep 17 00:00:00 2001 From: Ray Greenwell Date: Tue, 28 Mar 2006 23:17:52 +0000 Subject: [PATCH] Report from brown team, engaged in Operation Slam Your Dick in a Door: "Still purple and bruised, sir!" I'm working around more bugs. In theory everything should log in and join the chat room, but the browser crashes- every single time. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3986 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../com/threerings/crowd/data/PlaceObject.as | 6 +-- src/as/com/threerings/io/ObjectInputStream.as | 21 ++++++-- src/as/com/threerings/io/Streamer.as | 21 +++++++- src/as/com/threerings/util/ClassUtil.as | 49 ++++++++++++++++++- 4 files changed, 89 insertions(+), 8 deletions(-) diff --git a/src/as/com/threerings/crowd/data/PlaceObject.as b/src/as/com/threerings/crowd/data/PlaceObject.as index d8c05417b..ea7e3b6c8 100644 --- a/src/as/com/threerings/crowd/data/PlaceObject.as +++ b/src/as/com/threerings/crowd/data/PlaceObject.as @@ -183,9 +183,9 @@ public class PlaceObject extends DObject public override function writeObject (out :ObjectOutputStream) :void { super.writeObject(out); - out.writeObject(occupants); - out.writeObject(occupantInfo); - out.writeObject(speakService); + out.writeField(occupants); + out.writeField(occupantInfo); + out.writeField(speakService); } // documentation inherited diff --git a/src/as/com/threerings/io/ObjectInputStream.as b/src/as/com/threerings/io/ObjectInputStream.as index a54085a04..ccb54fb33 100644 --- a/src/as/com/threerings/io/ObjectInputStream.as +++ b/src/as/com/threerings/io/ObjectInputStream.as @@ -53,7 +53,7 @@ public class ObjectInputStream Log.debug("read cname: " + cname); var streamer :Streamer = Streamer.getStreamerByJavaName(cname); if (streamer == Streamer.BAD_STREAMER) { - Log.warning("OMG, cannot stream" + cname); + Log.warning("OMG, cannot stream " + cname); return null; } @@ -129,8 +129,23 @@ public class ObjectInputStream throw new Error("Cannot field stream " + type); } - var obj :Object = streamer.createObject(this); - streamer.readObject(obj, this); + var obj :Object; + if (streamer != null) { + obj = streamer.createObject(this); + + } else { + // create the streamable object, either by class or name + var c :Class; + if (type is Class) { + c = (type as Class); + } else { + c = ClassUtil.getClassByName( + Translations.getFromServer(type as String)); + } + obj = new c(); + } + + readBareObjectImpl(obj, streamer); return obj; } return null; diff --git a/src/as/com/threerings/io/Streamer.as b/src/as/com/threerings/io/Streamer.as index b0ffae7c6..e7bcd5f5e 100644 --- a/src/as/com/threerings/io/Streamer.as +++ b/src/as/com/threerings/io/Streamer.as @@ -4,6 +4,7 @@ import flash.util.trace; import flash.util.ByteArray; +import com.threerings.util.ClassUtil; import com.threerings.util.SimpleMap; import com.threerings.io.streamers.ArrayStreamer; @@ -49,6 +50,10 @@ public class Streamer { initStreamers(); + if (ClassUtil.isAssignableAs(Streamable, clazz)) { + return null; // Streamable + } + if (clazz === TypedArray) { throw new Error("Broken, TODO"); } @@ -66,19 +71,33 @@ public class Streamer { initStreamers(); + // see if we have a streamer for it for each (var streamer :Streamer in _streamers) { if (streamer.getJavaClassName() === jname) { return streamer; } } + // see if it's an array that we unstream using an ArrayStreamer if (jname.charAt(0) === "[") { var streamer :Streamer = new ArrayStreamer(jname); _streamers.push(streamer); return streamer; } - return null; + // otherwise see if it represents a Streamable + var clazz :Class = ClassUtil.getClassByName( + Translations.getFromServer(jname)); + if (ClassUtil.isAssignableAs(Streamable, clazz)) { + return null; // it's streamable + } + + // TEMP: workaround for fucked-up bug!!! FUCK ACTIONSCRIPT! + if (clazz == StreamableArrayList) { + return null; // it's streamable, yes it is + } + + return BAD_STREAMER; } /** This should be a protected constructor. */ diff --git a/src/as/com/threerings/util/ClassUtil.as b/src/as/com/threerings/util/ClassUtil.as index 440fb2425..944135351 100644 --- a/src/as/com/threerings/util/ClassUtil.as +++ b/src/as/com/threerings/util/ClassUtil.as @@ -27,7 +27,7 @@ public class ClassUtil public static function getClassByName (cname :String) :Class { // see also ApplicationDomain.currentDomain.getClass(cname) - return flash.util.getClassByName(cname); + return flash.util.getClassByName(cname.replace("::", ".")); } public static function isFinal (type :Class) :Boolean @@ -40,5 +40,52 @@ public class ClassUtil //var attrs :XMLList = flash.util.describeType(type).elements("type"); return false; } + + /** + * Returns true if an object of type srcClass is a subclass of or + * implements the interface represented by the asClass paramter. + * + * + * if (ClassUtil.isAssignableAs(Streamable, someClass)) { + * var s :Streamable = (new someClass() as Streamable); + * + */ + public static function isAssignableAs ( + asClass :Class, srcClass :Class) :Boolean + { + if (asClass == srcClass) { + return true; + + // if not the same class and srcClass is Object, we're done + } else if (srcClass == Object) { + return false; + } + + // ok, let's introspect on the class and see what we've got. + var typeInfo :XMLList = + flash.util.describeType(srcClass).child("factory"); + + // See which classes we extend. + var exts :XMLList = typeInfo.child("extends").attribute("type"); + for each (var type :String in exts) { + //if (asClass == getClassByName(type)) { + // TEMP: recursing sometimes gets around a describeType bug + if (isAssignableAs(asClass, getClassByName(type))) { + return true; + } + } + + // See which interfaces we implement. + var imps :XMLList = typeInfo.child("implements").attribute("type"); + for each (var type :String in imps) { + //if (asClass == getClassByName(type)) { + // TEMP: recursing sometimes gets around a describeType bug + if (isAssignableAs(asClass, getClassByName(type))) { + return true; + } + } + + return false; + } } }