PyEventEngine 0.6.2__cp315-cp315t-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. event_engine/__infra__.pxd +2 -0
  2. event_engine/__init__.pxd +2 -0
  3. event_engine/__init__.py +62 -0
  4. event_engine/base/__infra__.pxd +9 -0
  5. event_engine/base/__init__.pxd +9 -0
  6. event_engine/base/__init__.py +31 -0
  7. event_engine/base/c_allocator_protocol.c +14310 -0
  8. event_engine/base/c_allocator_protocol.cp315t-win_amd64.pyd +0 -0
  9. event_engine/base/c_allocator_protocol.h +23 -0
  10. event_engine/base/c_allocator_protocol.pxd +31 -0
  11. event_engine/base/c_allocator_protocol.pyx +193 -0
  12. event_engine/capi/__infra__.pxd +189 -0
  13. event_engine/capi/__init__.pxd +189 -0
  14. event_engine/capi/__init__.py +84 -0
  15. event_engine/capi/c_engine.c +32542 -0
  16. event_engine/capi/c_engine.cp315t-win_amd64.pyd +0 -0
  17. event_engine/capi/c_engine.h +393 -0
  18. event_engine/capi/c_engine.pxd +84 -0
  19. event_engine/capi/c_engine.pyi +478 -0
  20. event_engine/capi/c_engine.pyx +673 -0
  21. event_engine/capi/c_event.c +22826 -0
  22. event_engine/capi/c_event.cp315t-win_amd64.pyd +0 -0
  23. event_engine/capi/c_event.h +342 -0
  24. event_engine/capi/c_event.pxd +159 -0
  25. event_engine/capi/c_event.pyi +265 -0
  26. event_engine/capi/c_event.pyx +444 -0
  27. event_engine/capi/c_topic.c +34545 -0
  28. event_engine/capi/c_topic.cp315t-win_amd64.pyd +0 -0
  29. event_engine/capi/c_topic.h +1007 -0
  30. event_engine/capi/c_topic.pxd +147 -0
  31. event_engine/capi/c_topic.pyi +644 -0
  32. event_engine/capi/c_topic.pyx +818 -0
  33. event_engine/capi/fallback_engine.py +707 -0
  34. event_engine/config_view.c +10271 -0
  35. event_engine/config_view.cp315t-win_amd64.pyd +0 -0
  36. event_engine/config_view.pyx +55 -0
  37. event_engine/includes/event_engine/base/c_allocator_protocol.c +14310 -0
  38. event_engine/includes/event_engine/base/c_allocator_protocol.h +23 -0
  39. event_engine/includes/event_engine/capi/c_engine.c +32542 -0
  40. event_engine/includes/event_engine/capi/c_engine.h +393 -0
  41. event_engine/includes/event_engine/capi/c_event.c +22826 -0
  42. event_engine/includes/event_engine/capi/c_event.h +342 -0
  43. event_engine/includes/event_engine/capi/c_topic.c +34545 -0
  44. event_engine/includes/event_engine/capi/c_topic.h +1007 -0
  45. event_engine/includes/event_engine/config_view.c +10271 -0
  46. event_engine/native/__init__.py +60 -0
  47. event_engine/native/_event.py +420 -0
  48. event_engine/native/_topic.py +171 -0
  49. event_engine/native/engine.py +793 -0
  50. event_engine/native/event.py +469 -0
  51. event_engine/native/topic.py +943 -0
  52. pyeventengine-0.6.2.dist-info/METADATA +189 -0
  53. pyeventengine-0.6.2.dist-info/RECORD +56 -0
  54. pyeventengine-0.6.2.dist-info/WHEEL +5 -0
  55. pyeventengine-0.6.2.dist-info/licenses/LICENSE +21 -0
  56. pyeventengine-0.6.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,393 @@
1
+ #ifndef C_ENGINE_H
2
+ #define C_ENGINE_H
3
+
4
+ #include <errno.h>
5
+ #include <stdatomic.h>
6
+ #include <stdint.h>
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+ #include <time.h>
10
+
11
+ #ifdef _WIN32
12
+ #include <cbase/nt/pthread_nt_compat.h>
13
+ #include <cbase/nt/time_sched_nt_compat.h>
14
+ #else
15
+ #include <pthread.h>
16
+ #include <sched.h>
17
+ #endif
18
+
19
+ #include <cbase/allocator_protocol/c_allocator_protocol.h>
20
+ #include <event_engine/capi/c_event.h>
21
+ #include <event_engine/capi/c_topic.h>
22
+
23
+ /* Default capacity if not provided elsewhere */
24
+ #ifndef DEFAULT_MQ_CAPACITY
25
+ #define DEFAULT_MQ_CAPACITY 0x0fff
26
+ #endif
27
+
28
+ /* Hybrid spin limit (number of busy iterations before blocking) */
29
+ #ifndef DEFAULT_MQ_SPIN_LIMIT
30
+ #define DEFAULT_MQ_SPIN_LIMIT 0xffff
31
+ #endif
32
+
33
+ /* Default timeout in seconds for blocking operations */
34
+ #ifndef DEFAULT_MQ_TIMEOUT_SECONDS
35
+ #define DEFAULT_MQ_TIMEOUT_SECONDS 1.0
36
+ #endif
37
+
38
+ /* @brief In-memory ring-buffer message queue
39
+ *
40
+ * The buffer is a flexible array member placed last so the whole queue + buffer
41
+ * can be allocated in one block for better locality and simpler allocation.
42
+ */
43
+ typedef struct message_queue {
44
+ size_t capacity; // max number of entries
45
+ size_t head; // index to pop
46
+ size_t tail; // index to push
47
+ size_t count; // current count
48
+ evt_topic* topic; // topic this queue is bound to (may be NULL)
49
+
50
+ pthread_mutex_t mutex;
51
+ pthread_cond_t not_empty;
52
+ pthread_cond_t not_full;
53
+
54
+ #ifdef _WIN32
55
+ evt_message_payload* buf[1]; // MSVC-compatible trailing storage
56
+ #else
57
+ evt_message_payload* buf[]; // flexible array member
58
+ #endif
59
+ } message_queue;
60
+
61
+ /* ----------------------------------------------------------------------
62
+ * Signatures and Documentation
63
+ * --------------------------------------------------------------------*/
64
+
65
+ /**
66
+ * @brief Create a new message queue.
67
+ * @param capacity maximum number of entries (must be > 0)
68
+ * @param topic optional Topic to bind the queue to (may be NULL)
69
+ * @param allocator allocator_protocol for the allocation
70
+ * @return pointer to newly allocated message_queue or NULL on allocation failure
71
+ */
72
+ static inline message_queue* c_mq_new(size_t capacity, evt_topic* topic, allocator_protocol* allocator);
73
+
74
+ /**
75
+ * @brief Destroy a message queue.
76
+ * @param mq pointer to message_queue to destroy
77
+ * @return 0 on success, -1 on invalid argument
78
+ *
79
+ * Note: does not free evt_message_payload pointers still present in the buffer;
80
+ * caller is responsible for draining/freeing them before calling.
81
+ */
82
+ static inline int c_mq_free(message_queue* mq);
83
+
84
+ /**
85
+ * @brief Non-blocking put into the queue.
86
+ * @param mq queue pointer
87
+ * @param msg pointer to evt_message_payload (caller-owned)
88
+ * @return 0 on success, -1 on full/invalid args
89
+ */
90
+ static inline int c_mq_put(message_queue* mq, evt_message_payload* msg);
91
+
92
+ /**
93
+ * @brief Non-blocking get from the queue.
94
+ * @param mq queue pointer
95
+ * @param out_msg out parameter to receive evt_message_payload*
96
+ * @return 0 on success, -1 on empty/invalid args
97
+ */
98
+ static inline int c_mq_get(message_queue* mq, evt_message_payload** out_msg);
99
+
100
+ /**
101
+ * @brief Blocking put; waits until space available or timeout.
102
+ * @param mq queue pointer
103
+ * @param msg pointer to evt_message_payload
104
+ * @param timeout_seconds maximum seconds to wait (<=0 means wait forever)
105
+ * @return 0 on success, -1 on timeout/invalid args or error
106
+ */
107
+ static inline int c_mq_put_await(message_queue* mq, evt_message_payload* msg, double timeout_seconds);
108
+
109
+ /**
110
+ * @brief Blocking get; waits until an item is available or timeout.
111
+ * @param mq queue pointer
112
+ * @param out_msg out parameter to receive evt_message_payload*
113
+ * @param timeout_seconds maximum seconds to wait (<=0 means wait forever)
114
+ * @return 0 on success, -1 on timeout/invalid args or error
115
+ */
116
+ static inline int c_mq_get_await(message_queue* mq, evt_message_payload** out_msg, double timeout_seconds);
117
+
118
+ /**
119
+ * @brief Busy-looping put (spin up to max_spin times until space).
120
+ * @param mq queue pointer
121
+ * @param msg pointer to evt_message_payload
122
+ * @param max_spin maximum spin attempts before giving up
123
+ * @return 0 on success, -1 on full/invalid args or if max_spin reached
124
+ */
125
+ static inline int c_mq_put_busy(message_queue* mq, evt_message_payload* msg, size_t max_spin);
126
+
127
+ /**
128
+ * @brief Busy-looping get (spin up to max_spin times until item).
129
+ * @param mq queue pointer
130
+ * @param out_msg out parameter to receive evt_message_payload*
131
+ * @param max_spin maximum spin attempts before giving up
132
+ * @return 0 on success, -1 on empty/invalid args or if max_spin reached
133
+ */
134
+ static inline int c_mq_get_busy(message_queue* mq, evt_message_payload** out_msg, size_t max_spin);
135
+
136
+ /**
137
+ * @brief Hybrid put: busy-spin for a short while then block (timeout does not include spin time).
138
+ * @param mq queue pointer
139
+ * @param msg pointer to evt_message_payload
140
+ * @param timeout_seconds maximum seconds to wait in blocking phase (<=0 means wait forever)
141
+ * @return 0 on success, -1 on timeout/invalid args or error
142
+ */
143
+ static inline int c_mq_put_hybrid(message_queue* mq, evt_message_payload* msg, size_t max_spin, double timeout_seconds);
144
+
145
+ /**
146
+ * @brief Hybrid get: busy-spin for a short while then block (timeout does not include spin time).
147
+ * @param mq queue pointer
148
+ * @param out_msg out parameter to receive evt_message_payload*
149
+ * @param timeout_seconds maximum seconds to wait in blocking phase (<=0 means wait forever)
150
+ * @return 0 on success, -1 on timeout/invalid args or error
151
+ */
152
+ static inline int c_mq_get_hybrid(message_queue* mq, evt_message_payload** out_msg, size_t max_spin, double timeout_seconds);
153
+
154
+ /**
155
+ * @brief Get current occupied count of the queue.
156
+ * @param mq queue pointer
157
+ * @return number of occupied entries, or 0 on invalid arg
158
+ */
159
+ static inline size_t c_mq_occupied(message_queue* mq);
160
+
161
+ /* ----------------------------------------------------------------------
162
+ * Implementations
163
+ * --------------------------------------------------------------------*/
164
+
165
+ /* Helper: add seconds (fractional allowed) to timespec */
166
+ static inline void timespec_add_seconds(struct timespec* ts, double seconds) {
167
+ time_t sec = (time_t) seconds;
168
+ long nsec = (long) ((seconds - (double) sec) * 1e9);
169
+ ts->tv_sec += sec;
170
+ ts->tv_nsec += nsec;
171
+ if (ts->tv_nsec >= 1000000000L) {
172
+ ts->tv_sec += 1;
173
+ ts->tv_nsec -= 1000000000L;
174
+ }
175
+ else if (ts->tv_nsec < 0) {
176
+ ts->tv_sec -= 1;
177
+ ts->tv_nsec += 1000000000L;
178
+ }
179
+ }
180
+
181
+ /* Create a new queue. Returns NULL on allocation failure. */
182
+ static inline message_queue* c_mq_new(size_t capacity, evt_topic* topic, allocator_protocol* allocator) {
183
+ if (capacity == 0) return NULL;
184
+
185
+ #ifdef _WIN32
186
+ size_t total_bytes = sizeof(message_queue) + (capacity - 1) * sizeof(evt_message_payload*);
187
+ #else
188
+ size_t total_bytes = sizeof(message_queue) + capacity * sizeof(evt_message_payload*);
189
+ #endif
190
+
191
+ message_queue* mq = (message_queue*) c_ap_alloc(total_bytes, allocator);
192
+ if (!mq) return NULL;
193
+
194
+ mq->capacity = capacity;
195
+ mq->head = mq->tail = mq->count = 0;
196
+ mq->topic = topic;
197
+
198
+ pthread_mutex_init(&mq->mutex, NULL);
199
+ pthread_cond_init(&mq->not_empty, NULL);
200
+ pthread_cond_init(&mq->not_full, NULL);
201
+
202
+ return mq;
203
+ }
204
+
205
+ /* Destroy queue. Does not free message payloads pointed to by entries. */
206
+ static inline int c_mq_free(message_queue* mq) {
207
+ if (!mq) return -1;
208
+
209
+ pthread_mutex_lock(&mq->mutex);
210
+ pthread_mutex_unlock(&mq->mutex);
211
+ pthread_cond_destroy(&mq->not_empty);
212
+ pthread_cond_destroy(&mq->not_full);
213
+ pthread_mutex_destroy(&mq->mutex);
214
+
215
+ c_ap_free(mq);
216
+ return 0;
217
+ }
218
+
219
+ /* Non-blocking put. Returns 0 on success, -1 on full/invalid args. */
220
+ static inline int c_mq_put(message_queue* mq, evt_message_payload* msg) {
221
+ if (!mq || !msg) return -1;
222
+ int ret = -1;
223
+ pthread_mutex_lock(&mq->mutex);
224
+ if (mq->count == mq->capacity) {
225
+ ret = -1; /* full */
226
+ }
227
+ else {
228
+ mq->buf[mq->tail] = msg;
229
+ mq->tail = (mq->tail + 1) % mq->capacity;
230
+ mq->count++;
231
+ pthread_cond_signal(&mq->not_empty);
232
+ ret = 0;
233
+ }
234
+ pthread_mutex_unlock(&mq->mutex);
235
+ return ret;
236
+ }
237
+
238
+ /* Non-blocking get. On success *out_msg is set and returns 0. Returns -1 if empty/invalid args. */
239
+ static inline int c_mq_get(message_queue* mq, evt_message_payload** out_msg) {
240
+ if (!mq || !out_msg) return -1;
241
+ int ret = -1;
242
+ pthread_mutex_lock(&mq->mutex);
243
+ if (mq->count == 0) {
244
+ ret = -1; /* empty */
245
+ }
246
+ else {
247
+ *out_msg = mq->buf[mq->head];
248
+ mq->buf[mq->head] = NULL;
249
+ mq->head = (mq->head + 1) % mq->capacity;
250
+ mq->count--;
251
+ pthread_cond_signal(&mq->not_full);
252
+ ret = 0;
253
+ }
254
+ pthread_mutex_unlock(&mq->mutex);
255
+ return ret;
256
+ }
257
+
258
+ /* Blocking put. Waits until space is available. Returns 0 on success, -1 on error. */
259
+ static inline int c_mq_put_await(message_queue* mq, evt_message_payload* msg, double timeout_seconds) {
260
+ if (!mq || !msg) return -1;
261
+ pthread_mutex_lock(&mq->mutex);
262
+ struct timespec ts;
263
+ if (timeout_seconds > 0) {
264
+ clock_gettime(CLOCK_REALTIME, &ts);
265
+ timespec_add_seconds(&ts, timeout_seconds);
266
+ }
267
+ while (mq->count == mq->capacity) {
268
+ if (timeout_seconds > 0) {
269
+ int rc = pthread_cond_timedwait(&mq->not_full, &mq->mutex, &ts);
270
+ if (rc == ETIMEDOUT) {
271
+ pthread_mutex_unlock(&mq->mutex);
272
+ return -1;
273
+ }
274
+ if (rc != 0 && rc != EINTR) {
275
+ pthread_mutex_unlock(&mq->mutex);
276
+ return -1;
277
+ }
278
+ }
279
+ else {
280
+ pthread_cond_wait(&mq->not_full, &mq->mutex);
281
+ }
282
+ }
283
+ mq->buf[mq->tail] = msg;
284
+ mq->tail = (mq->tail + 1) % mq->capacity;
285
+ mq->count++;
286
+ pthread_cond_signal(&mq->not_empty);
287
+ pthread_mutex_unlock(&mq->mutex);
288
+ return 0;
289
+ }
290
+
291
+ /* Blocking get. Waits until an item is available. Returns 0 on success, -1 on error. */
292
+ static inline int c_mq_get_await(message_queue* mq, evt_message_payload** out_msg, double timeout_seconds) {
293
+ if (!mq || !out_msg) return -1;
294
+ pthread_mutex_lock(&mq->mutex);
295
+ struct timespec ts;
296
+ if (timeout_seconds > 0) {
297
+ clock_gettime(CLOCK_REALTIME, &ts);
298
+ timespec_add_seconds(&ts, timeout_seconds);
299
+ }
300
+ while (mq->count == 0) {
301
+ if (timeout_seconds > 0) {
302
+ int rc = pthread_cond_timedwait(&mq->not_empty, &mq->mutex, &ts);
303
+ if (rc == ETIMEDOUT) {
304
+ pthread_mutex_unlock(&mq->mutex);
305
+ return -1;
306
+ }
307
+ if (rc != 0 && rc != EINTR) {
308
+ pthread_mutex_unlock(&mq->mutex);
309
+ return -1;
310
+ }
311
+ }
312
+ else {
313
+ pthread_cond_wait(&mq->not_empty, &mq->mutex);
314
+ }
315
+ }
316
+ *out_msg = mq->buf[mq->head];
317
+ mq->buf[mq->head] = NULL;
318
+ mq->head = (mq->head + 1) % mq->capacity;
319
+ mq->count--;
320
+ pthread_cond_signal(&mq->not_full);
321
+ pthread_mutex_unlock(&mq->mutex);
322
+ return 0;
323
+ }
324
+
325
+ /* Busy-looping put (spin up to max_spin times until space). */
326
+ static inline int c_mq_put_busy(message_queue* mq, evt_message_payload* msg, size_t max_spin) {
327
+ if (!mq || !msg) return -1;
328
+ for (size_t i = 0; i < max_spin; ++i) {
329
+ pthread_mutex_lock(&mq->mutex);
330
+ if (mq->count < mq->capacity) {
331
+ mq->buf[mq->tail] = msg;
332
+ mq->tail = (mq->tail + 1) % mq->capacity;
333
+ mq->count++;
334
+ pthread_cond_signal(&mq->not_empty);
335
+ pthread_mutex_unlock(&mq->mutex);
336
+ return 0;
337
+ }
338
+ pthread_mutex_unlock(&mq->mutex);
339
+ sched_yield();
340
+ }
341
+ return -1;
342
+ }
343
+
344
+ /* Busy-looping get (spin up to max_spin times until item). */
345
+ static inline int c_mq_get_busy(message_queue* mq, evt_message_payload** out_msg, size_t max_spin) {
346
+ if (!mq || !out_msg) return -1;
347
+ for (size_t i = 0; i < max_spin; ++i) {
348
+ pthread_mutex_lock(&mq->mutex);
349
+ if (mq->count > 0) {
350
+ *out_msg = mq->buf[mq->head];
351
+ mq->buf[mq->head] = NULL;
352
+ mq->head = (mq->head + 1) % mq->capacity;
353
+ mq->count--;
354
+ pthread_cond_signal(&mq->not_full);
355
+ pthread_mutex_unlock(&mq->mutex);
356
+ return 0;
357
+ }
358
+ pthread_mutex_unlock(&mq->mutex);
359
+ sched_yield();
360
+ }
361
+ return -1;
362
+ }
363
+
364
+ /* Hybrid put: busy-spin for max_spin iterations then block */
365
+ static inline int c_mq_put_hybrid(message_queue* mq, evt_message_payload* msg, size_t max_spin, double timeout_seconds) {
366
+ if (!mq || !msg) return -1;
367
+ if (c_mq_put_busy(mq, msg, max_spin) == 0) {
368
+ return 0;
369
+ }
370
+ // After spinning, fallback to blocking with timeout (timeout does not include spin time)
371
+ return c_mq_put_await(mq, msg, timeout_seconds);
372
+ }
373
+
374
+ /* Hybrid get: busy-spin for max_spin iterations then block */
375
+ static inline int c_mq_get_hybrid(message_queue* mq, evt_message_payload** out_msg, size_t max_spin, double timeout_seconds) {
376
+ if (!mq || !out_msg) return -1;
377
+ if (c_mq_get_busy(mq, out_msg, max_spin) == 0) {
378
+ return 0;
379
+ }
380
+ // After spinning, fallback to blocking with timeout (timeout does not include spin time)
381
+ return c_mq_get_await(mq, out_msg, timeout_seconds);
382
+ }
383
+
384
+ /* Get current occupied count */
385
+ static inline size_t c_mq_occupied(message_queue* mq) {
386
+ if (!mq) return 0;
387
+ pthread_mutex_lock(&mq->mutex);
388
+ size_t n = mq->count;
389
+ pthread_mutex_unlock(&mq->mutex);
390
+ return n;
391
+ }
392
+
393
+ #endif /* C_ENGINE_H */
@@ -0,0 +1,84 @@
1
+ from cpython.datetime cimport datetime
2
+ from libc.stdint cimport uint64_t
3
+
4
+ from cbase.allocator_protocol.c_allocator_protocol cimport allocator_protocol
5
+ from cbase.bytemap.c_bytemap cimport bytemap
6
+
7
+ from .c_event cimport EventHook, evt_message_payload
8
+ from .c_topic cimport Topic, evt_topic
9
+
10
+
11
+ cdef extern from "event_engine/capi/c_engine.h":
12
+ const size_t DEFAULT_MQ_CAPACITY
13
+ const size_t DEFAULT_MQ_SPIN_LIMIT
14
+ const double DEFAULT_MQ_TIMEOUT_SECONDS
15
+
16
+ ctypedef struct pthread_mutex_t:
17
+ pass
18
+
19
+ ctypedef struct pthread_cond_t:
20
+ pass
21
+
22
+ ctypedef struct message_queue:
23
+ size_t capacity
24
+ size_t head
25
+ size_t tail
26
+ size_t count
27
+ evt_topic* topic
28
+ pthread_mutex_t mutex
29
+ pthread_cond_t not_empty
30
+ pthread_cond_t not_full
31
+ evt_message_payload* buf[]
32
+
33
+ message_queue* c_mq_new(size_t capacity, evt_topic* topic, allocator_protocol* allocator) except NULL
34
+ int c_mq_free(message_queue* mq) except -1
35
+ int c_mq_put(message_queue* mq, evt_message_payload* msg) noexcept nogil
36
+ int c_mq_get(message_queue* mq, evt_message_payload** out_msg) noexcept nogil
37
+ int c_mq_put_await(message_queue* mq, evt_message_payload* msg, double timeout_seconds) noexcept nogil
38
+ int c_mq_get_await(message_queue* mq, evt_message_payload** out_msg, double timeout_seconds) noexcept nogil
39
+ int c_mq_put_busy(message_queue* mq, evt_message_payload* msg, size_t max_spin) noexcept nogil
40
+ int c_mq_get_busy(message_queue* mq, evt_message_payload** out_msg, size_t max_spin) noexcept nogil
41
+ int c_mq_put_hybrid(message_queue* mq, evt_message_payload* msg, size_t max_spin, double timeout_seconds) noexcept nogil
42
+ int c_mq_get_hybrid(message_queue* mq, evt_message_payload** out_msg, size_t max_spin, double timeout_seconds) noexcept nogil
43
+ size_t c_mq_occupied(message_queue* mq) noexcept nogil
44
+
45
+
46
+ cdef class EventEngine:
47
+ cdef message_queue* mq
48
+ cdef bytemap* exact_topic_hooks
49
+ cdef bytemap* generic_topic_hooks
50
+
51
+ cdef readonly bint active
52
+ cdef readonly object engine
53
+ cdef public object logger
54
+ cdef readonly uint64_t seq_id
55
+
56
+ cdef inline void c_loop(self)
57
+
58
+ cdef inline evt_message_payload* c_get(self, bint block, size_t max_spin, double timeout)
59
+
60
+ cdef inline int c_publish(self, Topic topic, tuple args, dict kwargs, bint block, size_t max_spin, double timeout)
61
+
62
+ cdef inline void c_trigger(self, evt_message_payload* msg)
63
+
64
+ cdef inline EventHook c_get_hook(self, Topic topic)
65
+
66
+ cdef inline void c_register_hook(self, EventHook hook)
67
+
68
+ cdef inline EventHook c_unregister_hook(self, Topic topic)
69
+
70
+ cdef inline void c_register_handler(self, Topic topic, object py_callable, bint deduplicate)
71
+
72
+ cdef inline void c_unregister_handler(self, Topic topic, object py_callable)
73
+
74
+ cdef inline void c_clear(self)
75
+
76
+
77
+ cdef class EventEngineEx(EventEngine):
78
+ cdef readonly dict timer
79
+
80
+ cdef inline void c_timer_loop(self, double interval, Topic topic, datetime activate_time)
81
+
82
+ cdef inline void c_minute_timer_loop(self, Topic topic)
83
+
84
+ cdef inline void c_second_timer_loop(self, Topic topic)