GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

EventController.event_loop_start()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 8
ccs 2
cts 2
cp 1
crap 1
rs 9.4285
1
"""
2
Enarksh
3
4
Copyright 2013-2016 Set Based IT Consultancy
5
6
Licence MIT
7
"""
8 1
import logging
9
10 1
from enarksh.event.Event import Event
11 1
from enarksh.event.EventActor import EventActor
12
13
14 1
class EventController(EventActor):
15
    """
16
    A single threaded and a run-to-completion event controller. That is, each event is processed completely before any
17
    other event is processed. Hence, an event listener will run entirely before any other code runs (which can
18
    potentially modify the data the event listener invokes).
19
20
    Methods with name starting with 'internal_' MUST not be called from your application (only friend classes are
21
    allowed to call these methods).
22
    """
23
24
    # ------------------------------------------------------------------------------------------------------------------
25 1
    def __init__(self):
26
        """
27
        Object constructor.
28
        """
29 1
        Event.event_controller = self
30
31 1
        EventActor.__init__(self)
32
33 1
        self._events = dict()
34
        """
35
        All events in the current program.
36
37
        :type: dict[enarksh.event.Event.Event,dict[*,list[*]]]
38
        """
39
40 1
        self._listener_objects = dict()
41
        """
42
43
        :type: dict[*, set[enarksh.event.Event.Event]]
44
        """
45
46 1
        self._event_loop_start = Event(self)
47
        """
48
        Event that will be fired at the start of the event loop.
49
50
        :type: enarksh.event.Event.Event
51
        """
52
53 1
        self._event_loop_end = Event(self)
54
        """
55
        Event that will be fired at the end of the event loop.
56
57
        :type: enarksh.event.Event.Event
58
        """
59
60 1
        self._event_queue_empty = Event(self)
61
        """
62
        Event that will be fired when the event queue is empty.
63
64
        :type: enarksh.event.Event.Event
65
        """
66
67 1
        self.exit = False
68
        """
69
        If True the event loop terminates as soon as the event queue is emtpy. No event_queue_empty event will be fired.
70
71
        :type: bool
72
        """
73
74 1
        self._queue = []
75
        """
76
        The queue with events that have fired but have not been processed yet.
77
78
        :type: list[(enarksh.event.Event.Event,*)]
79
        """
80
81 1
        self.__log = logging.getLogger('enarksh')
82 1
        """
83
        The logger.
84
85
        :type: logging.Logger
86
        """
87
88
    # ------------------------------------------------------------------------------------------------------------------
89 1
    @property
90
    def event_loop_end(self):
91
        """
92
        Returns the event that will be fired at the end of the event loop.
93
94
        :rtype: enarksh.event.Event.Event
95
        """
96 1
        return self._event_loop_end
97
98
    # ------------------------------------------------------------------------------------------------------------------
99 1
    @property
100
    def event_loop_start(self):
101
        """
102
        Returns the event that will be fired at the start of the event loop.
103
104
        :rtype: enarksh.event.Event.Event
105
        """
106 1
        return self._event_loop_start
107
108
    # ------------------------------------------------------------------------------------------------------------------
109 1
    @property
110
    def event_queue_empty(self):
111
        """
112
        Returns the event that will be fired when the event queue is empty.
113
114
        :rtype: enarksh.event.Event.Event
115
        """
116 1
        return self._event_queue_empty
117
118
    # ------------------------------------------------------------------------------------------------------------------
119 1
    def queue_size(self):
120
        """
121
        Returns the number of event on the event queue.
122
123
        :rtype: int
124
        """
125
        return len(self._queue)
126
127
    # ------------------------------------------------------------------------------------------------------------------
128 1
    def loop(self):
129
        """
130
        Start the event handler loop.
131
132
        The event handler loop terminates under each of the conditions below:
133
        * The event handler for 'event_queue_empty' completes without adding new events on the event queue.
134
        * Property exit has been set to True and the event queue is empty. Note: after property exit has been set to
135
          True event 'event_queue_empty' will not be fired any more.
136
        """
137 1
        self._dispatch_event(self._event_loop_start, None)
138
139 1
        if not self.exit and not self._queue:
140 1
            self._dispatch_event(self._event_queue_empty, None)
141
142 1
        while self._queue:
143 1
            event, event_data = self._queue.pop(0)
144
145 1
            self._dispatch_event(event, event_data)
146
147 1
            if not self._queue and not self.exit:
148 1
                self._dispatch_event(self._event_queue_empty, None)
149 1
                if not self._queue:
150 1
                    self.exit = True
151
152 1
        self._dispatch_event(self._event_loop_end, None)
153
154
    # ------------------------------------------------------------------------------------------------------------------
155 1
    def _dispatch_event(self, event, event_data):
156
        """
157
        Dispatches an event.
158
159
        :param enarksh.event.Event.Event event: The event to be dispatch.
160
        :param * event_data: Additional data supplied by the event source.
161
        """
162 1
        for listener_object, listeners in self._events[event.ref].items():
163 1
            for listener, listener_data in listeners:
164 1
                try:
165 1
                    if listener_object:
166 1
                        listener(listener_object(), event, event_data, listener_data)
167
                    else:
168
                        listener(event, event_data, listener_data)
169
                except Exception:
170
                    self.__log.exception('Error')
171
172
    # ------------------------------------------------------------------------------------------------------------------
173 1
    def internal_queue_event(self, event, event_data):
174
        """
175
        Puts an event that has fired on the event queue.
176
177
        Note: Do not use this method directly. Use enarksh.event.Event.Event.fire() instead.
178
179
        :param enarksh.event.Event.Event event: The event that has fired.
180
        :param * event_data: Additional data supplied by the event source.
181
        """
182 1
        self._queue.append((event, event_data))
183
184
    # ------------------------------------------------------------------------------------------------------------------
185 1
    def internal_unregister_event_ref(self, event_ref):
186
        """
187
        Removes an event as an event in the current program.
188
189
        Note: Do not use this method directly. Use enarksh.event.EventActor.EventActor.destroy() instead.
190
191
        :param enarksh.event.Event.Event event_ref: The event that must be removed.
192
        """
193 1
        if event_ref in self._events:
194 1
            for listener_object in self._events[event_ref].keys():
195 1
                events = self._listener_objects[listener_object]
196 1
                events.remove(event_ref)
197
198 1
                if not events:
199 1
                    del self._listener_objects[listener_object]
200
201 1
            del self._events[event_ref]
202
203
    # ------------------------------------------------------------------------------------------------------------------
204 1
    def internal_unregister_listener_object_ref(self, listener_object_ref):
205
        """
206
        Removes an object as a listener object (i.e. an object with one or more methods registered as event listeners).
207
208
        Note: Do not use this method directly.
209
210
        :param enarksh.event.Listener.Listener listener_object_ref: The listener object.
211
        """
212 1
        if listener_object_ref in self._listener_objects:
213
            # Remove the object from all events.
214 1
            for event in self._listener_objects[listener_object_ref]:
215 1
                del self._events[event][listener_object_ref]
216
217
            # Remove the object as listener object.
218 1
            del self._listener_objects[listener_object_ref]
219
220
    # ------------------------------------------------------------------------------------------------------------------
221 1
    def internal_register_event(self, event):
222
        """
223
        Registers an event as an event in the current program.
224
225
        Note: Do not use this method directly. This method is automatically called by
226
        enarksh.event.Event.Event#__init__()
227
228
        :param enarksh.event.Event.Event event: The event that must be registered.
229
        """
230 1
        self._events[event.ref] = dict()
231
232
    # ------------------------------------------------------------------------------------------------------------------
233 1
    def internal_register_listener(self, event, listener, listener_data=None):
234
        """
235
        Registers a callable as a listener for an event.
236
237
        Note: Do not use this method directly. Use enarksh.event.Event.Event.register_listener() instead.
238
239
        :param enarksh.event.Event.Event event: The event for which the listener needs to notified.
240
        :param callable listener: The callable that must be called when the event fires. If the callable is a class
241
                                  method it object must be an instance of enarksh.event.EventActor.EventActor.
242
        :param listener_data: Additional data supplied by the listener. This data will be passed to the listener when
243
                              the event fires.
244
        """
245 1
        if hasattr(listener, '__self__'):
246 1
            if not isinstance(listener.__self__, EventActor):
247
                raise ValueError('Only an event actor can be a listener, got {0}'.format(listener.__self__))
248 1
            listener_object = listener.__self__.ref
249 1
            listener = listener.__func__
250
        else:
251
            listener_object = None
252
253
        # Register the event and the listener.
254 1
        if listener_object not in self._events[event.ref]:
255 1
            self._events[event.ref][listener_object] = list()
256 1
        self._events[event.ref][listener_object].append((listener, listener_data))
257
258
        # Register the listener's object as a listener object.
259 1
        if listener_object not in self._listener_objects:
260 1
            self._listener_objects[listener_object] = set()
261 1
        self._listener_objects[listener_object].add(event.ref)
262
263
# ----------------------------------------------------------------------------------------------------------------------
264