1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
7class Stage(object):
8 def __init__(self, f):
9 self._f = f
10 self._parent = None
11 self._cache = {}
13 def __call__(self, *x, **kwargs):
14 if kwargs.get('nocache', False):
15 return self.call_nocache(*x)
17 if x not in self._cache:
18 if self._parent is not None:
19 self._cache[x] = self._f(self._parent(*x[:-1]), *x[-1])
20 else:
21 self._cache[x] = self._f(*x[-1])
23 return self._cache[x]
25 def call_nocache(self, *x):
26 if self._parent is not None:
27 return self._f(self._parent.call_nocache(*x[:-1]), *x[-1])
28 else:
29 return self._f(*x[-1])
31 def clear(self):
32 self._cache.clear()
35class Chain(object):
36 def __init__(self, *stages):
37 parent = None
38 self.stages = []
39 for stage in stages:
40 if not isinstance(stage, Stage):
41 stage = Stage(stage)
43 stage._parent = parent
44 parent = stage
45 self.stages.append(stage)
47 def clear(self):
48 for stage in self.stages:
49 stage.clear()
51 def __call__(self, *x, **kwargs):
52 return self.stages[len(x)-1](*x, **kwargs)