[dispatcher] add dispatcher macro
This commit is contained in:
90
src/main/haxework/macro/DispatcherMacro.hx
Normal file
90
src/main/haxework/macro/DispatcherMacro.hx
Normal file
@@ -0,0 +1,90 @@
|
||||
package haxework.macro;
|
||||
|
||||
import haxe.macro.TypeTools;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.ExprTools;
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Type;
|
||||
|
||||
class DispatcherMacro {
|
||||
|
||||
private static inline var metaName:String = ':dispatcher';
|
||||
|
||||
public static function has(classType:ClassType):Bool {
|
||||
return classType.meta.has(metaName);
|
||||
}
|
||||
|
||||
private var classType:ClassType;
|
||||
private var fields:Array<Field>;
|
||||
|
||||
public function new(classType:ClassType, fields:Array<Field>) {
|
||||
this.classType = classType;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public function apply():Array<Field> {
|
||||
var result:Array<Field> = fields.slice(0);
|
||||
var typeName = ExprTools.toString(classType.meta.extract(metaName)[0].params[0]);
|
||||
var type:ClassType = switch Context.getType(typeName) {
|
||||
case TInst(t, _): t.get();
|
||||
case _: null;
|
||||
}
|
||||
var fields = type.fields.get();
|
||||
for (field in fields) {
|
||||
var argsTypes:Array<Type> = switch field.type {
|
||||
case TFun(args, _): args.map(function(arg) return arg.t);
|
||||
case _ : [];
|
||||
}
|
||||
var signal = 'Signal${argsTypes.length}';
|
||||
var type = TPath({
|
||||
pack: ['haxework', 'signal'],
|
||||
name: 'Signal',
|
||||
sub: signal,
|
||||
params: argsTypes.map(function(t) return TPType(TypeTools.toComplexType(t))),
|
||||
});
|
||||
result.push({
|
||||
name: '${field.name}Change',
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
kind: FProp('default', 'null', type, Context.parse('new haxework.signal.Signal.${signal}()', Context.currentPos())),
|
||||
});
|
||||
}
|
||||
result.push({
|
||||
name: 'connect',
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
kind: FFun({
|
||||
args: [{
|
||||
name: 'listener',
|
||||
type: TPath({
|
||||
pack: type.pack,
|
||||
name: type.name,
|
||||
}),
|
||||
}],
|
||||
ret: null,
|
||||
expr: macro $b{fields.map(function(field) {
|
||||
return Context.parse('${field.name}Change.connect(listener.${field.name})', Context.currentPos());
|
||||
})},
|
||||
}),
|
||||
});
|
||||
result.push({
|
||||
name: 'disconnect',
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
kind: FFun({
|
||||
args: [{
|
||||
name: 'listener',
|
||||
type: TPath({
|
||||
pack: type.pack,
|
||||
name: type.name,
|
||||
}),
|
||||
}],
|
||||
ret: null,
|
||||
expr: macro $b{fields.map(function(field) {
|
||||
return Context.parse('${field.name}Change.disconnect(listener.${field.name})', Context.currentPos());
|
||||
})},
|
||||
}),
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,11 @@ package haxework.parser;
|
||||
import haxe.macro.Context;
|
||||
import haxe.macro.Expr;
|
||||
import haxe.macro.Type;
|
||||
import haxework.macro.DispatcherMacro;
|
||||
import haxework.macro.ProvideMacro;
|
||||
import haxework.macro.ResourceMacro;
|
||||
import haxework.macro.TemplateMacro;
|
||||
|
||||
|
||||
class Parser {
|
||||
|
||||
private static function auto():Void {
|
||||
@@ -46,6 +46,11 @@ class Parser {
|
||||
var template = new TemplateMacro(ct, fields);
|
||||
fields = template.apply();
|
||||
}
|
||||
if (DispatcherMacro.has(ct)) {
|
||||
modify = true;
|
||||
var dispatcher = new DispatcherMacro(ct, fields);
|
||||
fields = dispatcher.apply();
|
||||
}
|
||||
return modify ? fields : null;
|
||||
default: return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user