From 81bfee5132014ee4be4be599ad6ad9a1cf5e6459 Mon Sep 17 00:00:00 2001 From: Charlie Groves Date: Sat, 26 Feb 2011 02:04:06 +0000 Subject: [PATCH] Generate receivers and decoders for actionscript git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6507 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- build.xml | 5 +- .../threerings/bureau/client/BureauDecoder.as | 8 +-- .../bureau/client/BureauReceiver.as | 24 ++------- .../crowd/client/LocationDecoder.as | 10 ++-- .../crowd/client/LocationReceiver.as | 13 +---- .../presents/peer/server/PeerManager.java | 1 - .../presents/tools/GenReceiverTask.java | 50 ++++++++++++++++-- .../threerings/presents/tools/GenUtil.java | 2 +- .../threerings/presents/tools/ImportSet.java | 2 +- .../threerings/presents/tools/decoder_as.tmpl | 51 +++++++++++++++++++ .../presents/tools/receiver_as.tmpl | 17 +++++++ 11 files changed, 129 insertions(+), 54 deletions(-) create mode 100644 src/main/resources/com/threerings/presents/tools/decoder_as.tmpl create mode 100644 src/main/resources/com/threerings/presents/tools/receiver_as.tmpl diff --git a/build.xml b/build.xml index 90bee2cd2..66c862773 100644 --- a/build.xml +++ b/build.xml @@ -290,7 +290,8 @@ - + @@ -364,7 +365,7 @@ - + diff --git a/src/main/as/com/threerings/bureau/client/BureauDecoder.as b/src/main/as/com/threerings/bureau/client/BureauDecoder.as index fbe650ce4..762b6a609 100644 --- a/src/main/as/com/threerings/bureau/client/BureauDecoder.as +++ b/src/main/as/com/threerings/bureau/client/BureauDecoder.as @@ -21,7 +21,6 @@ package com.threerings.bureau.client { -import com.threerings.bureau.client.BureauReceiver; import com.threerings.presents.client.InvocationDecoder; /** @@ -49,31 +48,28 @@ public class BureauDecoder extends InvocationDecoder this.receiver = receiver; } - // documentation inherited public override function getReceiverCode () :String { return RECEIVER_CODE; } - // documentation inherited public override function dispatchNotification (methodId :int, args :Array) :void { switch (methodId) { case CREATE_AGENT: BureauReceiver(receiver).createAgent( - args[0] as int + (args[0] as int) ); return; case DESTROY_AGENT: BureauReceiver(receiver).destroyAgent( - args[0] as int + (args[0] as int) ); return; default: super.dispatchNotification(methodId, args); - return; } } } diff --git a/src/main/as/com/threerings/bureau/client/BureauReceiver.as b/src/main/as/com/threerings/bureau/client/BureauReceiver.as index 594600380..2fccb22c2 100644 --- a/src/main/as/com/threerings/bureau/client/BureauReceiver.as +++ b/src/main/as/com/threerings/bureau/client/BureauReceiver.as @@ -23,28 +23,12 @@ package com.threerings.bureau.client { import com.threerings.presents.client.InvocationReceiver; -/** - * Hooks for controlling a previously launched bureau client. - */ public interface BureauReceiver extends InvocationReceiver { - /** - * Creates a new agent. Implementors should create a new {@link Agent} and give it access to - * the {@link AgentObject} referred to by the agentId parameter and must notify - * the service that the agent has been created using {@link BureauService#agentCreated}. - * @param client the client receiving the request - * @param agentId the id of the AgentObject that needs an Agent - */ - function createAgent (agentId :int) :void; + // from Java interface BureauReceiver + function createAgent (arg1 :int) :void; - /** - * Destroys a previously created agent. Implementors should destroy the agent that was created - * by the call to createAgent with the same agent id and must notify - * the service that the agent has been created using {@link BureauService#agentDestroyed}. - * @param client the client receiving the request - * @param agentId the id of the AgentObject whose Agent - * should be destroyed - */ - function destroyAgent (agentId :int) :void; + // from Java interface BureauReceiver + function destroyAgent (arg1 :int) :void; } } diff --git a/src/main/as/com/threerings/crowd/client/LocationDecoder.as b/src/main/as/com/threerings/crowd/client/LocationDecoder.as index 487c7cf1a..b0f7dda34 100644 --- a/src/main/as/com/threerings/crowd/client/LocationDecoder.as +++ b/src/main/as/com/threerings/crowd/client/LocationDecoder.as @@ -21,7 +21,6 @@ package com.threerings.crowd.client { -import com.threerings.crowd.client.LocationReceiver; import com.threerings.presents.client.InvocationDecoder; /** @@ -45,19 +44,16 @@ public class LocationDecoder extends InvocationDecoder this.receiver = receiver; } - // documentation inherited - override public function getReceiverCode () :String + public override function getReceiverCode () :String { return RECEIVER_CODE; } - // documentation inherited - override public function dispatchNotification ( - methodId :int, args :Array) :void + public override function dispatchNotification (methodId :int, args :Array) :void { switch (methodId) { case FORCED_MOVE: - (receiver as LocationReceiver).forcedMove( + LocationReceiver(receiver).forcedMove( (args[0] as int) ); return; diff --git a/src/main/as/com/threerings/crowd/client/LocationReceiver.as b/src/main/as/com/threerings/crowd/client/LocationReceiver.as index c3a8c93b9..e735756d5 100644 --- a/src/main/as/com/threerings/crowd/client/LocationReceiver.as +++ b/src/main/as/com/threerings/crowd/client/LocationReceiver.as @@ -23,18 +23,9 @@ package com.threerings.crowd.client { import com.threerings.presents.client.InvocationReceiver; -/** - * Defines, for the location services, a set of notifications delivered - * asynchronously by the server to the client. - */ public interface LocationReceiver extends InvocationReceiver { - /** - * Used to communicate a required move notification to the client. The - * server will have removed the client from their existing location - * and the client is then responsible for generating a {@link - * LocationService#moveTo} request to move to the new location. - */ - function forcedMove (placeId :int) :void; + // from Java interface LocationReceiver + function forcedMove (arg1 :int) :void; } } diff --git a/src/main/java/com/threerings/presents/peer/server/PeerManager.java b/src/main/java/com/threerings/presents/peer/server/PeerManager.java index 1490480ba..770d2d96c 100644 --- a/src/main/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/main/java/com/threerings/presents/peer/server/PeerManager.java @@ -569,7 +569,6 @@ public abstract class PeerManager final DObjectAddress remote, final ResultListener listener) { if (remote.nodeName.equals(_nodeName)) { - System.out.println("Found locally!"); _omgr.postRunnable(new Runnable() { public void run () { listener.requestCompleted(remote.oid); diff --git a/src/main/java/com/threerings/presents/tools/GenReceiverTask.java b/src/main/java/com/threerings/presents/tools/GenReceiverTask.java index b99e0516d..f369024ea 100644 --- a/src/main/java/com/threerings/presents/tools/GenReceiverTask.java +++ b/src/main/java/com/threerings/presents/tools/GenReceiverTask.java @@ -29,12 +29,14 @@ import java.util.List; import java.io.File; +import com.google.common.base.Preconditions; import com.google.common.collect.Iterators; import com.samskivert.util.ComparableArrayList; import com.samskivert.util.StringUtil; import com.threerings.presents.client.InvocationDecoder; +import com.threerings.presents.client.InvocationReceiver; import com.threerings.presents.data.ClientObject; import com.threerings.presents.server.InvocationSender; @@ -43,6 +45,14 @@ import com.threerings.presents.server.InvocationSender; */ public class GenReceiverTask extends InvocationTask { + /** + * Configures the path to our ActionScript source files. + */ + public void setAsroot (File asroot) + { + _asroot = asroot; + } + @Override public void processClass (File source, Class receiver) throws Exception @@ -57,11 +67,8 @@ public class GenReceiverTask extends InvocationTask } // verify that the receiver class name is as we expect it to be - if (!rname.endsWith("Receiver")) { - System.err.println("Cannot process '" + rname + "':"); - System.err.println("Receiver classes must be named SomethingReceiver."); - return; - } + Preconditions.checkArgument(rname.endsWith("Receiver"), "Cannot process '%s'. " + + "Receiver classes must be named SomethingReceiver.", rname); ImportSet imports = new ImportSet(); ComparableArrayList methods = new ComparableArrayList(); @@ -142,8 +149,33 @@ public class GenReceiverTask extends InvocationTask "package", rpackage, "methods", methods, "imports", implist); + if (_asroot == null) { + return; + } + // generate an ActionScript decoder + String sppath = rpackage.replace('.', File.separatorChar); + String aspath = _asroot + File.separator + sppath + File.separator + name + "Decoder.as"; + writeTemplate(AS_DECODER_TMPL, aspath, + "name", name, + "receiver_code", rcode, + "package", rpackage, + "methods", methods, + "imports", implist); + + // ... and an ActionScript receiver + aspath = _asroot + File.separator + sppath + File.separator + rname + ".as"; + implist.remove(InvocationDecoder.class.getName()); + checkedAdd(implist, InvocationReceiver.class.getName()); + writeTemplate(AS_RECEIVER_TMPL, aspath, + "name", name, + "package", rpackage, + "methods", methods, + "imports", implist); } + /** The path to our ActionScript source files. */ + protected File _asroot; + /** Specifies the path to the sender template. */ protected static final String SENDER_TMPL = "com/threerings/presents/tools/sender.tmpl"; @@ -151,4 +183,12 @@ public class GenReceiverTask extends InvocationTask /** Specifies the path to the decoder template. */ protected static final String DECODER_TMPL = "com/threerings/presents/tools/decoder.tmpl"; + + /** Specifies the path to the decoder template. */ + protected static final String AS_DECODER_TMPL = + "com/threerings/presents/tools/decoder_as.tmpl"; + + /** Specifies the path to the decoder template. */ + protected static final String AS_RECEIVER_TMPL = + "com/threerings/presents/tools/receiver_as.tmpl"; } diff --git a/src/main/java/com/threerings/presents/tools/GenUtil.java b/src/main/java/com/threerings/presents/tools/GenUtil.java index e7f8d38c3..bc36bfbc8 100644 --- a/src/main/java/com/threerings/presents/tools/GenUtil.java +++ b/src/main/java/com/threerings/presents/tools/GenUtil.java @@ -47,7 +47,7 @@ public class GenUtil extends com.samskivert.util.GenUtil /** A regular expression for matching the class or interface declaration. */ public static final Pattern NAME_PATTERN = - Pattern.compile("^\\s*public\\s+(?:abstract\\s+)?(interface|class|enum)\\s+(\\S+)(\\W|$)"); + Pattern.compile("^\\s*public\\s+(?:abstract\\s+)?(@?interface|class|enum)\\s+([\\w$]+)"); /** * Returns the name of the supplied class as it would appear in ActionScript code using the diff --git a/src/main/java/com/threerings/presents/tools/ImportSet.java b/src/main/java/com/threerings/presents/tools/ImportSet.java index 788199a6a..d34a2f41b 100644 --- a/src/main/java/com/threerings/presents/tools/ImportSet.java +++ b/src/main/java/com/threerings/presents/tools/ImportSet.java @@ -44,7 +44,7 @@ import com.samskivert.util.StringUtil; *

A few methods also use a "pattern" string parameter that is used to match a class name. * This is a dumbed down regular expression (to avoid many \.) where "*" means .* and no other * characters have special meaning. The pattern is also implicitly enclosed with ^$ so that the - * pattern must match the class name in its entirity. Callers will mostly use this to specify a + * pattern must match the class name in its entirety. Callers will mostly use this to specify a * prefix like "something*" or a suffix like "*something". */ public class ImportSet diff --git a/src/main/resources/com/threerings/presents/tools/decoder_as.tmpl b/src/main/resources/com/threerings/presents/tools/decoder_as.tmpl new file mode 100644 index 000000000..56ed55e5e --- /dev/null +++ b/src/main/resources/com/threerings/presents/tools/decoder_as.tmpl @@ -0,0 +1,51 @@ +package {{package}} { + +{{#imports}} +import {{this}}; +{{/imports}} + +/** + * Dispatches calls to a {@link {{name}}Receiver} instance. + */ +public class {{name}}Decoder extends InvocationDecoder +{ + /** The generated hash code used to identify this receiver class. */ + public static const RECEIVER_CODE :String = "{{receiver_code}}"; + +{{#methods}} + /** The method id used to dispatch {@link {{name}}Receiver#{{method.name}}} + * notifications. */ + public static const {{code}} :int = {{-index}}; + +{{/methods}} + /** + * Creates a decoder that may be registered to dispatch invocation + * service notifications to the specified receiver. + */ + public function {{name}}Decoder (receiver :{{name}}Receiver) + { + this.receiver = receiver; + } + + public override function getReceiverCode () :String + { + return RECEIVER_CODE; + } + + public override function dispatchNotification (methodId :int, args :Array) :void + { + switch (methodId) { +{{#methods}} + case {{code}}: + {{name}}Receiver(receiver).{{method.name}}( + {{getASUnwrappedArgList}} + ); + return; + +{{/methods}} + default: + super.dispatchNotification(methodId, args); + } + } +} +} diff --git a/src/main/resources/com/threerings/presents/tools/receiver_as.tmpl b/src/main/resources/com/threerings/presents/tools/receiver_as.tmpl new file mode 100644 index 000000000..e06e41074 --- /dev/null +++ b/src/main/resources/com/threerings/presents/tools/receiver_as.tmpl @@ -0,0 +1,17 @@ +package {{package}} { + +{{#imports}} +import {{this}}; +{{/imports}} + +public interface {{name}}Receiver extends InvocationReceiver +{ +{{#methods}} +{{^-first}} + +{{/-first}} + // from Java interface {{name}}Receiver + function {{method.name}} ({{getASArgList}}) :void; +{{/methods}} +} +}