src.fairreckitlib.core.events.event_dispatcher
This module contains a class that implements dispatcher/listener behaviour.
Classes:
EventDispatcher: can dispatch an event to the respectively subscribed listeners.
This program has been developed by students from the bachelor Computer Science at Utrecht University within the Software Project course. © Copyright Utrecht University (Department of Information and Computing Sciences)
1"""This module contains a class that implements dispatcher/listener behaviour. 2 3Classes: 4 5 EventDispatcher: can dispatch an event to the respectively subscribed listeners. 6 7This program has been developed by students from the bachelor Computer Science at 8Utrecht University within the Software Project course. 9© Copyright Utrecht University (Department of Information and Computing Sciences) 10""" 11 12from typing import Any, Callable, Optional, Tuple 13 14from .event_args import EventArgs 15 16 17class EventDispatcher: 18 """Event Dispatcher provides tools to communicate events to listeners. 19 20 The dispatcher is a centralized object that keeps track of all registered listeners 21 for a specified event ID. These listeners can be added and removed dynamically. 22 23 Public methods: 24 25 add_listener 26 get_num_listeners 27 get_num_listeners_total 28 remove_listener 29 dispatch 30 """ 31 32 def __init__(self): 33 """Construct the EventDispatcher.""" 34 self.listeners = {} 35 36 def add_listener( 37 self, 38 event_id: str, 39 event_listener: Any, 40 func_on_event: Tuple[ 41 Callable[[Any, EventArgs], None], 42 Optional[Callable[[Any, EventArgs], None]] 43 ]) -> None: 44 """Add a listener for the specified event ID. 45 46 The event_listener and func_on_event are joined as a tuple to describe the listener 47 and is expected to be unique. The listener will be notified by the dispatcher 48 every time that the event arguments with the specified ID is propagated. 49 This function raises a KeyError when the listener tuple already exists. 50 51 Args: 52 event_id: unique ID that classifies the event. 53 event_listener: the listener of the event. This object is passed to 54 the event callback function as the first argument when the event is dispatched. 55 func_on_event: the callback functions that are called when the event 56 is dispatched. The first argument is the event_listener, followed by event args. 57 and any keyword args 58 """ 59 if event_id not in self.listeners: 60 self.listeners[event_id] = [] 61 62 listener = (event_listener, func_on_event) 63 if listener in self.listeners[event_id]: 64 raise KeyError('listener is already registered for event', event_id) 65 66 self.listeners[event_id].append(listener) 67 68 def get_num_listeners(self, event_id: str) -> Optional[int]: 69 """Get the amount of listeners for the specified event id. 70 71 Args: 72 event_id: the event id to query the number of listeners of. 73 74 Returns: 75 the number of listeners of the event or None when the event is not registered. 76 """ 77 return len(self.listeners[event_id]) if event_id in self.listeners else None 78 79 def get_num_listeners_total(self) -> int: 80 """Get the total amount of listeners for the dispatcher. 81 82 Returns: 83 the number of listeners in total. 84 """ 85 num_listeners = 0 86 87 for event_id, _ in self.listeners.items(): 88 num_listeners += self.get_num_listeners(event_id) 89 90 return num_listeners 91 92 def remove_listener( 93 self, 94 event_id: str, 95 event_listener: Any, 96 func_on_event: Tuple[ 97 Callable[[Any, EventArgs], None], 98 Optional[Callable[[Any, EventArgs], None]] 99 ]) -> None: 100 """Remove a listener for the specified event ID. 101 102 The event_listener and func_on_event are joined as a tuple to describe the listener 103 and is expected to be unique. The listener is also expected to be identical to the one 104 that was used in 'add_listener' and will no longer be notified by the dispatcher when the 105 event arguments with the specified ID is propagated. 106 This function raises a KeyError when either the event_id or listener tuple does not exist. 107 108 Args: 109 event_id: unique ID that classifies the event. 110 event_listener: the listener of the event. This object is passed to 111 the event callback function as the first argument when the event is dispatched. 112 func_on_event: the callback functions that are called when the event 113 is dispatched. The first argument is the event_listener, followed by event args 114 and any keyword args. 115 """ 116 if event_id not in self.listeners: 117 raise KeyError('event is not registered:', event_id) 118 119 listener = (event_listener, func_on_event) 120 if listener not in self.listeners[event_id]: 121 raise KeyError('listener is not registered for event:', event_id) 122 123 self.listeners[event_id].remove(listener) 124 125 def dispatch(self, event_args: EventArgs, **kwargs) -> bool: 126 """Dispatch event arguments with the corresponding event ID. 127 128 The event arguments with the specified ID will be propagated to all registered listeners. 129 For each listener their respective callback function is called with the listener 130 as the first argument, followed by the specified event args and keyword args. 131 132 Args: 133 event_args: the event's arguments. 134 135 Keyword Args: 136 Any: varies depending on the event. 137 138 Returns: 139 whether the event was dispatched to any registered listeners. 140 """ 141 if event_args.event_id not in self.listeners: 142 return False 143 144 for (event_listener, func_on_event) in self.listeners[event_args.event_id]: 145 internal_func, external_func = func_on_event 146 internal_func(event_listener, event_args, **kwargs) 147 if external_func is not None: 148 external_func(event_listener, event_args, **kwargs) 149 150 return True
18class EventDispatcher: 19 """Event Dispatcher provides tools to communicate events to listeners. 20 21 The dispatcher is a centralized object that keeps track of all registered listeners 22 for a specified event ID. These listeners can be added and removed dynamically. 23 24 Public methods: 25 26 add_listener 27 get_num_listeners 28 get_num_listeners_total 29 remove_listener 30 dispatch 31 """ 32 33 def __init__(self): 34 """Construct the EventDispatcher.""" 35 self.listeners = {} 36 37 def add_listener( 38 self, 39 event_id: str, 40 event_listener: Any, 41 func_on_event: Tuple[ 42 Callable[[Any, EventArgs], None], 43 Optional[Callable[[Any, EventArgs], None]] 44 ]) -> None: 45 """Add a listener for the specified event ID. 46 47 The event_listener and func_on_event are joined as a tuple to describe the listener 48 and is expected to be unique. The listener will be notified by the dispatcher 49 every time that the event arguments with the specified ID is propagated. 50 This function raises a KeyError when the listener tuple already exists. 51 52 Args: 53 event_id: unique ID that classifies the event. 54 event_listener: the listener of the event. This object is passed to 55 the event callback function as the first argument when the event is dispatched. 56 func_on_event: the callback functions that are called when the event 57 is dispatched. The first argument is the event_listener, followed by event args. 58 and any keyword args 59 """ 60 if event_id not in self.listeners: 61 self.listeners[event_id] = [] 62 63 listener = (event_listener, func_on_event) 64 if listener in self.listeners[event_id]: 65 raise KeyError('listener is already registered for event', event_id) 66 67 self.listeners[event_id].append(listener) 68 69 def get_num_listeners(self, event_id: str) -> Optional[int]: 70 """Get the amount of listeners for the specified event id. 71 72 Args: 73 event_id: the event id to query the number of listeners of. 74 75 Returns: 76 the number of listeners of the event or None when the event is not registered. 77 """ 78 return len(self.listeners[event_id]) if event_id in self.listeners else None 79 80 def get_num_listeners_total(self) -> int: 81 """Get the total amount of listeners for the dispatcher. 82 83 Returns: 84 the number of listeners in total. 85 """ 86 num_listeners = 0 87 88 for event_id, _ in self.listeners.items(): 89 num_listeners += self.get_num_listeners(event_id) 90 91 return num_listeners 92 93 def remove_listener( 94 self, 95 event_id: str, 96 event_listener: Any, 97 func_on_event: Tuple[ 98 Callable[[Any, EventArgs], None], 99 Optional[Callable[[Any, EventArgs], None]] 100 ]) -> None: 101 """Remove a listener for the specified event ID. 102 103 The event_listener and func_on_event are joined as a tuple to describe the listener 104 and is expected to be unique. The listener is also expected to be identical to the one 105 that was used in 'add_listener' and will no longer be notified by the dispatcher when the 106 event arguments with the specified ID is propagated. 107 This function raises a KeyError when either the event_id or listener tuple does not exist. 108 109 Args: 110 event_id: unique ID that classifies the event. 111 event_listener: the listener of the event. This object is passed to 112 the event callback function as the first argument when the event is dispatched. 113 func_on_event: the callback functions that are called when the event 114 is dispatched. The first argument is the event_listener, followed by event args 115 and any keyword args. 116 """ 117 if event_id not in self.listeners: 118 raise KeyError('event is not registered:', event_id) 119 120 listener = (event_listener, func_on_event) 121 if listener not in self.listeners[event_id]: 122 raise KeyError('listener is not registered for event:', event_id) 123 124 self.listeners[event_id].remove(listener) 125 126 def dispatch(self, event_args: EventArgs, **kwargs) -> bool: 127 """Dispatch event arguments with the corresponding event ID. 128 129 The event arguments with the specified ID will be propagated to all registered listeners. 130 For each listener their respective callback function is called with the listener 131 as the first argument, followed by the specified event args and keyword args. 132 133 Args: 134 event_args: the event's arguments. 135 136 Keyword Args: 137 Any: varies depending on the event. 138 139 Returns: 140 whether the event was dispatched to any registered listeners. 141 """ 142 if event_args.event_id not in self.listeners: 143 return False 144 145 for (event_listener, func_on_event) in self.listeners[event_args.event_id]: 146 internal_func, external_func = func_on_event 147 internal_func(event_listener, event_args, **kwargs) 148 if external_func is not None: 149 external_func(event_listener, event_args, **kwargs) 150 151 return True
Event Dispatcher provides tools to communicate events to listeners.
The dispatcher is a centralized object that keeps track of all registered listeners for a specified event ID. These listeners can be added and removed dynamically.
Public methods:
add_listener get_num_listeners get_num_listeners_total remove_listener dispatch
37 def add_listener( 38 self, 39 event_id: str, 40 event_listener: Any, 41 func_on_event: Tuple[ 42 Callable[[Any, EventArgs], None], 43 Optional[Callable[[Any, EventArgs], None]] 44 ]) -> None: 45 """Add a listener for the specified event ID. 46 47 The event_listener and func_on_event are joined as a tuple to describe the listener 48 and is expected to be unique. The listener will be notified by the dispatcher 49 every time that the event arguments with the specified ID is propagated. 50 This function raises a KeyError when the listener tuple already exists. 51 52 Args: 53 event_id: unique ID that classifies the event. 54 event_listener: the listener of the event. This object is passed to 55 the event callback function as the first argument when the event is dispatched. 56 func_on_event: the callback functions that are called when the event 57 is dispatched. The first argument is the event_listener, followed by event args. 58 and any keyword args 59 """ 60 if event_id not in self.listeners: 61 self.listeners[event_id] = [] 62 63 listener = (event_listener, func_on_event) 64 if listener in self.listeners[event_id]: 65 raise KeyError('listener is already registered for event', event_id) 66 67 self.listeners[event_id].append(listener)
Add a listener for the specified event ID.
The event_listener and func_on_event are joined as a tuple to describe the listener and is expected to be unique. The listener will be notified by the dispatcher every time that the event arguments with the specified ID is propagated. This function raises a KeyError when the listener tuple already exists.
Args: event_id: unique ID that classifies the event. event_listener: the listener of the event. This object is passed to the event callback function as the first argument when the event is dispatched. func_on_event: the callback functions that are called when the event is dispatched. The first argument is the event_listener, followed by event args. and any keyword args
69 def get_num_listeners(self, event_id: str) -> Optional[int]: 70 """Get the amount of listeners for the specified event id. 71 72 Args: 73 event_id: the event id to query the number of listeners of. 74 75 Returns: 76 the number of listeners of the event or None when the event is not registered. 77 """ 78 return len(self.listeners[event_id]) if event_id in self.listeners else None
Get the amount of listeners for the specified event id.
Args: event_id: the event id to query the number of listeners of.
Returns: the number of listeners of the event or None when the event is not registered.
80 def get_num_listeners_total(self) -> int: 81 """Get the total amount of listeners for the dispatcher. 82 83 Returns: 84 the number of listeners in total. 85 """ 86 num_listeners = 0 87 88 for event_id, _ in self.listeners.items(): 89 num_listeners += self.get_num_listeners(event_id) 90 91 return num_listeners
Get the total amount of listeners for the dispatcher.
Returns: the number of listeners in total.
93 def remove_listener( 94 self, 95 event_id: str, 96 event_listener: Any, 97 func_on_event: Tuple[ 98 Callable[[Any, EventArgs], None], 99 Optional[Callable[[Any, EventArgs], None]] 100 ]) -> None: 101 """Remove a listener for the specified event ID. 102 103 The event_listener and func_on_event are joined as a tuple to describe the listener 104 and is expected to be unique. The listener is also expected to be identical to the one 105 that was used in 'add_listener' and will no longer be notified by the dispatcher when the 106 event arguments with the specified ID is propagated. 107 This function raises a KeyError when either the event_id or listener tuple does not exist. 108 109 Args: 110 event_id: unique ID that classifies the event. 111 event_listener: the listener of the event. This object is passed to 112 the event callback function as the first argument when the event is dispatched. 113 func_on_event: the callback functions that are called when the event 114 is dispatched. The first argument is the event_listener, followed by event args 115 and any keyword args. 116 """ 117 if event_id not in self.listeners: 118 raise KeyError('event is not registered:', event_id) 119 120 listener = (event_listener, func_on_event) 121 if listener not in self.listeners[event_id]: 122 raise KeyError('listener is not registered for event:', event_id) 123 124 self.listeners[event_id].remove(listener)
Remove a listener for the specified event ID.
The event_listener and func_on_event are joined as a tuple to describe the listener and is expected to be unique. The listener is also expected to be identical to the one that was used in 'add_listener' and will no longer be notified by the dispatcher when the event arguments with the specified ID is propagated. This function raises a KeyError when either the event_id or listener tuple does not exist.
Args: event_id: unique ID that classifies the event. event_listener: the listener of the event. This object is passed to the event callback function as the first argument when the event is dispatched. func_on_event: the callback functions that are called when the event is dispatched. The first argument is the event_listener, followed by event args and any keyword args.
126 def dispatch(self, event_args: EventArgs, **kwargs) -> bool: 127 """Dispatch event arguments with the corresponding event ID. 128 129 The event arguments with the specified ID will be propagated to all registered listeners. 130 For each listener their respective callback function is called with the listener 131 as the first argument, followed by the specified event args and keyword args. 132 133 Args: 134 event_args: the event's arguments. 135 136 Keyword Args: 137 Any: varies depending on the event. 138 139 Returns: 140 whether the event was dispatched to any registered listeners. 141 """ 142 if event_args.event_id not in self.listeners: 143 return False 144 145 for (event_listener, func_on_event) in self.listeners[event_args.event_id]: 146 internal_func, external_func = func_on_event 147 internal_func(event_listener, event_args, **kwargs) 148 if external_func is not None: 149 external_func(event_listener, event_args, **kwargs) 150 151 return True
Dispatch event arguments with the corresponding event ID.
The event arguments with the specified ID will be propagated to all registered listeners. For each listener their respective callback function is called with the listener as the first argument, followed by the specified event args and keyword args.
Args: event_args: the event's arguments.
Keyword Args: Any: varies depending on the event.
Returns: whether the event was dispatched to any registered listeners.