improved RPC macro

This commit is contained in:
Djeeberjr 2023-07-30 23:18:51 +02:00
parent f3a13e4247
commit db50a93512
3 changed files with 71 additions and 10 deletions

46
src/macros/Helper.hx Normal file
View File

@ -0,0 +1,46 @@
package macros;
#if macro
import haxe.macro.TypeTools;
import haxe.macro.Expr.Position;
import haxe.macro.Expr.ComplexType;
import haxe.macro.Context;
import haxe.macro.Type;
class Helper {
public static function resolveType(t: ComplexType,pos: Position): Null<ComplexType> {
if (t == null) return null;
return TypeTools.toComplexType(Context.resolveType(t,pos));
}
public static function newPromise(t: ComplexType): ComplexType {
if (Helper.isVoidC(t)){
return TPath({name: "Promise", params: [TPType(TPath({name:"Noise",pack: ["tink", "core"]}))], pack: ["tink", "core"]});
}
return TPath({name: "Promise", params: [TPType(t)], pack: ["tink", "core"]});
}
public static function isVoidC(t: ComplexType): Bool {
switch (t){
case TPath(p):
return (p.name == "Void");
default:
return false;
}
}
public static function isVoid(t: Type) {
switch (t){
case TAbstract(t, _):
return (t.get().name == "Void");
default:
return false;
}
}
}
#end

View File

@ -10,6 +10,7 @@ class RPC {
var fields = Context.getBuildFields(); var fields = Context.getBuildFields();
var className = Context.getLocalClass().get().name + "RPC"; var className = Context.getLocalClass().get().name + "RPC";
var imports = Context.getLocalImports();
var c = macro class $className extends macros.rpc.RPCBase { var c = macro class $className extends macros.rpc.RPCBase {
public function new(id:kernel.net.Package.NetworkID) { public function new(id:kernel.net.Package.NetworkID) {
@ -27,15 +28,22 @@ class RPC {
case FFun(f): case FFun(f):
var argsExprs:Array<Expr> = [for (a in f.args) macro $i{a.name}]; var argsExprs:Array<Expr> = [for (a in f.args) macro $i{a.name}];
var convertedArgs = [];
for (a in f.args) {
a.type = Helper.resolveType(a.type,field.pos);
convertedArgs.push(a);
}
c.fields.push({ c.fields.push({
name: field.name, name: field.name,
pos: field.pos, pos: field.pos,
kind: FFun({ kind: FFun({
args: f.args, args: convertedArgs,
expr: macro { expr: macro {
return cast this._performRequest($v{field.name}, $a{argsExprs}); return cast this._performRequest($v{field.name}, $a{argsExprs});
}, },
ret: TPath({name: "Promise", params: [TPType(f.ret)], pack: ["tink", "core"]}), ret: Helper.newPromise(Helper.resolveType(f.ret,field.pos)),
}), }),
access: [APublic], access: [APublic],
doc: null, doc: null,
@ -47,7 +55,6 @@ class RPC {
} }
haxe.macro.Context.defineType(c); haxe.macro.Context.defineType(c);
return fields; return fields;
} }
@ -73,12 +80,20 @@ class RPC {
case TFun(args, ret): case TFun(args, ret):
var callArgs = [for (k => v in args) macro pack.data.args[$v{k}]]; var callArgs = [for (k => v in args) macro pack.data.args[$v{k}]];
// TODO: transform this to a switch statement if (Helper.isVoid(ret)){
exprs.push(macro {
if (pack.data.func == $v{funName}) {
this.$funName($a{callArgs});
pack.respond(null);
}
});
}else{
exprs.push(macro { exprs.push(macro {
if (pack.data.func == $v{funName}) { if (pack.data.func == $v{funName}) {
pack.respond(this.$funName($a{callArgs})); pack.respond(this.$funName($a{callArgs}));
} }
}); });
}
default: default:
Context.error("Only functions can be used for rpc", field.pos); Context.error("Only functions can be used for rpc", field.pos);
} }

View File

@ -22,7 +22,7 @@ abstract class RPCBase {
}).map((res) -> { }).map((res) -> {
switch (res) { switch (res) {
case Success(pack): case Success(pack):
return pack.data; return Success(pack.data);
case Failure(_): case Failure(_):
return res; return res;
} }