disp)
{
T marsh = _invmgr.registerDispatcher(disp);
_marshallers.add(marsh);
diff --git a/src/main/java/com/threerings/presents/client/InvocationService.java b/src/main/java/com/threerings/presents/client/InvocationService.java
index e570dbf6f..1d309b0f8 100644
--- a/src/main/java/com/threerings/presents/client/InvocationService.java
+++ b/src/main/java/com/threerings/presents/client/InvocationService.java
@@ -21,13 +21,15 @@
package com.threerings.presents.client;
+import com.threerings.presents.data.ClientObject;
+
/**
* Serves as the base interface for invocation services. An invocation service can be defined by
* extending this interface and defining service methods, as well as response listeners (which must
* extend {@link InvocationListener}). For example:
*
*
- * public interface LocationService extends InvocationService
+ * public interface LocationService extends InvocationService<ClientObject>
* {
*
* // Used to communicate responses to moveTo() requests.
@@ -62,7 +64,7 @@ package com.threerings.presents.client;
* }
*
*/
-public interface InvocationService
+public interface InvocationService
{
/**
* Invocation service methods that require a response should take a listener argument that can
diff --git a/src/main/java/com/threerings/presents/client/TimeBaseService.java b/src/main/java/com/threerings/presents/client/TimeBaseService.java
index 8f1499537..e750b59bd 100644
--- a/src/main/java/com/threerings/presents/client/TimeBaseService.java
+++ b/src/main/java/com/threerings/presents/client/TimeBaseService.java
@@ -21,11 +21,13 @@
package com.threerings.presents.client;
+import com.threerings.presents.data.ClientObject;
+
/**
* Provides a means by which to obtain access to a time base object which can be used to convert
* delta times into absolute times.
*/
-public interface TimeBaseService extends InvocationService
+public interface TimeBaseService extends InvocationService
{
/**
* Used to communicated the result of a {@link TimeBaseService#getTimeOid} request.
diff --git a/src/main/java/com/threerings/presents/data/InvocationMarshaller.java b/src/main/java/com/threerings/presents/data/InvocationMarshaller.java
index 3cb1184ea..cf5925219 100644
--- a/src/main/java/com/threerings/presents/data/InvocationMarshaller.java
+++ b/src/main/java/com/threerings/presents/data/InvocationMarshaller.java
@@ -40,8 +40,8 @@ import static com.threerings.presents.Log.log;
* Provides a base from which all invocation service marshallers extend. Handles functionality
* common to all marshallers.
*/
-public class InvocationMarshaller
- implements Streamable, InvocationService
+public class InvocationMarshaller
+ implements Streamable, InvocationService
{
/**
* Provides a base from which invocation listener marshallers extend.
diff --git a/src/main/java/com/threerings/presents/data/TimeBaseMarshaller.java b/src/main/java/com/threerings/presents/data/TimeBaseMarshaller.java
index 9171ce413..cb295a6e4 100644
--- a/src/main/java/com/threerings/presents/data/TimeBaseMarshaller.java
+++ b/src/main/java/com/threerings/presents/data/TimeBaseMarshaller.java
@@ -34,7 +34,7 @@ import com.threerings.presents.client.TimeBaseService;
*/
@Generated(value={"com.threerings.presents.tools.GenServiceTask"},
comments="Derived from TimeBaseService.java.")
-public class TimeBaseMarshaller extends InvocationMarshaller
+public class TimeBaseMarshaller extends InvocationMarshaller
implements TimeBaseService
{
/**
diff --git a/src/main/java/com/threerings/presents/peer/client/PeerService.java b/src/main/java/com/threerings/presents/peer/client/PeerService.java
index a2cecd05c..4f15a901e 100644
--- a/src/main/java/com/threerings/presents/peer/client/PeerService.java
+++ b/src/main/java/com/threerings/presents/peer/client/PeerService.java
@@ -22,12 +22,13 @@
package com.threerings.presents.peer.client;
import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.ClientObject;
import com.threerings.presents.peer.data.NodeObject.Lock;
/**
* Defines requests made from one peer to another.
*/
-public interface PeerService extends InvocationService
+public interface PeerService extends InvocationService
{
/**
* Informs the node that the sending peer ratifies its acquisition or release of the specified
diff --git a/src/main/java/com/threerings/presents/peer/data/PeerMarshaller.java b/src/main/java/com/threerings/presents/peer/data/PeerMarshaller.java
index 4ed07defe..9aeb12d89 100644
--- a/src/main/java/com/threerings/presents/peer/data/PeerMarshaller.java
+++ b/src/main/java/com/threerings/presents/peer/data/PeerMarshaller.java
@@ -24,6 +24,7 @@ package com.threerings.presents.peer.data;
import javax.annotation.Generated;
import com.threerings.presents.client.InvocationService;
+import com.threerings.presents.data.ClientObject;
import com.threerings.presents.data.InvocationMarshaller;
import com.threerings.presents.peer.client.PeerService;
@@ -36,7 +37,7 @@ import com.threerings.presents.peer.client.PeerService;
*/
@Generated(value={"com.threerings.presents.tools.GenServiceTask"},
comments="Derived from PeerService.java.")
-public class PeerMarshaller extends InvocationMarshaller
+public class PeerMarshaller extends InvocationMarshaller
implements PeerService
{
/** The method id used to dispatch {@link #generateReport} requests. */
diff --git a/src/main/java/com/threerings/presents/tools/GenServiceTask.java b/src/main/java/com/threerings/presents/tools/GenServiceTask.java
index 344df91b0..5b28d54aa 100644
--- a/src/main/java/com/threerings/presents/tools/GenServiceTask.java
+++ b/src/main/java/com/threerings/presents/tools/GenServiceTask.java
@@ -21,18 +21,17 @@
package com.threerings.presents.tools;
+import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-
-import java.util.Arrays;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.io.File;
-
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -249,6 +248,11 @@ public class GenServiceTask extends InvocationTask
imports.add(InvocationMarshaller.class);
imports.add("javax.annotation.Generated");
+ // We only add a type parameter for the caller ClientObject type if the service has one
+ if (sdesc.callerTypeSpecified) {
+ imports.add(sdesc.callerType);
+ }
+
// import classes contained in arrays
imports.translateClassArrays();
@@ -276,7 +280,9 @@ public class GenServiceTask extends InvocationTask
ctx.put("package", mpackage);
ctx.put("methods", sdesc.methods);
ctx.put("listeners", sdesc.listeners);
- ctx.put("importGroups", imports.toGroups(Arrays.asList("java", "com.threerings")));
+ ctx.put("typeParameters",
+ sdesc.callerTypeSpecified ? "<" + sdesc.callerType.getSimpleName() + ">" : "");
+ ctx.put("importGroups", imports.toGroups());
// determine the path to our marshaller file
String mpath = source.getPath();
@@ -327,7 +333,7 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(mpackage);
- ctx.put("importGroups", imports.toGroups(Arrays.asList("com.threerings")));
+ ctx.put("importGroups", imports.toGroups());
// now generate ActionScript versions of our marshaller
@@ -362,7 +368,7 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(mpackage);
- ctx.put("importGroups", imports.toGroups(Arrays.asList("com.threerings")));
+ ctx.put("importGroups", imports.toGroups());
ctx.put("listener", listener);
String aslpath = _asroot + File.separator + mppath +
File.separator + mname + "_" + listener.getListenerName() + "Marshaller.as";
@@ -397,7 +403,7 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(sdesc.spackage);
- ctx.put("importGroups", imports.toGroups(Arrays.asList("com.threerings")));
+ ctx.put("importGroups", imports.toGroups());
ctx.put("package", sdesc.spackage);
// make sure our service directory exists
@@ -429,7 +435,7 @@ public class GenServiceTask extends InvocationTask
// remove imports in our own package
imports.removeSamePackage(sdesc.spackage);
- ctx.put("importGroups", imports.toGroups(Arrays.asList("com.threerings")));
+ ctx.put("importGroups", imports.toGroups());
ctx.put("listener", listener);
String aslpath = _asroot + File.separator + sppath + File.separator +
@@ -463,7 +469,7 @@ public class GenServiceTask extends InvocationTask
}
// swap Client for ClientObject
- imports.add(ClientObject.class);
+ imports.add(sdesc.callerType);
// add some classes required for all dispatchers
imports.add(InvocationDispatcher.class);
@@ -514,8 +520,9 @@ public class GenServiceTask extends InvocationTask
// start with imports required by service methods
ImportSet imports = sdesc.imports.clone();
- // swap Client for ClientObject
- imports.add(ClientObject.class);
+ if (!sdesc.methods.isEmpty()) {
+ imports.add(sdesc.callerType);
+ }
// import superclass and service
imports.add(InvocationProvider.class);
@@ -552,7 +559,8 @@ public class GenServiceTask extends InvocationTask
"package", mpackage,
"methods", sdesc.methods,
"listeners", sdesc.listeners,
- "importGroups", imports.toGroups(Arrays.asList("java", "com.threerings")));
+ "callerType", sdesc.callerType.getSimpleName(),
+ "importGroups", imports.toGroups());
}
/**
@@ -567,6 +575,8 @@ public class GenServiceTask extends InvocationTask
/** Rolls up everything needed for the generate* methods. */
protected class ServiceDescription
{
+ public Class> callerType = ClientObject.class;
+ public boolean callerTypeSpecified;// True if callerType came from a type parameter
public Class> service;
public String sname;
public String spackage;
@@ -578,6 +588,11 @@ public class GenServiceTask extends InvocationTask
public ServiceDescription (Class> serviceClass)
{
service = serviceClass;
+ Type[] genint = service.getGenericInterfaces();
+ if (genint.length > 0 && genint[0] instanceof ParameterizedType) {
+ callerType = (Class>)((ParameterizedType)genint[0]).getActualTypeArguments()[0];
+ callerTypeSpecified = true;
+ }
sname = service.getSimpleName();
spackage = service.getPackage().getName();
ActionScript asa = service.getAnnotation(ActionScript.class);
diff --git a/src/main/java/com/threerings/presents/tools/ImportSet.java b/src/main/java/com/threerings/presents/tools/ImportSet.java
index 80df9fe96..b2fb4401c 100644
--- a/src/main/java/com/threerings/presents/tools/ImportSet.java
+++ b/src/main/java/com/threerings/presents/tools/ImportSet.java
@@ -332,21 +332,12 @@ public class ImportSet
* ordering and spacing. Within each group, sorting is alphabetical.
*/
public List> toGroups ()
- {
- return toGroups(IMPORT_GROUPS);
- }
-
- /**
- * Converts the set of imports to groups of class names, according to the provided groups.
- * Within each group, sorting is alphabetical.
- */
- public List> toGroups (final List groups)
{
List list = Lists.newArrayList(_imports);
Collections.sort(list, new Comparator() {
public int compare (String class1, String class2) {
return ComparisonChain.start()
- .compare(findImportGroup(class1, groups), findImportGroup(class2, groups))
+ .compare(findImportGroup(class1), findImportGroup(class2))
.compare(class1, class2)
.result();
}
@@ -355,7 +346,7 @@ public class ImportSet
List current = null;
int lastGroup = -2;
for (String imp : list) {
- int group = findImportGroup(imp, groups);
+ int group = findImportGroup(imp);
if (group != lastGroup) {
if (current == null || !current.isEmpty()) {
result.add(current = Lists.newArrayList());
@@ -415,10 +406,10 @@ public class ImportSet
return Pattern.compile(pattern.toString());
}
- protected static int findImportGroup (String imp, List groups)
+ protected static int findImportGroup (String imp)
{
String longest = null;
- for (String prefix : groups) {
+ for (String prefix : IMPORT_GROUPS) {
if (!imp.startsWith(prefix)) {
continue;
}
@@ -426,7 +417,7 @@ public class ImportSet
longest = prefix;
}
}
- return groups.indexOf(longest);
+ return IMPORT_GROUPS.indexOf(longest);
}
protected HashSet _imports = Sets.newHashSet();
@@ -438,17 +429,24 @@ public class ImportSet
protected static List IMPORT_GROUPS = Lists.newArrayList(
"flash.",
"fl.",
+ "java",
"",
OOO,
OOO + "io.",
OOO + "util.",
OOO + "presents.",
+ OOO + "tudey.",
OOO + "orth.",
OOO + "riposte.",
+ OOO + "riposte.",
OOO + "samsara.",
OOO + "flashbang.",
OOO + "downtown.",
OOO + "biteme.",
OOO + "who.",
- OOO + "blueharvest.");
+ OOO + "blueharvest.",
+ OOO + "piracy.",
+ OOO + "ppa.",
+ OOO + "yohoho.",
+ OOO + "projectx.");
}
diff --git a/src/main/resources/com/threerings/presents/tools/marshaller.tmpl b/src/main/resources/com/threerings/presents/tools/marshaller.tmpl
index 8062464ff..25f5f0042 100644
--- a/src/main/resources/com/threerings/presents/tools/marshaller.tmpl
+++ b/src/main/resources/com/threerings/presents/tools/marshaller.tmpl
@@ -14,7 +14,7 @@ import {{this}};
* to the requesting client.
*/
{{generated}}
-public class {{name}}Marshaller extends InvocationMarshaller
+public class {{name}}Marshaller extends InvocationMarshaller{{typeParameters}}
implements {{name}}Service
{
{{#listeners}}
diff --git a/src/main/resources/com/threerings/presents/tools/provider.tmpl b/src/main/resources/com/threerings/presents/tools/provider.tmpl
index 9b495f773..0f7ffc45f 100644
--- a/src/main/resources/com/threerings/presents/tools/provider.tmpl
+++ b/src/main/resources/com/threerings/presents/tools/provider.tmpl
@@ -19,7 +19,7 @@ public interface {{name}}Provider extends InvocationProvider
/**
* Handles a {@link {{name}}Service#{{method.name}}} request.
*/
- {{typeParams}}void {{method.name}} (ClientObject caller{{#hasArgs}}, {{/hasArgs}}{{getArgList}}){{^listenerArgs.isEmpty}}
+ {{typeParams}}void {{method.name}} ({{callerType}} caller{{#hasArgs}}, {{/hasArgs}}{{getArgList}}){{^listenerArgs.isEmpty}}
throws InvocationException{{/listenerArgs.isEmpty}};
{{/methods}}
diff --git a/src/test/java/com/threerings/presents/client/TestService.java b/src/test/java/com/threerings/presents/client/TestService.java
index de2d46e8c..8942d6e59 100644
--- a/src/test/java/com/threerings/presents/client/TestService.java
+++ b/src/test/java/com/threerings/presents/client/TestService.java
@@ -23,10 +23,12 @@ package com.threerings.presents.client;
import java.util.List;
+import com.threerings.presents.data.ClientObject;
+
/**
* A test of the invocation services.
*/
-public interface TestService extends InvocationService
+public interface TestService extends InvocationService
{
/** Used to dispatch responses to {@link TestService#test} requests. */
public static interface TestFuncListener extends InvocationListener
diff --git a/src/test/java/com/threerings/presents/data/TestMarshaller.java b/src/test/java/com/threerings/presents/data/TestMarshaller.java
index 10a36994c..b0146364a 100644
--- a/src/test/java/com/threerings/presents/data/TestMarshaller.java
+++ b/src/test/java/com/threerings/presents/data/TestMarshaller.java
@@ -36,7 +36,7 @@ import com.threerings.presents.client.TestService;
*/
@Generated(value={"com.threerings.presents.tools.GenServiceTask"},
comments="Derived from TestService.java.")
-public class TestMarshaller extends InvocationMarshaller
+public class TestMarshaller extends InvocationMarshaller
implements TestService
{
/**