Skip to content

Instantly share code, notes, and snippets.

@Arachnid
Created July 24, 2015 13:09
Show Gist options
  • Save Arachnid/1bd41e6332598fbe909d to your computer and use it in GitHub Desktop.
Save Arachnid/1bd41e6332598fbe909d to your computer and use it in GitHub Desktop.
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
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