Skip to content

Instantly share code, notes, and snippets.

@elsassph
Last active May 25, 2016 20:04
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save elsassph/d3d1f1dc461d50eface1 to your computer and use it in GitHub Desktop.
Save elsassph/d3d1f1dc461d50eface1 to your computer and use it in GitHub Desktop.
Haxe - use macro to generate dispatch code
/*
Automatically generate dispatch functions as:
public function onDoubleArguments(one:String, two:Int) {
for (listener in listeners)
listener.onDoubleArguments(one, two);
}
*/
class Example extends Dispatcher<Dynamic>
{
public function onDoubleArguments(one:String, two:Int);
public function onSingleArgument(one:String);
public function onNoArgument();
public function onEmptyBody() { }
public function onNonEmptyBody() {
trace('my code here');
}
}
@:autoBuild(DispatchBuilder.build())
class Dispatcher<T>
{
var listeners:Array<T>;
public function new() {
listeners = [];
}
// addListener, removeListener,...
}
#if macro
import haxe.macro.Context;
import haxe.macro.Expr;
class DispatchBuilder
{
macro static public function build():Array<Field>
{
var fields = Context.getBuildFields();
for (field in fields)
{
if (field.name == 'new') continue;
switch (field.kind)
{
case FieldType.FFun(fn):
if (!isEmpty(fn.expr)) continue;
var fname = field.name;
var args = [for (arg in fn.args) macro $i{arg.name}];
fn.expr = macro {
for (listener in listeners)
listener.$fname( $a{args} );
}
default:
}
}
return fields;
}
static function isEmpty(expr:Expr)
{
if (expr == null) return true;
return switch (expr.expr) {
case ExprDef.EBlock(exprs): exprs.length == 0;
default: false;
}
}
}
#end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment