package react import "strconv" const testVersion = 4 // MyReactor implements Reactor type MyReactor struct { lastId int cells []Cell } // New creates a new Reactor func New() *MyReactor { r := &MyReactor{} return r } // CreateInput builds an input cell and adds it to the reactor func (r *MyReactor) CreateInput(i int) InputCell { r.lastId++ ic := MyCell{val: i, id: r.lastId} ic.previousVal = ic.Value() return &ic } // CreateCompute1 Takes a cell and a function and returns a compute cell // which has a value based on running the function on the cells value. func (r *MyReactor) CreateCompute1(c Cell, f func(int) int) ComputeCell { r.lastId++ cc := &MyCell{id: r.lastId, isComputed: true} cc.compVal = func() int { return f(c.Value()) } cc.previousVal = cc.Value() c.(*MyCell).addDependent(cc) return cc } // CreateCompute2 Takes two cells and a function and returns a compute cell // which has a value based on running the function on the cells values. func (r *MyReactor) CreateCompute2(c1, c2 Cell, f func(int, int) int) ComputeCell { r.lastId++ cc := &MyCell{id: r.lastId, isComputed: true} cc.compVal = func() int { return f(c1.Value(), c2.Value()) } cc.previousVal = cc.Value() c1.(*MyCell).addDependent(cc) c2.(*MyCell).addDependent(cc) return cc } // MyCell implements the all Cell interfaces type MyCell struct { id int isComputed bool val int compVal func() int lastCallbackId int callbacks map[int]func(int) dependents []Cell previousVal int } // Value returns the value of the cell func (c MyCell) Value() int { if c.isComputed { return c.compVal() } return c.val } // SetValue sets the value on the cell func (c *MyCell) SetValue(i int) { if i == c.val || c.isComputed { // No change or this is a computed cell, just return return } c.previousVal = c.val c.val = i c.updated() } func i(v int) string { return strconv.Itoa(v) } func (c *MyCell) updated() { if c.Value() == c.previousVal { // Value didn't change, done. return } c.previousVal = c.Value() // Triggers callbacks for _, v := range c.callbacks { v(c.Value()) } // Hit 'updated' on all dependents for _, v := range c.dependents { v.(*MyCell).updated() } } func (c *MyCell) addDependent(nc Cell) { c.dependents = append(c.dependents, nc) } func (c *MyCell) AddCallback(cb func(int)) CallbackHandle { if c.lastCallbackId == 0 { c.callbacks = make(map[int]func(int)) } c.lastCallbackId++ c.callbacks[c.lastCallbackId] = cb return c.lastCallbackId } func (c *MyCell) RemoveCallback(cbh CallbackHandle) { delete(c.callbacks, cbh.(int)) }