bindAll support

This commit is contained in:
Dmitri Granetchi
2015-06-27 00:41:58 +03:00
parent 9c4e98fd96
commit aac6e6fada
6 changed files with 95 additions and 0 deletions
+4
View File
@@ -25,4 +25,8 @@ class Bind {
@:noUsing macro static public function unbindAll(object:ExprOf<IBindable>):Expr {
return BindMacros.unbindAll(object);
}
@:noUsing macro static public function bindAll(object:ExprOf<IBindable>, listener:Expr, force:Bool = true):Expr {
return BindMacros.bindAll(object, listener, force);
}
}
+38
View File
@@ -92,4 +92,42 @@ class SignalTools {
}
}
}
static public function bindAll(bindable:bindx.IBindable, callback:Void -> Void, force = true):Void -> Void {
var listenField = function (_, _) callback();
var listenMethod = callback;
var signals = getSignals(bindable, force);
for (signal in signals) {
if (Std.is(signal, FieldSignal)) signal.add(listenField);
else signal.add(listenMethod);
}
return function () {
for (signal in signals) {
if (Std.is(signal, FieldSignal)) signal.remove(listenField);
else signal.remove(listenMethod);
}
}
}
static function getSignals(bindable:bindx.IBindable, force = true):Array<bindx.BindSignal.Signal<Dynamic>> {
var signals = [];
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 signal:bindx.BindSignal.Signal<Dynamic> = cast std.Reflect.field(bindable, m);
trace(signal);
if (signal == null && force) {
var args:Array<Dynamic> = std.Reflect.field(data, BIND_SIGNAL_META);
var lazy:Bool = args[0];
if (lazy) signal = cast std.Reflect.getProperty(bindable, m.substr(1));
trace(signal);
}
if (signal != null) signals.push(signal);
}
}
return signals;
}
}
+8
View File
@@ -38,6 +38,14 @@ class BindMacros {
return BindableMacros.bindingSignalProvider.getUnbindAllExpr(object, type);
}
static inline function bindAll(object:ExprOf<IBindable>, listener:Expr, force:Bool = true):Expr {
var type = object.deepTypeof();
if (!isBindable(type.getClass())) {
Context.error('\'${object.toString()}\' must be bindx.IBindable', object.pos);
}
return BindableMacros.bindingSignalProvider.getBindAllExpr(object, type, listener, force);
}
static inline function warnCheckField(field:Expr):{e:Expr, field:ClassField} {
var res = null;
try {
+4
View File
@@ -93,6 +93,10 @@ class BindSignalProvider implements IBindingSignalProvider {
return macro bindx.BindSignal.SignalTools.unbindAll($expr);
}
public function getBindAllExpr(expr:ExprOf<IBindable>, type:Type, listener:Expr, force:Bool = true):Expr {
return macro bindx.BindSignal.SignalTools.bindAll($expr, $listener, $v{force});
}
function generateSignal(field:Field, type:ComplexType, builder:Expr, res:Array<Field>):Void {
var signalName = signalName(field.name);
var meta = field.bindableMeta();
@@ -13,4 +13,5 @@ interface IBindingSignalProvider {
function getClassFieldUnbindExpr(expr:Expr, field:ClassField, listener:Expr):Expr;
function getClassFieldChangedExpr(expr:Expr, field:ClassField, oldValue:Expr, newValue:Expr):Expr;
function getUnbindAllExpr(expr:ExprOf<IBindable>, type:Type):Expr;
function getBindAllExpr(expr:ExprOf<IBindable>, type:Type, listener:Expr, force:Bool = true):Expr;
}
+40
View File
@@ -288,6 +288,46 @@ class BaseTest extends BuddySuite {
true.should.be(true);
});
it("bindx should bind all bindings (force mode)", function () {
var unbind = Bind.bindAll(b, function () callNum ++, true);
b.str = "123";
b.str2 = "123";
Bind.notify(b.bind);
Bind.notify(b.bind2);
callNum.should.be(4);
unbind();
b.str = "234";
b.str2 = "234";
Bind.notify(b.bind);
Bind.notify(b.bind2);
callNum.should.be(4);
});
it("bindx should bind all bindings (simple mode)", function () {
var unbind = Bind.bindAll(b, function () callNum ++, false);
b.str = "123";
b.str2 = "123";
Bind.notify(b.bind);
Bind.notify(b.bind2);
callNum.should.be(2); // ignore lazy signals
unbind();
b.str = "234";
b.str2 = "234";
Bind.notify(b.bind);
Bind.notify(b.bind2);
callNum.should.be(2);
});
it("bindx should resolve typedefs", function () {
var a:TypeBindable1 = new TypeBindable1();