diff --git a/src/tink/lang/macros/ClassBuilder.hx b/src/tink/lang/macros/ClassBuilder.hx index ed65770..2b99043 100644 --- a/src/tink/lang/macros/ClassBuilder.hx +++ b/src/tink/lang/macros/ClassBuilder.hx @@ -14,7 +14,7 @@ class ClassBuilder { } static function noBindings(ctx:ClassBuildContext) { #if debug - var bindable = [':bindable', ':cache']; + var bindable = [':bindable', ':cache', ':signal']; for (m in ctx.members) for (tag in bindable) switch (m.extractMeta(tag)) { @@ -30,10 +30,11 @@ class ClassBuilder { Forward.process, PropBuilder.process, #if tink_reactive //probably shouldn't be here but it's very convenient for now - tink.reactive.bindings.macros.BindableProperties.make + tink.reactive.bindings.macros.BindableProperties.make, + tink.reactive.signals.macros.SignalBuilder.make #else noBindings - #end, + #end ]; #end } \ No newline at end of file diff --git a/src/tink/reactive/signals/Signal.hx b/src/tink/reactive/signals/Signal.hx new file mode 100644 index 0000000..3adf1ef --- /dev/null +++ b/src/tink/reactive/signals/Signal.hx @@ -0,0 +1,28 @@ +package tink.reactive.signals; +import tink.collections.maps.FunctionMap; + +/** + * ... + * @author back2dos + */ + +interface Signal { + function watch(handler:T->Dynamic):Void; + function unwatch(handler:T->Dynamic):Void; +} + +class SimpleSignal implements Signal { + var handlers:FunctionMapDynamic, T->Dynamic>; + public function new() { + this.handlers = new FunctionMap(); + } + public function watch(handler) { + handlers.set(handler, handler); + } + public function unwatch(handler) { + handlers.remove(handler); + } + public function fire(data:T) { + for (h in handlers.keys()) h(data); + } +} \ No newline at end of file diff --git a/src/tink/reactive/signals/macros/SignalBuilder.hx b/src/tink/reactive/signals/macros/SignalBuilder.hx new file mode 100644 index 0000000..b055ea7 --- /dev/null +++ b/src/tink/reactive/signals/macros/SignalBuilder.hx @@ -0,0 +1,37 @@ +package tink.reactive.signals.macros; + +/** + * ... + * @author back2dos + */ +import tink.macro.build.Member; +import tink.macro.build.MemberTransformer; +import haxe.macro.Expr; + +using tink.macro.tools.MacroTools; + +class SignalBuilder { + static inline var SIGNAL = ':signal'; + static public function make(ctx:ClassBuildContext) { + for (member in ctx.members) + switch (member.extractMeta(SIGNAL)) { + case Success(tag): + switch (member.kind) { + case FVar(t, e): + if (e != null) e.reject(); + if (t == null) member.pos.error('type required'); + + var own = '_' + member.name; + ctx.add(Member.plain(own, 'tink.reactive.signals.Signal.SimpleSignal'.asComplexType([TPType(t)]), tag.pos)); + + member.kind = FProp('default', 'null', 'tink.reactive.signals.Signal'.asComplexType([TPType(t)])); + ctx.getCtor().init(member.name, tag.pos, own.resolve(tag.pos), true); + ctx.getCtor().init(own, tag.pos, 'tink.reactive.signals.Signal.SimpleSignal'.instantiate(tag.pos), true); + member.publish(); + default: + member.pos.error('can only declare signals on variables'); + } + default: + } + } +} \ No newline at end of file