added RPC macro
This commit is contained in:
parent
10a061c41b
commit
5fa6c3ecbf
@ -1,5 +1,6 @@
|
|||||||
package bin;
|
package bin;
|
||||||
|
|
||||||
|
import kernel.log.Log;
|
||||||
import kernel.ps.ProcessHandle;
|
import kernel.ps.ProcessHandle;
|
||||||
import kernel.ps.Process;
|
import kernel.ps.Process;
|
||||||
|
|
||||||
@ -11,6 +12,13 @@ class HelloWorld implements Process {
|
|||||||
|
|
||||||
public function run(handle:ProcessHandle) {
|
public function run(handle:ProcessHandle) {
|
||||||
handle.write("Hello World!");
|
handle.write("Hello World!");
|
||||||
|
|
||||||
|
var c = new HelloWorldServiceRPC(0);
|
||||||
|
|
||||||
|
c.getNumber().handle((res)->{
|
||||||
|
Log.debug("Got number: " + res);
|
||||||
|
});
|
||||||
|
|
||||||
handle.close();
|
handle.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
package bin;
|
package bin;
|
||||||
|
|
||||||
import kernel.Timer;
|
import macros.rpc.RPC;
|
||||||
import kernel.ps.ProcessHandle;
|
import kernel.ps.ProcessHandle;
|
||||||
import kernel.ps.Process;
|
import kernel.ps.Process;
|
||||||
|
|
||||||
|
using tink.CoreApi;
|
||||||
|
|
||||||
|
@:build(macros.rpc.RPC.buildRPC())
|
||||||
class HelloWorldService implements Process {
|
class HelloWorldService implements Process {
|
||||||
private var timer:Timer;
|
private var handle:ProcessHandle;
|
||||||
|
|
||||||
public function new() {}
|
public function new() {}
|
||||||
|
|
||||||
public function run(handle:ProcessHandle) {
|
public function run(handle:ProcessHandle) {
|
||||||
handle.write("Hello World! Started\n");
|
this.handle = handle;
|
||||||
this.startTimer(handle);
|
|
||||||
handle.addDeferFunc(()->{
|
RPC.generateRPCPackageHandle();
|
||||||
timer.cancle();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function startTimer(handle: ProcessHandle) {
|
@rpc
|
||||||
this.timer = new Timer(5, function() {
|
public function getNumber():Int{
|
||||||
handle.write("Hello World!\n");
|
return 42;
|
||||||
this.startTimer(handle);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
79
src/macros/rpc/RPC.hx
Normal file
79
src/macros/rpc/RPC.hx
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package macros.rpc;
|
||||||
|
|
||||||
|
import haxe.macro.Context;
|
||||||
|
import haxe.macro.Expr;
|
||||||
|
using Lambda;
|
||||||
|
|
||||||
|
class RPC {
|
||||||
|
macro static public function buildRPC(): Array<Field> {
|
||||||
|
var fields = Context.getBuildFields();
|
||||||
|
|
||||||
|
var className = Context.getLocalClass().get().name + "RPC";
|
||||||
|
|
||||||
|
var c = macro class $className extends macros.rpc.RPCBase {
|
||||||
|
public function new(id: kernel.net.Package.NetworkID) {
|
||||||
|
super(id,$v{className});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (field in fields){
|
||||||
|
if (field.meta == null) continue;
|
||||||
|
if (field.meta.exists((i) -> i.name == "rpc") == false) continue;
|
||||||
|
|
||||||
|
switch (field.kind){
|
||||||
|
case FFun(f):
|
||||||
|
c.fields.push({
|
||||||
|
name: field.name,
|
||||||
|
pos: field.pos,
|
||||||
|
kind: FFun({
|
||||||
|
args: f.args,
|
||||||
|
expr: macro {
|
||||||
|
return cast this._performRequest($v{field.name},[]);
|
||||||
|
},
|
||||||
|
ret: TPath({name: "Promise", params: [TPType(f.ret)], pack: ["tink","core"]}),
|
||||||
|
}),
|
||||||
|
access: [APublic],
|
||||||
|
doc: null,
|
||||||
|
meta: [],
|
||||||
|
});
|
||||||
|
default:
|
||||||
|
Context.error("Only functions can be used for rpc", field.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
haxe.macro.Context.defineType(c);
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
macro static public function generateRPCPackageHandle() {
|
||||||
|
var proto = Context.getLocalClass().get().name + "RPC";
|
||||||
|
var exprs: Array<Expr> = [];
|
||||||
|
|
||||||
|
var fields = Context.getLocalClass().get().fields.get();
|
||||||
|
|
||||||
|
for (field in fields){
|
||||||
|
if (field.meta == null) continue;
|
||||||
|
if (!field.meta.has("rpc")) continue;
|
||||||
|
|
||||||
|
switch (field.kind){
|
||||||
|
case FMethod(k):
|
||||||
|
var funName = field.name;
|
||||||
|
exprs.push(macro {
|
||||||
|
if (pack.data.func == $v{funName}){
|
||||||
|
pack.respond(this.$funName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
default:
|
||||||
|
Context.error("Only functions can be used for rpc", field.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return macro {
|
||||||
|
kernel.net.Net.instance.registerProto($v{proto},(pack)->{
|
||||||
|
$a{exprs}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
29
src/macros/rpc/RPCBase.hx
Normal file
29
src/macros/rpc/RPCBase.hx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package macros.rpc;
|
||||||
|
|
||||||
|
import kernel.net.Net;
|
||||||
|
import kernel.net.Package.NetworkID;
|
||||||
|
|
||||||
|
using tink.CoreApi;
|
||||||
|
|
||||||
|
abstract class RPCBase {
|
||||||
|
public final id:NetworkID;
|
||||||
|
private final _proto:String;
|
||||||
|
public function new(id: NetworkID, proto: String) {
|
||||||
|
this.id = id;
|
||||||
|
this._proto = proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _performRequest(func: String, args: Array<Dynamic>):Promise<Dynamic> {
|
||||||
|
return Net.instance.sendAndAwait(id, this._proto, {
|
||||||
|
func: func,
|
||||||
|
// args: args
|
||||||
|
}).map((res) -> {
|
||||||
|
switch (res){
|
||||||
|
case Success(pack):
|
||||||
|
return pack.data;
|
||||||
|
case Failure(_):
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user