[dispatcher] add dispatcher macro
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package demo;
|
||||
|
||||
import demo.dispatch.DemoDispatcher;
|
||||
import haxework.net.JsonLoader;
|
||||
import demo.popup.ColorPopup;
|
||||
import haxework.App;
|
||||
@@ -30,16 +31,28 @@ import haxework.log.TraceLogger;
|
||||
}
|
||||
}
|
||||
|
||||
class Demo extends App {
|
||||
class Demo extends App implements DemoListener {
|
||||
|
||||
public static function main() {
|
||||
L.push(new TraceLogger());
|
||||
|
||||
var app = new App();
|
||||
var app = new Demo();
|
||||
app.resources.image.put("logo", HaxeLogo.resolve());
|
||||
Theme.setColor(0x33aa33);
|
||||
app.start(new DemoView());
|
||||
|
||||
var dispatcher = new DemoDispatcher();
|
||||
dispatcher.connect(app);
|
||||
dispatcher.test1Change.emit();
|
||||
dispatcher.test2Change.emit(1);
|
||||
dispatcher.test3Change.emit(1, "test");
|
||||
dispatcher.test4Change.emit(app);
|
||||
dispatcher.disconnect(app);
|
||||
dispatcher.test1Change.emit();
|
||||
dispatcher.test2Change.emit(1);
|
||||
dispatcher.test3Change.emit(1, "test");
|
||||
dispatcher.test4Change.emit(app);
|
||||
|
||||
new JsonLoader().GET("http://umix.tv/channel/data2/renova.json")
|
||||
.then(function(data:Array<Model>) {
|
||||
app.resources.any.put("data", data);
|
||||
@@ -47,4 +60,21 @@ class Demo extends App {
|
||||
})
|
||||
.catchError(function(error) trace(error));
|
||||
}
|
||||
|
||||
public function test1():Void {
|
||||
trace('test1');
|
||||
}
|
||||
|
||||
public function test2(a:Int):Void {
|
||||
trace('test2', a);
|
||||
}
|
||||
|
||||
public function test3(a:Int, b:String):Void {
|
||||
trace('test3', a, b);
|
||||
}
|
||||
|
||||
public function test4(app: App):Void {
|
||||
trace('test4', app);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
14
demo/src/demo/dispatch/DemoDispatcher.hx
Normal file
14
demo/src/demo/dispatch/DemoDispatcher.hx
Normal file
@@ -0,0 +1,14 @@
|
||||
package demo.dispatch;
|
||||
|
||||
import haxework.App;
|
||||
|
||||
interface DemoListener {
|
||||
public function test1():Void;
|
||||
public function test2(a:Int):Void;
|
||||
public function test3(a:Int, b:String):Void;
|
||||
public function test4(app:App):Void;
|
||||
}
|
||||
|
||||
@:dispatcher(DemoListener) class DemoDispatcher {
|
||||
public function new() {}
|
||||
}
|
||||
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