Commit | Line | Data |
---|---|---|
8ee66edd FC |
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 |