From 13f43728ecc79167cfad464ba15c45cc69f34ac4 Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Fri, 15 Oct 2010 08:42:39 +0000 Subject: [PATCH] Generate streaming code for Map Is there a reason Map isn't Equalable? java.util.Map requires an equals implementation, and it has the same lack of guarantee of its values implementing equals. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6201 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../tools/GenActionScriptStreamableTask.java | 6 +++- .../presents/tools/GenActionScriptTask.java | 31 ++++++++-------- .../com/threerings/io/ASStreamableSubset.as | 36 ++++++++++++++++++- .../as/com/threerings/io/StreamableTest.as | 4 ++- .../com/threerings/io/ASStreamableSubset.java | 11 +++++- 5 files changed, 69 insertions(+), 19 deletions(-) diff --git a/src/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java b/src/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java index 1840a56d8..d09d2ca24 100644 --- a/src/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java +++ b/src/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java @@ -24,9 +24,11 @@ package com.threerings.presents.tools; import java.lang.reflect.Field; import java.util.List; +import java.util.Map; import java.util.Set; import java.io.File; + import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; @@ -96,9 +98,11 @@ public class GenActionScriptStreamableTask extends GenActionScriptTask this.name = f.getName(); this.simpleType = addImportAndGetShortType(f.getType(), true, imports); - // Reading and writing Lists uses ArrayStreamer.INSTANCE directly + // Lists and Maps use their Streamers directly if (List.class.isAssignableFrom(f.getType())) { imports.add("com.threerings.io.streamers.ArrayStreamer"); + } else if (Map.class.isAssignableFrom(f.getType())) { + imports.add("com.threerings.io.streamers.MapStreamer"); } this.reader = toReadObject(f.getType()); this.writer = toWriteObject(f.getType(), name); diff --git a/src/java/com/threerings/presents/tools/GenActionScriptTask.java b/src/java/com/threerings/presents/tools/GenActionScriptTask.java index 70930da0d..f43668903 100644 --- a/src/java/com/threerings/presents/tools/GenActionScriptTask.java +++ b/src/java/com/threerings/presents/tools/GenActionScriptTask.java @@ -26,6 +26,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import java.io.BufferedWriter; @@ -269,30 +270,24 @@ public class GenActionScriptTask extends GenTask return "com.threerings.io.TypedArray"; } return "Array"; - } - - if (Integer.TYPE.equals(type) || + } else if (Map.class.isAssignableFrom(type)) { + return "com.threerings.util.Map"; + } else if (Integer.TYPE.equals(type) || Byte.TYPE.equals(type) || Short.TYPE.equals(type) || Character.TYPE.equals(type)) { return "int"; - } - - if (Float.TYPE.equals(type) || + } else if (Float.TYPE.equals(type) || Double.TYPE.equals(type)) { return "Number"; - } - - if (Long.TYPE.equals(type)) { + } else if (Long.TYPE.equals(type)) { return "com.threerings.util.Long"; - } - - if (Boolean.TYPE.equals(type)) { + } else if (Boolean.TYPE.equals(type)) { return "Boolean"; + } else { + // inner classes are not supported by ActionScript so we _ + return type.getName().replaceAll("\\$", "_"); } - - // inner classes are not supported by ActionScript so we _ - return type.getName().replaceAll("\\$", "_"); } public static String toReadObject (Class type) @@ -331,6 +326,9 @@ public class GenActionScriptTask extends GenTask } else if (type.equals(Double.TYPE)) { return "readDouble()"; + } else if (Map.class.isAssignableFrom(type)) { + return "readField(MapStreamer.INSTANCE)"; + } else if (List.class.isAssignableFrom(type)) { return "readField(ArrayStreamer.INSTANCE)"; @@ -391,6 +389,9 @@ public class GenActionScriptTask extends GenTask } else if (List.class.isAssignableFrom(type)) { return "writeField(" + name + ", ArrayStreamer.INSTANCE)"; + } else if (Map.class.isAssignableFrom(type)) { + return "writeField(" + name + ", MapStreamer.INSTANCE)"; + } else { return "writeObject(" + name + ")"; } diff --git a/tests/src/as/com/threerings/io/ASStreamableSubset.as b/tests/src/as/com/threerings/io/ASStreamableSubset.as index fa1cdcaed..b1d59920c 100644 --- a/tests/src/as/com/threerings/io/ASStreamableSubset.as +++ b/tests/src/as/com/threerings/io/ASStreamableSubset.as @@ -30,8 +30,11 @@ import com.threerings.util.Long; import com.threerings.io.TypedArray; import flash.utils.ByteArray; import com.threerings.io.streamers.ArrayStreamer; +import com.threerings.util.Map; +import com.threerings.io.streamers.MapStreamer; // GENERATED PREAMBLE END +import com.threerings.util.Maps; import com.threerings.util.Util; // GENERATED CLASSDECL START @@ -66,6 +69,29 @@ public class ASStreamableSubset extends SimpleStreamableObject bytes.writeByte(3); ints = TypedArray.create(int, [1, 2, 3]); strings = TypedArray.create(String, ["one", "two", "three"]); + stringMap = Maps.newMapOf(String); + stringMap.put("one", "1"); + stringMap.put("two", "2"); + stringMap.put("three", "3"); + } + + protected static function mapEquals (m1 :Map, m2 :Map) :Boolean + { + if (m1 == m2) { + return true; + } + if (m1 == null) { + return false; + } + if (m1.size() != m2.size()) { + return false; + } + for each (var key :Object in m1.keys()) { + if (!m2.containsKey(key) || !Util.equals(m1.get(key), m2.get(key))) { + return false; + } + } + return true; } public function equals (o :ASStreamableSubset) :Boolean @@ -76,7 +102,9 @@ public class ASStreamableSubset extends SimpleStreamableObject Util.equals(bools, o.bools) && Util.equals(bytes, o.bytes) && Util.equals(ints, o.ints) && Util.equals(nullBools, o.nullBools) && Util.equals(nullBytes, o.nullBytes) && Util.equals(nullInts, o.nullInts) && - Util.equals(strings, o.strings) && Util.equals(nullStrings, o.nullStrings); + Util.equals(strings, o.strings) && Util.equals(nullStrings, o.nullStrings) && + mapEquals(stringMap, o.stringMap) && + mapEquals(nullStringMap, o.nullStringMap); } @@ -99,6 +127,8 @@ public class ASStreamableSubset extends SimpleStreamableObject public var nullInts :TypedArray; public var strings :TypedArray; public var nullStrings :TypedArray; + public var stringMap :Map; + public var nullStringMap :Map; override public function readObject (ins :ObjectInputStream) :void { @@ -121,6 +151,8 @@ public class ASStreamableSubset extends SimpleStreamableObject nullInts = ins.readField(TypedArray.getJavaType(int)); strings = ins.readField(ArrayStreamer.INSTANCE); nullStrings = ins.readField(ArrayStreamer.INSTANCE); + stringMap = ins.readField(MapStreamer.INSTANCE); + nullStringMap = ins.readField(MapStreamer.INSTANCE); } override public function writeObject (out :ObjectOutputStream) :void @@ -144,6 +176,8 @@ public class ASStreamableSubset extends SimpleStreamableObject out.writeField(nullInts); out.writeField(strings, ArrayStreamer.INSTANCE); out.writeField(nullStrings, ArrayStreamer.INSTANCE); + out.writeField(stringMap, MapStreamer.INSTANCE); + out.writeField(nullStringMap, MapStreamer.INSTANCE); } // GENERATED STREAMING END diff --git a/tests/src/as/com/threerings/io/StreamableTest.as b/tests/src/as/com/threerings/io/StreamableTest.as index 27c7ec057..055f410e1 100644 --- a/tests/src/as/com/threerings/io/StreamableTest.as +++ b/tests/src/as/com/threerings/io/StreamableTest.as @@ -55,7 +55,9 @@ public class StreamableTest extends TestCase "ffff0024636f6d2e746872656572696e67732e696f2e415353747265616d61626c65537562736574" + "01000200000003000000000000000440a0000040180000000000000007080100036f6e6500010000" + "0003010001010000000301020301000000030000000100000002000000030000000100000003fffe" + - "00106a6176612e6c616e672e537472696e6700036f6e650002000374776f00020005746872656500"); + "00106a6176612e6c616e672e537472696e6700036f6e650002000374776f00020005746872656500" + + "01000000030002000374776f0002000132000200036f6e6500020001310002000574687265650002" + + "00013300"); var input:ObjectInputStream = new ObjectInputStream(javaData); var read :ASStreamableSubset = input.readObject(ASStreamableSubset); assertTrue(sub.equals(read)); diff --git a/tests/src/java/com/threerings/io/ASStreamableSubset.java b/tests/src/java/com/threerings/io/ASStreamableSubset.java index b77ec1164..a633018ac 100644 --- a/tests/src/java/com/threerings/io/ASStreamableSubset.java +++ b/tests/src/java/com/threerings/io/ASStreamableSubset.java @@ -23,9 +23,11 @@ package com.threerings.io; import java.util.Arrays; import java.util.List; +import java.util.Map; import com.google.common.base.Objects; import com.google.common.collect.Lists; +import com.samskivert.util.Mapping; public class ASStreamableSubset extends SimpleStreamableObject { @@ -52,6 +54,9 @@ public class ASStreamableSubset extends SimpleStreamableObject public List strings = Lists.newArrayList("one", "two", "three"); public List nullStrings; + public Map stringMap = Mapping.of("one", "1", "two", "2", "three", "3"); + public Map nullStringMap; + @Override public boolean equals (Object other) { @@ -76,6 +81,10 @@ public class ASStreamableSubset extends SimpleStreamableObject && Arrays.equals(nullInts, ow.nullInts) && - Objects.equal(strings, ow.strings) && Objects.equal(nullStrings, ow.nullStrings); + Objects.equal(strings, ow.strings) && Objects.equal(nullStrings, ow.nullStrings) + && + + Objects.equal(stringMap, ow.stringMap) + && Objects.equal(nullStringMap, ow.nullStringMap); } }