bindAll dispatch field name

This commit is contained in:
Dima Granetchi
2015-07-20 10:29:04 +03:00
parent d77d0f104d
commit 95d6e3d721
3 changed files with 43 additions and 23 deletions
+28 -15
View File
@@ -76,6 +76,8 @@ class Signal<T> {
class SignalTools { class SignalTools {
static public inline var BIND_SIGNAL_META = "BindSignal"; static public inline var BIND_SIGNAL_META = "BindSignal";
static public inline var SIGNAL_POSTFIX = "Changed";
static public function unbindAll(bindable:bindx.IBindable):Void { static public function unbindAll(bindable:bindx.IBindable):Void {
var meta = haxe.rtti.Meta.getFields(std.Type.getClass(bindable)); var meta = haxe.rtti.Meta.getFields(std.Type.getClass(bindable));
@@ -86,44 +88,55 @@ class SignalTools {
if (signal != null) { if (signal != null) {
signal.removeAll(); signal.removeAll();
var args:Array<Dynamic> = std.Reflect.field(data, BIND_SIGNAL_META); var args:Array<Dynamic> = std.Reflect.field(data, BIND_SIGNAL_META);
var lazy:Bool = args[0]; var lazy:Bool = args[1];
if (lazy) std.Reflect.setField(bindable, m, null); if (lazy) std.Reflect.setField(bindable, m, null);
} }
} }
} }
} }
static public function bindAll(bindable:bindx.IBindable, callback:Void -> Void, force = true):Void -> Void { static public function bindAll(bindable:bindx.IBindable, callback:String -> Void, force = true):Void -> Void {
var listenField = function (_, _) callback(); var listeners = new Map<bindx.BindSignal.Signal<Dynamic>, Dynamic>();
var listenMethod = callback;
var signals = getSignals(bindable, force); var signals = getSignals(bindable, force);
for (signal in signals) { for (name in signals.keys()) {
if (Std.is(signal, FieldSignal)) signal.add(listenField); var signal = signals.get(name);
else signal.add(listenMethod); if (std.Std.is(signal, FieldSignal)) {
var listener = function (_, _) callback(name);
listeners.set(signal, listener);
signal.add(listener);
} else {
var listener = function () callback(name);
listeners.set(signal, listener);
signal.add(listener);
}
} }
return function () { return function () {
for (signal in signals) { for (signal in listeners.keys()) {
if (Std.is(signal, FieldSignal)) signal.remove(listenField); var listener = listeners.get(signal);
else signal.remove(listenMethod); if (Std.is(signal, FieldSignal)) signal.remove(listener);
else signal.remove(listener);
} }
} }
} }
static function getSignals(bindable:bindx.IBindable, force = true):Array<bindx.BindSignal.Signal<Dynamic>> { static function getSignals(bindable:bindx.IBindable, force = true):Map<String, bindx.BindSignal.Signal<Dynamic>> {
var signals = []; var signals = new Map<String, bindx.BindSignal.Signal<Dynamic>>();
var meta = haxe.rtti.Meta.getFields(std.Type.getClass(bindable)); var meta = haxe.rtti.Meta.getFields(std.Type.getClass(bindable));
if (meta != null) for (m in std.Reflect.fields(meta)) { if (meta != null) for (m in std.Reflect.fields(meta)) {
var data = std.Reflect.field(meta, m); var data = std.Reflect.field(meta, m);
if (std.Reflect.hasField(data, BIND_SIGNAL_META)) { if (std.Reflect.hasField(data, BIND_SIGNAL_META)) {
var args:Array<Dynamic> = std.Reflect.field(data, BIND_SIGNAL_META);
var signal:bindx.BindSignal.Signal<Dynamic> = cast std.Reflect.field(bindable, m); var signal:bindx.BindSignal.Signal<Dynamic> = cast std.Reflect.field(bindable, m);
if (signal == null && force) { if (signal == null && force) {
var args:Array<Dynamic> = std.Reflect.field(data, BIND_SIGNAL_META); var lazy:Bool = args[1];
var lazy:Bool = args[0];
if (lazy) signal = cast std.Reflect.getProperty(bindable, m.substr(1)); if (lazy) signal = cast std.Reflect.getProperty(bindable, m.substr(1));
} }
if (signal != null) signals.push(signal); if (signal != null) {
var name = args[0];
signals.set(name, signal);
}
} }
} }
return signals; return signals;
+5 -6
View File
@@ -11,8 +11,6 @@ using haxe.macro.Tools;
class BindSignalProvider implements IBindingSignalProvider { class BindSignalProvider implements IBindingSignalProvider {
static inline var SIGNAL_POSTFIX = "Changed";
/** /**
* default value: true * default value: true
*/ */
@@ -24,7 +22,7 @@ class BindSignalProvider implements IBindingSignalProvider {
public function new() {} public function new() {}
@:extern static inline function signalName(fieldName:String):String return fieldName + SIGNAL_POSTFIX; @:extern static inline function signalName(fieldName:String):String return fieldName + SignalTools.SIGNAL_POSTFIX;
@:extern static inline function signalGetterName(fieldName:String):String return "get_" + signalName(fieldName); @:extern static inline function signalGetterName(fieldName:String):String return "get_" + signalName(fieldName);
@:extern static inline function signalPrivateName(fieldName:String):String return "_" + signalName(fieldName); @:extern static inline function signalPrivateName(fieldName:String):String return "_" + signalName(fieldName);
@@ -98,7 +96,8 @@ class BindSignalProvider implements IBindingSignalProvider {
} }
function generateSignal(field:Field, type:ComplexType, builder:Expr, res:Array<Field>):Void { function generateSignal(field:Field, type:ComplexType, builder:Expr, res:Array<Field>):Void {
var signalName = signalName(field.name); var fieldName = field.name;
var signalName = signalName(fieldName);
var meta = field.bindableMeta(); var meta = field.bindableMeta();
var inlineSignalGetter = meta.findParam(INLINE_SIGNAL_GETTER); var inlineSignalGetter = meta.findParam(INLINE_SIGNAL_GETTER);
@@ -108,7 +107,7 @@ class BindSignalProvider implements IBindingSignalProvider {
name: signalPrivateName, name: signalPrivateName,
kind: FVar(type, null), kind: FVar(type, null),
pos: field.pos, pos: field.pos,
meta: [ { name:SignalTools.BIND_SIGNAL_META, pos:field.pos, params: [macro true] } ], meta: [ { name:SignalTools.BIND_SIGNAL_META, pos:field.pos, params: [macro $v{fieldName}, macro true] } ],
access: [APrivate] access: [APrivate]
}); });
@@ -142,7 +141,7 @@ class BindSignalProvider implements IBindingSignalProvider {
kind: FProp("default", "null", type, builder), kind: FProp("default", "null", type, builder),
pos: field.pos, pos: field.pos,
access: [APrivate], access: [APrivate],
meta: [ { name:SignalTools.BIND_SIGNAL_META, pos:field.pos, params: [macro false] } ] meta: [ { name:SignalTools.BIND_SIGNAL_META, pos:field.pos, params: [macro $v{fieldName}, macro false] } ]
}); });
} }
} }
+10 -2
View File
@@ -290,11 +290,16 @@ class BaseTest extends BuddySuite {
}); });
it("bindx should bind all bindings (force mode)", function () { it("bindx should bind all bindings (force mode)", function () {
var unbind = Bind.bindAll(b, function () callNum ++, true); var fieldName = "";
var unbind = Bind.bindAll(b, function (name) { name.should.be(fieldName); callNum ++; }, true);
fieldName = "str";
b.str = "123"; b.str = "123";
fieldName = "str2";
b.str2 = "123"; b.str2 = "123";
fieldName = "bind";
Bind.notify(b.bind); Bind.notify(b.bind);
fieldName = "bind2";
Bind.notify(b.bind2); Bind.notify(b.bind2);
callNum.should.be(4); callNum.should.be(4);
@@ -310,11 +315,14 @@ class BaseTest extends BuddySuite {
}); });
it("bindx should bind all bindings (simple mode)", function () { it("bindx should bind all bindings (simple mode)", function () {
var unbind = Bind.bindAll(b, function () callNum ++, false); var fieldName = "";
var unbind = Bind.bindAll(b, function (name) { name.should.be(fieldName); callNum ++; }, false);
b.str = "123"; b.str = "123";
fieldName = "str2";
b.str2 = "123"; b.str2 = "123";
Bind.notify(b.bind); Bind.notify(b.bind);
fieldName = "bind2";
Bind.notify(b.bind2); Bind.notify(b.bind2);
callNum.should.be(2); // ignore lazy signals callNum.should.be(2); // ignore lazy signals