diff --git a/src/bindx/Bind.hx b/src/bindx/Bind.hx index 2a6972f..e83085d 100644 --- a/src/bindx/Bind.hx +++ b/src/bindx/Bind.hx @@ -29,4 +29,8 @@ class Bind { @:noUsing macro static public function bindAll(object:ExprOf, listener:Expr, force:Bool = true):Expr { return BindMacros.bindAll(object, listener, force); } + + @:noUsing macro static public function bindAllWithOrigin(object:ExprOf, listener:Expr, force:Bool = true):Expr { + return BindMacros.bindAllWithOrigin(object, listener, force); + } } \ No newline at end of file diff --git a/src/bindx/SignalTools.hx b/src/bindx/SignalTools.hx index 60794b2..4955240 100644 --- a/src/bindx/SignalTools.hx +++ b/src/bindx/SignalTools.hx @@ -38,7 +38,40 @@ class SignalTools { * @param force = true - force instantiate all lazy signals * @return Void -> Void */ - static public function bindAll(bindable:bindx.IBindable, callback: bindx.IBindable -> String -> Dynamic -> Dynamic -> Void, force = true):Void -> Void { + static public function bindAll(bindable:bindx.IBindable, callback: String -> Dynamic -> Dynamic -> Void, force = true):Void -> Void { + var listeners = new Map, Function>(); + + var signals = getSignals(bindable, force); + for (name in signals.keys()) { + var signal = signals.get(name); + if (signal == null) continue; + if (std.Std.is(signal, bindx.BindSignal.FieldSignal)) { + var listener = function (from:Dynamic, to:Dynamic) callback(name, from, to); + listeners.set(signal, listener); + signal.add(listener); + } else { + var listener = function () callback(name, null, null); + listeners.set(signal, listener); + signal.add(listener); + } + } + + return function () { + for (signal in listeners.keys()) { + var listener = listeners.get(signal); + signal.remove(listener); + } + } + } + + /** + * Bind all bindable fields/methods (use reflection api), include IBindable source object in callback + * @param bindable - target object + * @param callback - + * @param force = true - force instantiate all lazy signals + * @return Void -> Void + */ + static public function bindAllWithOrigin (bindable:bindx.IBindable, callback: bindx.IBindable -> String -> Dynamic -> Dynamic -> Void, force = true):Void -> Void { var listeners = new Map, Function>(); var signals = getSignals(bindable, force); diff --git a/src/bindx/macro/BindMacros.hx b/src/bindx/macro/BindMacros.hx index 86309b5..33651ab 100644 --- a/src/bindx/macro/BindMacros.hx +++ b/src/bindx/macro/BindMacros.hx @@ -46,6 +46,14 @@ class BindMacros { return BindableMacros.bindingSignalProvider.getBindAllExpr(object, type, listener, force); } + static inline function bindAllWithOrigin(object:ExprOf, 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.getBindAllWithOriginExpr(object, type, listener, force); + } + static inline function warnCheckField(field:Expr):{e:Expr, field:ClassField} { var res = null; try { diff --git a/src/bindx/macro/BindSignalProvider.hx b/src/bindx/macro/BindSignalProvider.hx index 4fcae7d..1ba9065 100644 --- a/src/bindx/macro/BindSignalProvider.hx +++ b/src/bindx/macro/BindSignalProvider.hx @@ -99,6 +99,10 @@ class BindSignalProvider implements IBindingSignalProvider { return macro bindx.SignalTools.bindAll($expr, $listener, $v{force}); } + public function getBindAllWithOriginExpr(expr:ExprOf, type:Type, listener:Expr, force:Bool = true):Expr { + return macro bindx.SignalTools.bindAllWithOrigin($expr, $listener, $v{force}); + } + function generateSignal(field:Field, type:ComplexType, builder:Expr, res:Array):Void { var fieldName = field.name; var signalName = signalName(fieldName); diff --git a/src/bindx/macro/IBindingSignalProvider.hx b/src/bindx/macro/IBindingSignalProvider.hx index 1c4d5d7..f675052 100644 --- a/src/bindx/macro/IBindingSignalProvider.hx +++ b/src/bindx/macro/IBindingSignalProvider.hx @@ -14,4 +14,5 @@ interface IBindingSignalProvider { function getClassFieldChangedExpr(expr:Expr, field:ClassField, oldValue:Expr, newValue:Expr):Expr; function getUnbindAllExpr(expr:ExprOf, type:Type):Expr; function getBindAllExpr(expr:ExprOf, type:Type, listener:Expr, force:Bool = true):Expr; + function getBindAllWithOriginExpr(expr:ExprOf, type:Type, listener:Expr, force:Bool = true):Expr; } \ No newline at end of file