From 539f6d724402824ca46e7b7174b12fab98540444 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Tue, 29 Aug 2017 10:53:16 +0200 Subject: [PATCH] use the generated getters to make the reactive extensions more robust --- src/reactive.nim | 101 +++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/src/reactive.nim b/src/reactive.nim index 1b28df7..167d6e9 100644 --- a/src/reactive.nim +++ b/src/reactive.nim @@ -20,7 +20,7 @@ type ReactiveBase* = ref object of RootObj ## everything that is a "reactive" ## value derives from that sinks*: SinkSeq - dups: JDict[cstring, bool] + dups: JDict[cstring, int] id: int Reactive*[T] = ref object of ReactiveBase value*: T @@ -38,13 +38,16 @@ type var rid: int proc addSink(x: ReactiveBase; key: cstring; sink: proc(msg: Message; pos: int)) = - if x.dups == nil: x.dups = newJDict[cstring, bool]() + if x.dups == nil: x.dups = newJDict[cstring, int]() if not x.dups.contains(key): - x.dups[key] = true + x.dups[key] = x.sinks.len x.sinks.add sink if x.id == 0: inc rid x.id = rid + else: + # update existing entry: + x.sinks[x.dups[key]] = sink proc addSink(x: ReactiveBase; sink: proc(msg: Message; pos: int)) = x.sinks.add sink @@ -58,12 +61,16 @@ proc broadcast(x: ReactiveBase, msg: Message; pos = 0) = if inhibited == 0: for s in x.sinks: s(msg, pos) -var toTrack: proc (msg: Message; pos: int) = nil +var toTrack: seq[(cstring, proc (msg: Message; pos: int))] = @[] -proc now*[T](x: Reactive[T]): T = - if toTrack != nil: - x.addSink toTrack - result = x.value +template withTrack(key, t, body) = + toTrack.add((key, t)) + body + discard toTrack.pop() + +proc trackDependency*(r: ReactiveBase) = + for t in toTrack: + r.addSink t[0], t[1] template wrapObserver(f: untyped) = var state: State @@ -114,11 +121,6 @@ template glitchFree(f: untyped) = x.broadcast(msg, pos) helper -proc `:=`[T](x: Reactive[T], f: proc(): T) = - toTrack = wrapObserver(f()) - x.value = f() - toTrack = nil - proc `<-`*[T](x: Reactive[T], val: T) = #if x.value != val: x.value = val @@ -204,25 +206,31 @@ proc deleteElem*[T](x: RSeq[T]; y: T) = x.broadcast(Mark) x.broadcast(Deleted, position) -proc map*[T, U](x: RSeq[T], f: proc(x: T): U): RSeq[U] = - let xl = x.L.value - let res = newRSeq[U](xl) - for i in 0..