64 self.register_hook(callback, event, subevent) |
64 self.register_hook(callback, event, subevent) |
65 |
65 |
66 def register_hook(self, function, event, etype=''): |
66 def register_hook(self, function, event, etype=''): |
67 """register a function to call when <event> occurs |
67 """register a function to call when <event> occurs |
68 |
68 |
69 <etype> is an entity/relation type or an empty string. |
69 <etype> is an entity/relation type or an empty string. |
70 If etype is the empty string, the function will be called at each |
70 |
71 event, else the function will be called only when event occurs on an |
71 If etype is the empty string, the function will be called at each event, |
72 entity/relation of the given type. |
72 else the function will be called only when event occurs on an entity or |
|
73 relation of the given type. |
73 """ |
74 """ |
74 assert event in ALL_HOOKS, '%r NOT IN %r' % (event, ALL_HOOKS) |
75 assert event in ALL_HOOKS, '%r NOT IN %r' % (event, ALL_HOOKS) |
75 assert (not event in SYSTEM_HOOKS or not etype), (event, etype) |
76 assert (not event in SYSTEM_HOOKS or not etype), (event, etype) |
76 etype = etype or '' |
77 etype = etype or '' |
77 try: |
78 try: |
81 |
82 |
82 except KeyError: |
83 except KeyError: |
83 self.error('can\'t register hook %s on %s (%s)', |
84 self.error('can\'t register hook %s on %s (%s)', |
84 event, etype or 'any', function.func_name) |
85 event, etype or 'any', function.func_name) |
85 |
86 |
86 def unregister_hook(self, function, event, etype=''): |
87 def unregister_hook(self, function_or_cls, event=None, etype=''): |
87 """register a function to call when <event> occurs |
88 """unregister a function to call when <event> occurs, or a Hook subclass. |
88 |
89 In the later case, event/type information are extracted from the given |
89 <etype> is an entity/relation type or an empty string. |
90 class. |
90 If etype is the empty string, the function will be called at each |
|
91 event, else the function will be called only when event occurs on an |
|
92 entity/relation of the given type. |
|
93 """ |
91 """ |
94 assert event in ALL_HOOKS, event |
92 if isinstance(function_or_cls, type) and issubclass(function_or_cls, Hook): |
95 etype = etype or '' |
93 for event, ertype in function_or_cls.register_to(): |
96 self.info('unregister hook %s on %s (%s)', event, etype, |
94 for hook in self._hooks[event][ertype]: |
97 function.func_name) |
95 if getattr(hook, 'im_self', None).__class__ is function_or_cls: |
98 self._hooks[event][etype].remove(function) |
96 self._hooks[event][ertype].remove(hook) |
|
97 self.info('unregister hook %s on %s (%s)', event, etype, |
|
98 function_or_cls.__name__) |
|
99 break |
|
100 else: |
|
101 self.warning("can't unregister hook %s on %s (%s), not found", |
|
102 event, etype, function_or_cls.__name__) |
|
103 else: |
|
104 assert event in ALL_HOOKS, event |
|
105 etype = etype or '' |
|
106 self.info('unregister hook %s on %s (%s)', event, etype, |
|
107 function_or_cls.func_name) |
|
108 self._hooks[event][etype].remove(function_or_cls) |
99 |
109 |
100 def call_hooks(self, __event, __type='', *args, **kwargs): |
110 def call_hooks(self, __event, __type='', *args, **kwargs): |
101 """call hook matching event and optional type""" |
111 """call hook matching event and optional type""" |
102 if __type: |
112 if __type: |
103 self.info('calling hooks for event %s (%s)', __event, __type) |
113 self.info('calling hooks for event %s (%s)', __event, __type) |