Created
July 24, 2015 13:09
-
-
Save Arachnid/1bd41e6332598fbe909d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Signal(object): | |
def __init__(self, initial=None): | |
self._value = initial | |
self.dependencies = [] | |
@property | |
def value(self): | |
return self._value | |
@value.setter | |
def value(self, value): | |
self._value = value | |
for target in self.dependencies: | |
target.notify() | |
def _find_dependencies(fun): | |
deps = [] | |
for cell in fun.func_closure: | |
if isinstance(cell.cell_contents, Signal): | |
deps.append(cell.cell_contents) | |
for value in fun.func_globals.itervalues(): | |
if isinstance(value, Signal): | |
deps.append(value) | |
return deps | |
class ComputedSignal(Signal): | |
_nil = object() | |
def __init__(self, compute, sensitivity_list=None, initial=_nil): | |
if initial == ComputedSignal._nil: | |
super(ComputedSignal, self).__init__(compute()) | |
else: | |
super(ComputedSignal, self).__init__(initial) | |
self._compute = compute | |
if not sensitivity_list: | |
sensitivity_list = _find_dependencies(compute) | |
for target in sensitivity_list: | |
target.dependencies.append(self) | |
def notify(self): | |
self.value = self._compute() | |
def always(*args): | |
def decorator(fun): | |
return ComputedSignal(fun, args) | |
return decorator |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from signals import * | |
def manipulate_signals(a, b): | |
@always() | |
def sum(): | |
return a.value + b.value | |
@always() | |
def product(): | |
return sum.value * a.value | |
return product | |
def test_signals(): | |
a = Signal(0) | |
b = Signal(0) | |
result = manipulate_signals(a, b) | |
a.value = 10 | |
b.value = 20 | |
assert result.value == 300 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment