Macros.hx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package hrt.shgraph;
  2. import haxe.macro.Context;
  3. import haxe.macro.Expr;
  4. import hxsl.Ast;
  5. using hxsl.Ast;
  6. using haxe.macro.Tools;
  7. class Macros {
  8. #if macro
  9. static function buildNode() {
  10. var fields = Context.getBuildFields();
  11. for (f in fields) {
  12. if (f.name == "SRC") {
  13. switch (f.kind) {
  14. case FVar(_, expr) if (expr != null):
  15. var pos = expr.pos;
  16. if( !Lambda.has(f.access, AStatic) ) f.access.push(AStatic);
  17. Context.getLocalClass().get().meta.add(":src", [expr], pos);
  18. try {
  19. var c = Context.getLocalClass();
  20. // function map(e: haxe.macro.Expr) {
  21. // switch(e) {
  22. // case EMeta("sginput", args, e):
  23. // trace("sginput");
  24. // }
  25. // }
  26. // expr.map()
  27. var inVars : Array<String> = [];
  28. var outVars : Array<String> = [];
  29. var defValues : Array<String> = [];
  30. function iter(e: haxe.macro.Expr) : Void {
  31. switch(e.expr) {
  32. case EMeta(meta, subexpr):
  33. switch (meta.name) {
  34. case "sginput":
  35. var defValue = null;
  36. if (meta.params != null && meta.params.length > 0) {
  37. switch (meta.params[0].expr) {
  38. case EConst(v):
  39. switch(v) {
  40. case CIdent(name):
  41. defValue = name;
  42. case CFloat(val), CInt(val):
  43. defValue = '$val';
  44. default:
  45. throw "sginput default param must be an identifier or a integer";
  46. }
  47. default:
  48. trace(meta.params[0].expr);
  49. throw "sginput default param must be a constant value";
  50. }
  51. }
  52. switch(subexpr.expr) {
  53. case EVars(vars):
  54. for (v in vars) {
  55. inVars.push(v.name);
  56. defValues.push(defValue);
  57. }
  58. e.expr = subexpr.expr;
  59. default:
  60. throw "sginput must be used with variables only";
  61. }
  62. case "sgoutput":
  63. switch(subexpr.expr) {
  64. case EVars(vars):
  65. for (v in vars) {
  66. outVars.push(v.name);
  67. }
  68. e.expr = subexpr.expr;
  69. default:
  70. throw "sgoutput must be used with variables only";
  71. }
  72. default:
  73. }
  74. default:
  75. }
  76. }
  77. expr.iter(iter);
  78. var shader = new hxsl.MacroParser().parseExpr(expr);
  79. f.kind = FVar(null, macro @:pos(pos) $v{shader});
  80. var check = new hxsl.Checker();
  81. check.warning = function(msg,pos) {
  82. haxe.macro.Context.warning(msg, pos);
  83. };
  84. var name = Std.string(c);
  85. var name = Std.string(c);
  86. var check = new hxsl.Checker();
  87. check.warning = function(msg,pos) {
  88. haxe.macro.Context.warning(msg, pos);
  89. };
  90. var shader = check.check(name, shader);
  91. //trace(shader);
  92. //Printer.check(shader);
  93. var str = Context.defined("display") ? "" : hxsl.Serializer.run(shader);
  94. f.kind = FVar(null, { expr : EConst(CString(str)), pos : pos } );
  95. f.meta.push({
  96. name : ":keep",
  97. pos : pos,
  98. });
  99. function makeField(name: String, arr: Array<String>) : Field
  100. {
  101. return {
  102. name: name,
  103. access: [APublic, AStatic],
  104. kind: FVar(macro : Array<String>, macro $v{arr}),
  105. pos: f.pos,
  106. meta: [{
  107. name : ":keep",
  108. pos : pos,}
  109. ],
  110. };
  111. }
  112. var inVarField : Field = makeField("_inVars", inVars);
  113. var outVarField : Field = makeField("_outVars", outVars);
  114. var defValuesField : Field = makeField("_defValues", defValues);
  115. fields.push(inVarField);
  116. fields.push(outVarField);
  117. fields.push(defValuesField);
  118. } catch( e : hxsl.Ast.Error ) {
  119. fields.remove(f);
  120. Context.error(e.msg, e.pos);
  121. }
  122. default:
  123. }
  124. }
  125. }
  126. return fields;
  127. }
  128. static function autoRegisterNode() {
  129. var fields = Context.getBuildFields();
  130. var thisClass = Context.getLocalClass();
  131. var cl = thisClass.get();
  132. var clPath = cl.pack.copy();
  133. clPath.push(cl.name);
  134. #if editor
  135. fields.push({
  136. name: "_",
  137. access: [Access.AStatic],
  138. kind: FieldType.FVar(macro:Bool, macro ShaderNode.register($v{cl.name}, ${clPath.toFieldExpr()})),
  139. pos: Context.currentPos(),
  140. });
  141. #end
  142. return fields;
  143. }
  144. #end
  145. }