improved RPC macro
This commit is contained in:
		
							parent
							
								
									f3a13e4247
								
							
						
					
					
						commit
						db50a93512
					
				
							
								
								
									
										46
									
								
								src/macros/Helper.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/macros/Helper.hx
									
									
									
									
									
										Normal 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
 | 
			
		||||
@ -10,6 +10,7 @@ class RPC {
 | 
			
		||||
		var fields = Context.getBuildFields();
 | 
			
		||||
 | 
			
		||||
		var className = Context.getLocalClass().get().name + "RPC";
 | 
			
		||||
		var imports = Context.getLocalImports();
 | 
			
		||||
 | 
			
		||||
		var c = macro class $className extends macros.rpc.RPCBase {
 | 
			
		||||
			public function new(id:kernel.net.Package.NetworkID) {
 | 
			
		||||
@ -27,15 +28,22 @@ class RPC {
 | 
			
		||||
				case FFun(f):
 | 
			
		||||
					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({
 | 
			
		||||
						name: field.name,
 | 
			
		||||
						pos: field.pos,
 | 
			
		||||
						kind: FFun({
 | 
			
		||||
							args: f.args,
 | 
			
		||||
							args: convertedArgs,
 | 
			
		||||
							expr: macro {
 | 
			
		||||
								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],
 | 
			
		||||
						doc: null,
 | 
			
		||||
@ -47,7 +55,6 @@ class RPC {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		haxe.macro.Context.defineType(c);
 | 
			
		||||
 | 
			
		||||
		return fields;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -73,12 +80,20 @@ class RPC {
 | 
			
		||||
						case TFun(args, ret):
 | 
			
		||||
							var callArgs = [for (k => v in args) macro pack.data.args[$v{k}]];
 | 
			
		||||
 | 
			
		||||
							// TODO: transform this to a switch statement
 | 
			
		||||
							exprs.push(macro {
 | 
			
		||||
								if (pack.data.func == $v{funName}) {
 | 
			
		||||
									pack.respond(this.$funName($a{callArgs}));
 | 
			
		||||
								}
 | 
			
		||||
							});
 | 
			
		||||
							if (Helper.isVoid(ret)){
 | 
			
		||||
								exprs.push(macro {
 | 
			
		||||
									if (pack.data.func == $v{funName}) {
 | 
			
		||||
										this.$funName($a{callArgs});
 | 
			
		||||
										pack.respond(null);
 | 
			
		||||
									}
 | 
			
		||||
								});
 | 
			
		||||
							}else{
 | 
			
		||||
								exprs.push(macro {
 | 
			
		||||
									if (pack.data.func == $v{funName}) {
 | 
			
		||||
										pack.respond(this.$funName($a{callArgs}));
 | 
			
		||||
									}
 | 
			
		||||
								});
 | 
			
		||||
							}
 | 
			
		||||
						default:
 | 
			
		||||
							Context.error("Only functions can be used for rpc", field.pos);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
@ -22,7 +22,7 @@ abstract class RPCBase {
 | 
			
		||||
		}).map((res) -> {
 | 
			
		||||
			switch (res) {
 | 
			
		||||
				case Success(pack):
 | 
			
		||||
					return pack.data;
 | 
			
		||||
					return Success(pack.data);
 | 
			
		||||
				case Failure(_):
 | 
			
		||||
					return res;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user