diff --git a/src/kernel/peripherals/Redstone.hx b/src/kernel/peripherals/Redstone.hx index b6d2bc1..7b56b7c 100644 --- a/src/kernel/peripherals/Redstone.hx +++ b/src/kernel/peripherals/Redstone.hx @@ -43,6 +43,7 @@ abstract BundleMask(Int) from cc.Colors.Color to cc.Colors.Color { } } +@:build(macros.Exporter.buildExport()) class Redstone implements IPeripheral implements IExportable { public static inline final TYPE_NAME:String = "redstone"; // TODO: there is technically not a type for redstone. @@ -89,10 +90,12 @@ class Redstone implements IPeripheral implements IExportable { cc.Redstone.setOutput(this.addr,on); } + @export("output") public inline function getOutput(): Bool { return cc.Redstone.getOutput(this.addr); } + @export("input") public inline function getInput(): Bool { return cc.Redstone.getInput(this.addr); } @@ -126,14 +129,4 @@ class Redstone implements IPeripheral implements IExportable { public inline function testBundledInput(mask: Color): Bool { return cc.Redstone.testBundledInput(this.addr,mask); } - - - public function export():ExportConfig { - return { - getDelegates: [ - "input" => (_) -> {return Bool(this.getInput());}, - "analog" => (_) -> {return Number(this.getAnalogInput());} - ] - }; - } } diff --git a/src/macros/Exporter.hx b/src/macros/Exporter.hx new file mode 100644 index 0000000..1afe8bc --- /dev/null +++ b/src/macros/Exporter.hx @@ -0,0 +1,77 @@ +package macros; + +import haxe.macro.Context; +import haxe.macro.Expr; +using Lambda; + +class Exporter { + macro public static function buildExport():Array { + var fields = Context.getBuildFields(); + + var getExp = []; + + for (field in fields){ + if (field.meta == null) continue; + + var s = ""; + for (meta in field.meta){ + if (meta.name == "export"){ + switch (meta.params[0].expr){ + case EConst(CString(s1)): + s = s1; + default: + Context.error("Invalid export name", meta.pos); + } + } + } + + if (s == "") continue; + + switch (field.kind){ + case FFun(f): + var funName = field.name; + switch (f.ret){ + case TPath(p): + switch (p.name){ + case "Int": + getExp.push( macro $v{s} => (i: Int) -> lib.exporter.Response.ValueType.Int(this.$funName()) ); + case "Float": + getExp.push( macro $v{s} => (i: Int) -> lib.exporter.Response.ValueType.Float(this.$funName()) ); + case "Bool": + getExp.push( macro $v{s} => (i: Int) -> lib.exporter.Response.ValueType.Bool(this.$funName()) ); + case "String": + getExp.push( macro $v{s} => (i: Int) -> lib.exporter.Response.ValueType.String(this.$funName()) ); + default: + Context.error("Only Int, Float, Bool and String can be exported", field.pos); + } + default: + Context.error("Only functions returning a type can be exported", field.pos); + } + default: + Context.error("Only functions can be exported", field.pos); + } + } + + var exportField: Field = { + name: "export", + pos: Context.currentPos(), + kind: FFun({ + args: [], + ret: TPath({ name: "ExportConfig", pack: []}), + expr: macro { + return { + getDelegates: $a{getExp}, + }; + } + }), + access: [APublic], + doc: null, + meta: [], + }; + + fields.push(exportField); + + return fields; + } +} + \ No newline at end of file