# http://pyrocko.org - GPLv3 # # The Pyrocko Developers, 21st Century # ---|P------/S----------~Lg----------
class Stage(object): def __init__(self, f): self._f = f self._parent = None self._cache = {}
def __call__(self, *x, **kwargs): if kwargs.get('nocache', False): return self.call_nocache(*x)
if x not in self._cache: if self._parent is not None: self._cache[x] = self._f(self._parent(*x[:-1]), *x[-1]) else: self._cache[x] = self._f(*x[-1])
return self._cache[x]
def call_nocache(self, *x): if self._parent is not None: return self._f(self._parent.call_nocache(*x[:-1]), *x[-1]) else: return self._f(*x[-1])
def clear(self): self._cache.clear()
class Chain(object): def __init__(self, *stages): parent = None self.stages = [] for stage in stages: if not isinstance(stage, Stage): stage = Stage(stage)
stage._parent = parent parent = stage self.stages.append(stage)
def clear(self): for stage in self.stages: stage.clear()
def __call__(self, *x, **kwargs): return self.stages[len(x)-1](*x, **kwargs) |