diff --git a/src/bindx/BindSignal.hx b/src/bindx/BindSignal.hx index aa9ddec..2992838 100644 --- a/src/bindx/BindSignal.hx +++ b/src/bindx/BindSignal.hx @@ -25,6 +25,7 @@ class BindSignalProvider implements IBindingSignalProvider { * default value: false */ static inline var INLINE_SIGNAL_GETTER = "inlineSignalGetter"; + static inline var BIND_SIGNAL_META = "BindSignal"; public function new() {} @@ -74,7 +75,7 @@ class BindSignalProvider implements IBindingSignalProvider { public function getClassFieldUnbindExpr(expr:Expr, field:ClassField, listener:Expr):Expr { var signalName = signalName(field.name); - return if (!listener.expr.match(EConst(CIdent("null")))) + return if (!isNull(listener)) macro $expr.$signalName.remove($listener); else macro $expr.$signalName.removeAll(); @@ -82,8 +83,14 @@ class BindSignalProvider implements IBindingSignalProvider { public function getClassFieldChangedExpr(expr:Expr, field:ClassField, oldValue:Expr, newValue:Expr):Expr { var args = switch (field.kind) { - case FMethod(_): []; - case FVar(_, _): [oldValue, newValue]; + case FMethod(_): + if (!isNull(oldValue)) + Context.error("method notify don't require oldValue", oldValue.pos); + if (!isNull(newValue)) + Context.error("method notify don't require newValue", newValue.pos); + []; + case FVar(_, _): + [oldValue, newValue]; } return dispatchSignal(expr, field.name, args, hasLazy(field.bindableMeta())); } @@ -169,6 +176,10 @@ class BindSignalProvider implements IBindingSignalProvider { @:extern inline function hasLazy(meta:MetadataEntry) { return meta.findParam(LAZY_SIGNAL).isNullOrTrue(); } + + @:extern inline function isNull(expr:Expr):Bool { + return expr == null || expr.expr.match(EConst(CIdent("null"))); + } } #end diff --git a/test/BaseTest.hx b/test/BaseTest.hx index 34a59c3..155d314 100644 --- a/test/BaseTest.hx +++ b/test/BaseTest.hx @@ -21,8 +21,9 @@ class BaseTest extends BuddySuite { callNum = 0; }); - it ("bindx should bind properties", { + it ("bindx should bind/unbind properties", { var strFrom = b.str = "a"; + var callNum2 = 0; bind(b.str, function (from, to) { from.should.be(strFrom); @@ -30,35 +31,68 @@ class BaseTest extends BuddySuite { callNum ++; }); - Bind.bind(b.str, function (from, to) { + var listener2 = function (from:String, to:String) { from.should.be(strFrom); to.should.be(b.str); callNum ++; - }); + callNum2 ++; + }; + Bind.bind(b.str, listener2); b.str = "b"; callNum.should.be(2); + callNum2.should.be(1); + + Bind.unbind(b.str, listener2); + strFrom = b.str; + b.str = "c"; + + callNum.should.be(3); + callNum2.should.be(1); }); - it("bindx should bind 'null' values", { - b.str = null; + it("bindx should bind/unbind 'null' values", { + var strFrom = b.str = null; + var callNum2 = 0; var listener = function (from:String, to:String) { - from.should.be(null); + from.should.be(strFrom); to.should.be(b.str); callNum ++; } + var listener2 = function (from:String, to:String) { + from.should.be(strFrom); + to.should.be(b.str); + callNum ++; + callNum2 ++; + }; + bind(b.str, listener); //b.str == null now + bind(b.str, listener2); + + b.str = "a"; + callNum.should.be(2); + callNum2.should.be(1); - bind(b.str, listener); - Bind.bind(b.str, listener); - b.str = ""; + Bind.unbind(b.str, listener2); + strFrom = b.str; + b.str = null; // b.str set null + callNum.should.be(3); + callNum2.should.be(1); + }); + + it("bindx should bind and notify methods", { + var listener = function () callNum++; + bind(b.bind, listener); + Bind.notify(b.bind); + callNum.should.be(1); - - bindx.Bind.unbind(b.str, listener); - b.str = "1"; + + Bind.unbind(b.bind, listener); + Bind.notify(b.bind); + callNum.should.be(1); }); - it("bindx should notify manual", { + it("bindx should notify properties manual", { b.str = "3"; var f = "1"; var t = "2"; @@ -73,7 +107,7 @@ class BaseTest extends BuddySuite { callNum.should.be(1); }); - it("bindx should unbind all listeners", { + it("bindx should unbind all properties listeners", { bind(b.str, function (from, to) callNum++); bind(b.str, function (from, to) callNum++); @@ -83,6 +117,8 @@ class BaseTest extends BuddySuite { callNum.should.be(0); }); + it("bindx should unbind all method listeners"); + it("bindx should unbind all bindings (signal exists)", { bind(b.str, function (_, _) callNum++); // create binding signal bind(b.bind, function () callNum++); @@ -98,7 +134,7 @@ class BaseTest extends BuddySuite { Bind.unbindAll(b); b.str = b.str + "1"; - b.bind(); + Bind.notify(b.bind); callNum.should.be(0); }); }); @@ -108,9 +144,12 @@ class BaseTest extends BuddySuite { @:bindable class Bindable1 implements bindx.IBindable { - @:bindable(lazySignal=false) + @:bindable(lazySignal=true) public var str:String; + @:bindable(lazySignal=false) + public var str2:String; + @:bindable public var i(default, set):Int;