ya2 · news · projects · code · about

removed next/prev/rewind
[pmachines.git] / lib / observer.py
1 class ObsInfo:
2
3 def __init__(self, mth, sort, args):
4 self.mth = mth
5 self.sort = sort
6 self.args = args
7
8 def __repr__(self): return str(self.mth)
9
10
11 class Subject:
12
13 def __init__(self):
14 self.observers = {}
15
16 def attach(self, obs_meth, sort=10, rename='', args=None):
17 args = args or []
18 onm = rename or obs_meth.__name__
19 if onm not in self.observers: self.observers[onm] = []
20 self.observers[onm] += [ObsInfo(obs_meth, sort, args)]
21 sorted_obs = sorted(self.observers[onm], key=lambda obs: obs.sort)
22 self.observers[onm] = sorted_obs
23
24 def detach(self, obs_meth, lambda_call=None):
25 if isinstance(obs_meth, str):
26 onm = obs_meth
27 observers = [obs for obs in self.observers[onm]
28 if obs.mth == lambda_call]
29 else:
30 onm = obs_meth.__name__
31 observers = [obs for obs in self.observers[onm]
32 if obs.mth == obs_meth]
33 if not observers: raise Exception
34 list(map(self.observers[onm].remove, observers))
35
36 def notify(self, meth, *args, **kwargs):
37 if meth not in self.observers: return # no obs for this notification
38 for obs in self.observers[meth][:]:
39 if obs in self.observers[meth]: # if an obs removes another one
40 try:
41 act_args = obs.args + list(args)
42 obs.mth(*act_args, **kwargs)
43 except SystemError:
44 print('Quit')
45 import sys; sys.exit()
46
47 def observing(self, obs_meth):
48 if callable(obs_meth): obs_meth = obs_meth.__name__
49 return obs_meth in self.observers and self.observers[obs_meth]
50
51 def destroy(self): self.observers = None
52
53
54 class Observer: pass