tracks/python/exercises/react/example.py in trackler-2.2.1.135 vs tracks/python/exercises/react/example.py in trackler-2.2.1.136
- old
+ new
@@ -1,65 +1,56 @@
class Cell(object):
- def __init__(self, reactor, value=0, dependencies=set(),
- updater=None):
- self.reactor = reactor
- self.index = len(reactor.cells)
- reactor.cells.append(self)
- self.value = value
- self.dirty = False
- self.dependencies = dependencies
- self.dependents = set()
- self.updater = updater
- self.watchers = set()
- if updater is not None:
- self.update()
- self.notify()
+ def __init__(self):
+ self._watchers = []
+ self._value = None
+ self.counter = 0
- def add_watcher(self, watcher):
- self.watchers.add(watcher)
+ def add_watcher(self, cell):
+ self._watchers.append(cell)
- def remove_watcher(self, watcher):
- self.watchers.remove(watcher)
+ @property
+ def value(self):
+ return self._value
- def set_value(self, value, top=True):
- self.value = value
- for d in self.dependents:
- d.update()
- if top:
- self.reactor.notify()
+ @value.setter
+ def value(self, new_value):
+ self._value = new_value
+ self.counter += 1
+ for cell in self._watchers:
+ cell.compute()
- def update(self):
- if self.updater is not None:
- values = [d.value for d in self.dependencies]
- value = self.updater(values)
- if self.value != value:
- self.set_value(value, False)
- self.dirty = True
- def notify(self):
- if self.dirty:
- for watcher in self.watchers:
- watcher(self, self.value)
- self.dirty = False
+class InputCell(Cell):
+ def __init__(self, initial_value):
+ super(InputCell, self).__init__()
+ self._value = initial_value
- def __hash__(self):
- return self.index
+class ComputeCell(Cell):
+ def __init__(self, inputs, compute_function):
+ super(ComputeCell, self).__init__()
+ self.inputs = inputs
+ self.func = compute_function
+ self.callbacks = set()
+ self.compute()
+ self._register_inputs()
-class Reactor(object):
- def __init__(self):
- self.cells = []
+ def _register_inputs(self):
+ for inp in self.inputs:
+ inp.add_watcher(self)
- def create_input_cell(self, value):
- return Cell(self, value=value)
+ def compute(self):
+ # Only compute this cell when all inputs have same counters
+ if len(set([inp.counter for inp in self.inputs])) > 1:
+ return
+ new_val = self.func([inp.value for inp in self.inputs])
+ if new_val != self._value:
+ self.value = new_val
+ for cb in self.callbacks:
+ cb(new_val)
- def create_compute_cell(self, dependencies, updater):
- cell = Cell(self,
- dependencies=dependencies,
- updater=updater)
- for d in dependencies:
- d.dependents.add(cell)
- return cell
+ def add_callback(self, callback):
+ self.callbacks.add(callback)
- def notify(self):
- for cell in self.cells:
- cell.notify()
+ def remove_callback(self, callback):
+ if callback in self.callbacks:
+ self.callbacks.remove(callback)