diff --git a/src/bindx/BindSignal.hx b/src/bindx/BindSignal.hx index 97c20e7..1994cf6 100644 --- a/src/bindx/BindSignal.hx +++ b/src/bindx/BindSignal.hx @@ -76,6 +76,8 @@ class Signal { class SignalTools { static public inline var BIND_SIGNAL_META = "BindSignal"; + + static public inline var SIGNAL_POSTFIX = "Changed"; static public function unbindAll(bindable:bindx.IBindable):Void { var meta = haxe.rtti.Meta.getFields(std.Type.getClass(bindable)); @@ -86,44 +88,55 @@ class SignalTools { if (signal != null) { signal.removeAll(); var args:Array = 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); } } } } - static public function bindAll(bindable:bindx.IBindable, callback:Void -> Void, force = true):Void -> Void { - var listenField = function (_, _) callback(); - var listenMethod = callback; + static public function bindAll(bindable:bindx.IBindable, callback:String -> Void, force = true):Void -> Void { + var listeners = new Map, Dynamic>(); var signals = getSignals(bindable, force); - for (signal in signals) { - if (Std.is(signal, FieldSignal)) signal.add(listenField); - else signal.add(listenMethod); + for (name in signals.keys()) { + var signal = signals.get(name); + 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 () { - for (signal in signals) { - if (Std.is(signal, FieldSignal)) signal.remove(listenField); - else signal.remove(listenMethod); + for (signal in listeners.keys()) { + var listener = listeners.get(signal); + if (Std.is(signal, FieldSignal)) signal.remove(listener); + else signal.remove(listener); } } } - static function getSignals(bindable:bindx.IBindable, force = true):Array> { - var signals = []; + static function getSignals(bindable:bindx.IBindable, force = true):Map> { + var signals = new Map>(); var meta = haxe.rtti.Meta.getFields(std.Type.getClass(bindable)); if (meta != null) for (m in std.Reflect.fields(meta)) { var data = std.Reflect.field(meta, m); if (std.Reflect.hasField(data, BIND_SIGNAL_META)) { + var args:Array = std.Reflect.field(data, BIND_SIGNAL_META); var signal:bindx.BindSignal.Signal = cast std.Reflect.field(bindable, m); if (signal == null && force) { - var args:Array = std.Reflect.field(data, BIND_SIGNAL_META); - var lazy:Bool = args[0]; + var lazy:Bool = args[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; diff --git a/src/bindx/macro/BindSignalProvider.hx b/src/bindx/macro/BindSignalProvider.hx index 3537c3c..0ec1928 100644 --- a/src/bindx/macro/BindSignalProvider.hx +++ b/src/bindx/macro/BindSignalProvider.hx @@ -11,8 +11,6 @@ using haxe.macro.Tools; class BindSignalProvider implements IBindingSignalProvider { - static inline var SIGNAL_POSTFIX = "Changed"; - /** * default value: true */ @@ -24,7 +22,7 @@ class BindSignalProvider implements IBindingSignalProvider { 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 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):Void { - var signalName = signalName(field.name); + var fieldName = field.name; + var signalName = signalName(fieldName); var meta = field.bindableMeta(); var inlineSignalGetter = meta.findParam(INLINE_SIGNAL_GETTER); @@ -108,7 +107,7 @@ class BindSignalProvider implements IBindingSignalProvider { name: signalPrivateName, kind: FVar(type, null), 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] }); @@ -142,7 +141,7 @@ class BindSignalProvider implements IBindingSignalProvider { kind: FProp("default", "null", type, builder), pos: field.pos, 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] } ] }); } } diff --git a/test/BaseTest.hx b/test/BaseTest.hx index 42dea32..53f4c04 100644 --- a/test/BaseTest.hx +++ b/test/BaseTest.hx @@ -290,11 +290,16 @@ class BaseTest extends BuddySuite { }); 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"; + fieldName = "str2"; b.str2 = "123"; + fieldName = "bind"; Bind.notify(b.bind); + fieldName = "bind2"; Bind.notify(b.bind2); callNum.should.be(4); @@ -310,11 +315,14 @@ class BaseTest extends BuddySuite { }); 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"; + fieldName = "str2"; b.str2 = "123"; Bind.notify(b.bind); + fieldName = "bind2"; Bind.notify(b.bind2); callNum.should.be(2); // ignore lazy signals