Mercurial > libervia-backend
comparison src/tools/trigger.py @ 2499:af4a38ebf52a
core (trigger): new returnPoint method:
Normally trigger return value is a boolean used to check if normal workflow must be continued or stopped.
This method add a way to also specify a return value to the method, in addition to the "continue or not" boolean.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 28 Feb 2018 18:28:39 +0100 |
parents | 0046283a285d |
children |
comparison
equal
deleted
inserted
replaced
2498:d6de69da3dd4 | 2499:af4a38ebf52a |
---|---|
27 class TriggerException(Exception): | 27 class TriggerException(Exception): |
28 pass | 28 pass |
29 | 29 |
30 | 30 |
31 class SkipOtherTriggers(Exception): | 31 class SkipOtherTriggers(Exception): |
32 """ Exception to raise if normal behaviour must be followed instead of | 32 """ Exception to raise if normal behaviour must be followed instead of following triggers list """ |
33 following triggers list """ | |
34 pass | 33 pass |
35 | 34 |
36 | 35 |
37 class TriggerManager(object): | 36 class TriggerManager(object): |
38 """This class manage triggers: code which interact to change the behaviour | 37 """This class manage triggers: code which interact to change the behaviour of SàT""" |
39 of SàT""" | |
40 | 38 |
41 try: # FIXME: to be removed when a better solution is found | 39 try: # FIXME: to be removed when a better solution is found |
42 MIN_PRIORITY = float('-inf') | 40 MIN_PRIORITY = float('-inf') |
43 MAX_PRIORITY = float('+inf') | 41 MAX_PRIORITY = float('+inf') |
44 except: # XXX: Pyjamas will bug if you specify ValueError here | 42 except: # XXX: Pyjamas will bug if you specify ValueError here |
49 def __init__(self): | 47 def __init__(self): |
50 self.__triggers = {} | 48 self.__triggers = {} |
51 | 49 |
52 def add(self, point_name, callback, priority=0): | 50 def add(self, point_name, callback, priority=0): |
53 """Add a trigger to a point | 51 """Add a trigger to a point |
52 | |
54 @param point_name: name of the point when the trigger should be run | 53 @param point_name: name of the point when the trigger should be run |
55 @param callback: method to call at the trigger point | 54 @param callback: method to call at the trigger point |
56 @param priority: callback will be called in priority order, biggest | 55 @param priority: callback will be called in priority order, biggest |
57 first | 56 first |
58 """ | 57 """ |
67 self.__triggers[point_name].sort(key=lambda trigger_tuple: | 66 self.__triggers[point_name].sort(key=lambda trigger_tuple: |
68 trigger_tuple[0], reverse=True) | 67 trigger_tuple[0], reverse=True) |
69 | 68 |
70 def remove(self, point_name, callback): | 69 def remove(self, point_name, callback): |
71 """Remove a trigger from a point | 70 """Remove a trigger from a point |
71 | |
72 @param point_name: name of the point when the trigger should be run | 72 @param point_name: name of the point when the trigger should be run |
73 @param callback: method to remove, must exists in the trigger point""" | 73 @param callback: method to remove, must exists in the trigger point |
74 """ | |
74 for trigger_tuple in self.__triggers[point_name]: | 75 for trigger_tuple in self.__triggers[point_name]: |
75 if trigger_tuple[1] == callback: | 76 if trigger_tuple[1] == callback: |
76 self.__triggers[point_name].remove(trigger_tuple) | 77 self.__triggers[point_name].remove(trigger_tuple) |
77 return | 78 return |
78 raise TriggerException("Trying to remove an unexisting trigger") | 79 raise TriggerException("Trying to remove an unexisting trigger") |
79 | 80 |
80 def point(self, point_name, *args, **kwargs): | 81 def point(self, point_name, *args, **kwargs): |
81 """This put a trigger point | 82 """This put a trigger point |
82 All the trigger for that point will be run | 83 |
84 All the triggers for that point will be run | |
83 @param point_name: name of the trigger point | 85 @param point_name: name of the trigger point |
84 @return: True if the action must be continued, False else""" | 86 @return: True if the action must be continued, False else |
87 """ | |
85 if point_name not in self.__triggers: | 88 if point_name not in self.__triggers: |
86 return True | 89 return True |
87 | 90 |
88 for priority, trigger in self.__triggers[point_name]: | 91 for priority, trigger in self.__triggers[point_name]: |
89 try: | 92 try: |
90 if not trigger(*args, **kwargs): | 93 if not trigger(*args, **kwargs): |
91 return False | 94 return False |
92 except SkipOtherTriggers: | 95 except SkipOtherTriggers: |
93 break | 96 break |
94 return True | 97 return True |
98 | |
99 def returnPoint(self, point_name, *args, **kwargs): | |
100 """Like point but trigger must return (continue, return_value) | |
101 | |
102 All triggers for that point must return a tuple with 2 values: | |
103 - continue, same as for point, if False action must be finished | |
104 - return_value: value to return ONLY IF CONTINUE IS FALSE | |
105 @param point_name: name of the trigger point | |
106 @return: True if the action must be continued, False else | |
107 """ | |
108 | |
109 if point_name not in self.__triggers: | |
110 return True | |
111 | |
112 for priority, trigger in self.__triggers[point_name]: | |
113 try: | |
114 cont, ret_value = trigger(*args, **kwargs) | |
115 if not cont: | |
116 return False, ret_value | |
117 except SkipOtherTriggers: | |
118 break | |
119 return True, None |