diff --git a/src/main/java/com/threerings/presents/tools/ActionScriptUtils.java b/src/main/java/com/threerings/presents/tools/ActionScriptUtils.java index e3e194a32..cfbfba96f 100644 --- a/src/main/java/com/threerings/presents/tools/ActionScriptUtils.java +++ b/src/main/java/com/threerings/presents/tools/ActionScriptUtils.java @@ -274,6 +274,32 @@ public class ActionScriptUtils return false; } + /** + * Returns the primitive (unboxed) counterpart of a class, or the same class if it isn't a boxed + * type. + */ + public static Class toPrimitiveType (Class cclass) + { + if (Boolean.class == cclass) { + return Boolean.TYPE; + } else if (Character.class == cclass) { + return Character.TYPE; + } else if (Byte.class == cclass) { + return Byte.TYPE; + } else if (Short.class == cclass) { + return Short.TYPE; + } else if (Integer.class == cclass) { + return Integer.TYPE; + } else if (Long.class == cclass) { + return Long.TYPE; + } else if (Float.class == cclass) { + return Float.TYPE; + } else if (Double.class == cclass) { + return Double.TYPE; + } + return cclass; + } + /** Returns if the given class is an implementation of Map that doesn't know about Streaming */ protected static boolean isNaiveMap (Class type) { diff --git a/src/main/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java b/src/main/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java index e52d1538e..4b7fdfe28 100644 --- a/src/main/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java +++ b/src/main/java/com/threerings/presents/tools/GenActionScriptStreamableTask.java @@ -24,6 +24,8 @@ package com.threerings.presents.tools; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.List; import java.util.Map; import java.util.Set; @@ -165,12 +167,14 @@ public class GenActionScriptStreamableTask extends GenTask public final String name; public final String capitalName; public final String simpleType; + public final String parameterTypes; public final String reader; public final String writer; public final String dobjectField; public boolean dset; public boolean array; public boolean oidList; + public boolean hasTypeParameters; public ASField (Field f, ImportSet imports) { @@ -179,6 +183,25 @@ public class GenActionScriptStreamableTask extends GenTask dobjectField = StringUtil.unStudlyName(name).toUpperCase(); simpleType = ActionScriptUtils.addImportAndGetShortType(f.getType(), true, imports); + List parameters = Lists.newLinkedList(); + Type genType = f.getGenericType(); + if (genType instanceof ParameterizedType) { + for (Type param : ((ParameterizedType) genType).getActualTypeArguments()) { + if (param instanceof Class) { + // Convert any box classes to primitives to avoid having to import them + Class primitive = ActionScriptUtils.toPrimitiveType((Class) param); + parameters.add(ActionScriptUtils.addImportAndGetShortType( + primitive, false, imports)); + } + } + } + if (!parameters.isEmpty()) { + parameterTypes = Joiner.on(", ").join(parameters); + hasTypeParameters = true; + } else { + parameterTypes = ""; + } + // Lists and Maps use their Streamers directly if (List.class.isAssignableFrom(f.getType())) { imports.add("com.threerings.io.streamers.ArrayStreamer"); @@ -188,7 +211,6 @@ public class GenActionScriptStreamableTask extends GenTask imports.add("com.threerings.io.streamers.SetStreamer"); } else if (DSet.class.isAssignableFrom(f.getType())) { dset = true; - imports.add("com.threerings.presents.dobj.DSet_Entry"); // Used for signals } else if (OidList.class.isAssignableFrom(f.getType())) { oidList = true; } diff --git a/src/main/resources/com/threerings/presents/tools/streamable_as.tmpl b/src/main/resources/com/threerings/presents/tools/streamable_as.tmpl index 1bf27fc03..216427dbe 100644 --- a/src/main/resources/com/threerings/presents/tools/streamable_as.tmpl +++ b/src/main/resources/com/threerings/presents/tools/streamable_as.tmpl @@ -19,16 +19,17 @@ public class {{classname}} {{^extends.isEmpty}}extends {{extends}} // GENERATED STREAMING START {{#pubFields}} - public var {{name}} :{{simpleType}}; + public var {{name}} :{{simpleType}};{{#hasTypeParameters}} /* of */ {{parameterTypes}};{{/hasTypeParameters}} + {{/pubFields}} {{#dobject}} {{#pubFields}} public var {{name}}Changed :Signal = new Signal({{simpleType}}, {{simpleType}}); {{#dset}} - public var {{name}}EntryAdded :Signal = new Signal(DSet_Entry); - public var {{name}}EntryRemoved :Signal = new Signal(DSet_Entry); - public var {{name}}EntryUpdated :Signal = new Signal(DSet_Entry, DSet_Entry); + public var {{name}}EntryAdded :Signal = new Signal({{parameterTypes}}); + public var {{name}}EntryRemoved :Signal = new Signal({{parameterTypes}}); + public var {{name}}EntryUpdated :Signal = new Signal({{parameterTypes}}, {{parameterTypes}}); {{/dset}} {{#array}} public var {{name}}ElementUpdated :Signal = new Signal(int, Object, Object);