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)