From cfbbac64e432e37e1a17ab1b01d5a2da08ca38d7 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 29 Aug 2016 13:55:15 +0200 Subject: Semi-ok --- go/react/react.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 14 deletions(-) (limited to 'go') diff --git a/go/react/react.go b/go/react/react.go index 1f93906..069d7be 100644 --- a/go/react/react.go +++ b/go/react/react.go @@ -1,5 +1,7 @@ package react +import "log" + const testVersion = 4 type react struct { @@ -9,17 +11,18 @@ type inputCell struct { cell } -type computeCell struct { +type compuCell struct { cell cb map[CallbackHandle]func(int) } -func newComputeCell() *computeCell { - return &computeCell{cb: make(map[CallbackHandle]func(int))} +type com struct { + eval, ok chan bool } type cell struct { - value int + value int + observer []com } func New() Reactor { @@ -27,17 +30,63 @@ func New() Reactor { } func (r *react) CreateCompute1(c Cell, f func(int) int) ComputeCell { - return &computeCell{ - cell: cell{value: f(c.Value())}, - cb: make(map[CallbackHandle]func(int)), + ch := make(chan bool) + ok := make(chan bool) + cc := &compuCell{ + cb: make(map[CallbackHandle]func(int)), } + cc.value = f(c.Value()) + Register(c, ch, ok) + go func() { + for range ch { + log.Println("got", c.Value()) + old := cc.value + cc.value = f(c.Value()) + if old != cc.value { + for _, ch := range cc.observer { + log.Println("notify #1") + ch.eval <- true + <-ch.ok + } + for _, cb := range cc.cb { + log.Println("cb #1") + cb(cc.value) + } + } + ok <- true + } + }() + return cc } func (r *react) CreateCompute2(c1, c2 Cell, f func(int, int) int) ComputeCell { - return &computeCell{ - cell: cell{value: f(c1.Value(), c2.Value())}, - cb: make(map[CallbackHandle]func(int)), + ch := make(chan bool) + ok := make(chan bool) + cc := &compuCell{ + cb: make(map[CallbackHandle]func(int)), } + cc.value = f(c1.Value(), c2.Value()) + Register(c1, ch, ok) + Register(c2, ch, ok) + go func() { + for range ch { + old := cc.value + cc.value = f(c1.Value(), c2.Value()) + if old != cc.value { + for _, ch := range cc.observer { + log.Println("notify #2") + ch.eval <- true + <-ch.ok + } + for _, cb := range cc.cb { + log.Println("cb #2") + cb(cc.value) + } + } + ok <- true + } + }() + return cc } func (r *react) CreateInput(i int) InputCell { @@ -46,19 +95,38 @@ func (r *react) CreateInput(i int) InputCell { } } -func (c *computeCell) AddCallback(f func(int)) CallbackHandle { +func (c *compuCell) AddCallback(f func(int)) CallbackHandle { c.cb[&f] = f return &f } -func (c *computeCell) RemoveCallback(h CallbackHandle) { +func (c *compuCell) RemoveCallback(h CallbackHandle) { delete(c.cb, h) } func (c *inputCell) SetValue(i int) { + old := c.value c.value = i + if old != c.value { + for _, ch := range c.observer { + log.Println("notify", i) + ch.eval <- true + <-ch.ok + } + } } -func (c cell) Value() int { - return c.value +func (c *cell) Value() int { + v := c.value + log.Println("report", v) + return v +} + +func Register(c Cell, ch, ok chan bool) { + switch v := c.(type) { + case *compuCell: + v.observer = append(v.observer, com{ch, ok}) + case *inputCell: + v.observer = append(v.observer, com{ch, ok}) + } } -- cgit v1.2.3