Commit | Line | Data |
---|---|---|
6945df9a SM |
1 | /* |
2 | * The MIT License (MIT) | |
3 | * | |
4 | * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com> | |
5 | * | |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 | * of this software and associated documentation files (the "Software"), to deal | |
8 | * in the Software without restriction, including without limitation the rights | |
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 | * copies of the Software, and to permit persons to whom the Software is | |
11 | * furnished to do so, subject to the following conditions: | |
12 | * | |
13 | * The above copyright notice and this permission notice shall be included in | |
14 | * all copies or substantial portions of the Software. | |
15 | * | |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 | * THE SOFTWARE. | |
23 | */ | |
24 | ||
25 | /* Output argument typemap for connection output (always appends) */ | |
26 | %typemap(in, numinputs=0) | |
27 | (const bt_connection **BTOUTCONN) | |
28 | (bt_connection *temp_conn = NULL) { | |
29 | $1 = &temp_conn; | |
30 | } | |
31 | ||
32 | %typemap(argout) | |
33 | (const bt_connection **BTOUTCONN) { | |
34 | if (*$1) { | |
35 | /* SWIG_Python_AppendOutput() steals the created object */ | |
36 | $result = SWIG_Python_AppendOutput($result, | |
37 | SWIG_NewPointerObj(SWIG_as_voidptr(*$1), | |
38 | SWIGTYPE_p_bt_connection, 0)); | |
39 | } else { | |
40 | /* SWIG_Python_AppendOutput() steals Py_None */ | |
41 | Py_INCREF(Py_None); | |
42 | $result = SWIG_Python_AppendOutput($result, Py_None); | |
43 | } | |
44 | } | |
45 | ||
46 | /* Output argument typemap for component output (always appends) */ | |
47 | %typemap(in, numinputs=0) | |
48 | (const bt_component_source **OUT) | |
49 | (bt_component_source *temp_comp = NULL) { | |
50 | $1 = &temp_comp; | |
51 | } | |
52 | ||
53 | %typemap(in, numinputs=0) | |
54 | (const bt_component_filter **OUT) | |
55 | (bt_component_filter *temp_comp = NULL) { | |
56 | $1 = &temp_comp; | |
57 | } | |
58 | ||
59 | %typemap(in, numinputs=0) | |
60 | (const bt_component_sink **OUT) | |
61 | (bt_component_sink *temp_comp = NULL) { | |
62 | $1 = &temp_comp; | |
63 | } | |
64 | ||
65 | %typemap(argout) (const bt_component_source **OUT) { | |
66 | if (*$1) { | |
67 | /* SWIG_Python_AppendOutput() steals the created object */ | |
68 | $result = SWIG_Python_AppendOutput($result, | |
69 | SWIG_NewPointerObj(SWIG_as_voidptr(*$1), | |
70 | SWIGTYPE_p_bt_component_source, 0)); | |
71 | } else { | |
72 | /* SWIG_Python_AppendOutput() steals Py_None */ | |
73 | Py_INCREF(Py_None); | |
74 | $result = SWIG_Python_AppendOutput($result, Py_None); | |
75 | } | |
76 | } | |
77 | ||
78 | %typemap(argout) (const bt_component_filter **OUT) { | |
79 | if (*$1) { | |
80 | /* SWIG_Python_AppendOutput() steals the created object */ | |
81 | $result = SWIG_Python_AppendOutput($result, | |
82 | SWIG_NewPointerObj(SWIG_as_voidptr(*$1), | |
83 | SWIGTYPE_p_bt_component_filter, 0)); | |
84 | } else { | |
85 | /* SWIG_Python_AppendOutput() steals Py_None */ | |
86 | Py_INCREF(Py_None); | |
87 | $result = SWIG_Python_AppendOutput($result, Py_None); | |
88 | } | |
89 | } | |
90 | ||
91 | %typemap(argout) (const bt_component_sink **OUT) { | |
92 | if (*$1) { | |
93 | /* SWIG_Python_AppendOutput() steals the created object */ | |
94 | $result = SWIG_Python_AppendOutput($result, | |
95 | SWIG_NewPointerObj(SWIG_as_voidptr(*$1), | |
96 | SWIGTYPE_p_bt_component_sink, 0)); | |
97 | } else { | |
98 | /* SWIG_Python_AppendOutput() steals Py_None */ | |
99 | Py_INCREF(Py_None); | |
100 | $result = SWIG_Python_AppendOutput($result, Py_None); | |
101 | } | |
102 | } | |
103 | ||
104 | /* From graph-const.h */ | |
105 | ||
106 | typedef enum bt_graph_status { | |
107 | BT_GRAPH_STATUS_OK = 0, | |
108 | BT_GRAPH_STATUS_END = 1, | |
109 | BT_GRAPH_STATUS_AGAIN = 11, | |
110 | BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION = 111, | |
111 | BT_GRAPH_STATUS_CANCELED = 125, | |
112 | BT_GRAPH_STATUS_ERROR = -1, | |
113 | BT_GRAPH_STATUS_NOMEM = -12, | |
114 | } bt_graph_status; | |
115 | ||
116 | extern bt_bool bt_graph_is_canceled(const bt_graph *graph); | |
117 | ||
118 | extern void bt_graph_get_ref(const bt_graph *graph); | |
119 | ||
120 | extern void bt_graph_put_ref(const bt_graph *graph); | |
121 | ||
122 | /* From graph.h */ | |
123 | ||
124 | typedef void (*bt_graph_filter_component_input_port_added_listener_func)( | |
125 | const bt_component_filter *component, | |
126 | const bt_port_input *port, void *data); | |
127 | ||
128 | typedef void (*bt_graph_sink_component_input_port_added_listener_func)( | |
129 | const bt_component_sink *component, | |
130 | const bt_port_input *port, void *data); | |
131 | ||
132 | typedef void (*bt_graph_source_component_output_port_added_listener_func)( | |
133 | const bt_component_source *component, | |
134 | const bt_port_output *port, void *data); | |
135 | ||
136 | typedef void (*bt_graph_filter_component_output_port_added_listener_func)( | |
137 | const bt_component_filter *component, | |
138 | const bt_port_output *port, void *data); | |
139 | ||
140 | typedef void (*bt_graph_source_filter_component_ports_connected_listener_func)( | |
141 | const bt_component_source *source_component, | |
142 | const bt_component_filter *filter_component, | |
143 | const bt_port_output *upstream_port, | |
144 | const bt_port_input *downstream_port, void *data); | |
145 | ||
146 | typedef void (*bt_graph_source_sink_component_ports_connected_listener_func)( | |
147 | const bt_component_source *source_component, | |
148 | const bt_component_sink *sink_component, | |
149 | const bt_port_output *upstream_port, | |
150 | const bt_port_input *downstream_port, void *data); | |
151 | ||
152 | typedef void (*bt_graph_filter_filter_component_ports_connected_listener_func)( | |
153 | const bt_component_filter *filter_component_upstream, | |
154 | const bt_component_filter *filter_component_downstream, | |
155 | const bt_port_output *upstream_port, | |
156 | const bt_port_input *downstream_port, | |
157 | void *data); | |
158 | ||
159 | typedef void (*bt_graph_filter_sink_component_ports_connected_listener_func)( | |
160 | const bt_component_filter *filter_component, | |
161 | const bt_component_sink *sink_component, | |
162 | const bt_port_output *upstream_port, | |
163 | const bt_port_input *downstream_port, void *data); | |
164 | ||
165 | typedef void (* bt_graph_listener_removed_func)(void *data); | |
166 | ||
167 | extern bt_graph *bt_graph_create(void); | |
168 | ||
169 | extern bt_graph_status bt_graph_add_source_component(bt_graph *graph, | |
170 | const bt_component_class_source *component_class, | |
171 | const char *name, const bt_value *params, | |
172 | const bt_component_source **OUT); | |
173 | ||
174 | extern bt_graph_status bt_graph_add_source_component_with_init_method_data( | |
175 | bt_graph *graph, | |
176 | const bt_component_class_source *component_class, | |
177 | const char *name, const bt_value *params, | |
178 | void *init_method_data, | |
179 | const bt_component_source **OUT); | |
180 | ||
181 | extern bt_graph_status bt_graph_add_filter_component(bt_graph *graph, | |
182 | const bt_component_class_filter *component_class, | |
183 | const char *name, const bt_value *params, | |
184 | const bt_component_filter **OUT); | |
185 | ||
186 | extern bt_graph_status bt_graph_add_filter_component_with_init_method_data( | |
187 | bt_graph *graph, | |
188 | const bt_component_class_filter *component_class, | |
189 | const char *name, const bt_value *params, | |
190 | void *init_method_data, | |
191 | const bt_component_filter **OUT); | |
192 | ||
193 | extern bt_graph_status bt_graph_add_sink_component( | |
194 | bt_graph *graph, const bt_component_class_sink *component_class, | |
195 | const char *name, const bt_value *params, | |
196 | const bt_component_sink **OUT); | |
197 | ||
198 | extern bt_graph_status bt_graph_add_sink_component_with_init_method_data( | |
199 | bt_graph *graph, const bt_component_class_sink *component_class, | |
200 | const char *name, const bt_value *params, | |
201 | void *init_method_data, | |
202 | const bt_component_sink **OUT); | |
203 | ||
204 | extern bt_graph_status bt_graph_connect_ports(bt_graph *graph, | |
205 | const bt_port_output *upstream, | |
206 | const bt_port_input *downstream, | |
207 | const bt_connection **BTOUTCONN); | |
208 | ||
209 | extern bt_graph_status bt_graph_run(bt_graph *graph); | |
210 | ||
211 | extern bt_graph_status bt_graph_consume(bt_graph *graph); | |
212 | ||
213 | extern bt_graph_status bt_graph_add_filter_component_input_port_added_listener( | |
214 | bt_graph *graph, | |
215 | bt_graph_filter_component_input_port_added_listener_func listener, | |
216 | bt_graph_listener_removed_func listener_removed, void *data, | |
217 | int *listener_id); | |
218 | ||
219 | extern bt_graph_status bt_graph_add_sink_component_input_port_added_listener( | |
220 | bt_graph *graph, | |
221 | bt_graph_sink_component_input_port_added_listener_func listener, | |
222 | bt_graph_listener_removed_func listener_removed, void *data, | |
223 | int *listener_id); | |
224 | ||
225 | extern bt_graph_status bt_graph_add_source_component_output_port_added_listener( | |
226 | bt_graph *graph, | |
227 | bt_graph_source_component_output_port_added_listener_func listener, | |
228 | bt_graph_listener_removed_func listener_removed, void *data, | |
229 | int *listener_id); | |
230 | ||
231 | extern bt_graph_status bt_graph_add_filter_component_output_port_added_listener( | |
232 | bt_graph *graph, | |
233 | bt_graph_filter_component_output_port_added_listener_func listener, | |
234 | bt_graph_listener_removed_func listener_removed, void *data, | |
235 | int *listener_id); | |
236 | ||
237 | extern bt_graph_status | |
238 | bt_graph_add_source_filter_component_ports_connected_listener( | |
239 | bt_graph *graph, | |
240 | bt_graph_source_filter_component_ports_connected_listener_func listener, | |
241 | bt_graph_listener_removed_func listener_removed, void *data, | |
242 | int *listener_id); | |
243 | ||
244 | extern bt_graph_status | |
245 | bt_graph_add_filter_filter_component_ports_connected_listener( | |
246 | bt_graph *graph, | |
247 | bt_graph_filter_filter_component_ports_connected_listener_func listener, | |
248 | bt_graph_listener_removed_func listener_removed, void *data, | |
249 | int *listener_id); | |
250 | ||
251 | extern bt_graph_status | |
252 | bt_graph_add_source_sink_component_ports_connected_listener( | |
253 | bt_graph *graph, | |
254 | bt_graph_source_sink_component_ports_connected_listener_func listener, | |
255 | bt_graph_listener_removed_func listener_removed, void *data, | |
256 | int *listener_id); | |
257 | ||
258 | extern bt_graph_status | |
259 | bt_graph_add_filter_sink_component_ports_connected_listener( | |
260 | bt_graph *graph, | |
261 | bt_graph_filter_sink_component_ports_connected_listener_func listener, | |
262 | bt_graph_listener_removed_func listener_removed, void *data, | |
263 | int *listener_id); | |
264 | ||
265 | extern bt_graph_status bt_graph_cancel(bt_graph *graph); | |
266 | ||
267 | /* Helper functions for Python */ | |
268 | ||
269 | %{ | |
270 | ||
271 | static void graph_listener_removed(void *py_callable) | |
272 | { | |
273 | BT_ASSERT(py_callable); | |
274 | Py_DECREF(py_callable); | |
275 | } | |
276 | ||
277 | static void | |
278 | port_added_listener( | |
279 | const void *component, | |
280 | swig_type_info *component_swig_type, | |
281 | bt_component_class_type component_class_type, | |
282 | const void *port, | |
283 | swig_type_info *port_swig_type, | |
284 | bt_port_type port_type, | |
285 | void *py_callable) | |
286 | { | |
287 | PyObject *py_component_ptr = NULL; | |
288 | PyObject *py_port_ptr = NULL; | |
289 | PyObject *py_res = NULL; | |
290 | ||
291 | py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0); | |
292 | if (!py_component_ptr) { | |
293 | BT_LOGF_STR("Failed to create component SWIG pointer object."); | |
294 | goto end; | |
295 | } | |
296 | ||
297 | py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0); | |
298 | if (!py_port_ptr) { | |
299 | BT_LOGF_STR("Failed to create port SWIG pointer object."); | |
300 | goto end; | |
301 | } | |
302 | ||
303 | py_res = PyObject_CallFunction(py_callable, "(OiOi)", | |
304 | py_component_ptr, component_class_type, py_port_ptr, port_type); | |
305 | if (!py_res) { | |
306 | bt2_py_loge_exception(); | |
307 | PyErr_Clear(); | |
308 | } else { | |
309 | BT_ASSERT(py_res == Py_None); | |
310 | } | |
311 | ||
312 | end: | |
313 | Py_XDECREF(py_res); | |
314 | Py_XDECREF(py_port_ptr); | |
315 | Py_XDECREF(py_component_ptr); | |
316 | } | |
317 | ||
318 | static void | |
319 | source_component_output_port_added_listener(const bt_component_source *component_source, | |
320 | const bt_port_output *port_output, void *py_callable) | |
321 | { | |
322 | port_added_listener( | |
323 | component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, | |
324 | port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable); | |
325 | } | |
326 | ||
327 | static void | |
328 | filter_component_input_port_added_listener(const bt_component_filter *component_filter, | |
329 | const bt_port_input *port_input, void *py_callable) | |
330 | { | |
331 | port_added_listener( | |
332 | component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
333 | port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable); | |
334 | } | |
335 | ||
336 | static void | |
337 | filter_component_output_port_added_listener(const bt_component_filter *component_filter, | |
338 | const bt_port_output *port_output, void *py_callable) | |
339 | { | |
340 | port_added_listener( | |
341 | component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
342 | port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable); | |
343 | } | |
344 | ||
345 | static void | |
346 | sink_component_input_port_added_listener(const bt_component_sink *component_sink, | |
347 | const bt_port_input *port_input, void *py_callable) | |
348 | { | |
349 | port_added_listener( | |
350 | component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK, | |
351 | port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable); | |
352 | } | |
353 | ||
354 | static PyObject * | |
355 | bt_py3_graph_add_port_added_listener(struct bt_graph *graph, | |
356 | PyObject *py_callable) | |
357 | { | |
358 | PyObject *py_listener_ids = NULL; | |
359 | PyObject *py_listener_id = NULL; | |
360 | int listener_id; | |
361 | bt_graph_status status; | |
362 | ||
363 | BT_ASSERT(graph); | |
364 | BT_ASSERT(py_callable); | |
365 | ||
366 | /* | |
367 | * Behind the scene, we will be registering 4 different listeners and | |
368 | * return all of their ids. | |
369 | */ | |
370 | py_listener_ids = PyTuple_New(4); | |
371 | if (!py_listener_ids) { | |
372 | goto error; | |
373 | } | |
374 | ||
375 | /* source output port */ | |
376 | status = bt_graph_add_source_component_output_port_added_listener( | |
377 | graph, source_component_output_port_added_listener, | |
378 | graph_listener_removed, py_callable, &listener_id); | |
379 | if (status != BT_GRAPH_STATUS_OK) { | |
380 | goto error; | |
381 | } | |
382 | ||
383 | py_listener_id = PyLong_FromLong(listener_id); | |
384 | if (!py_listener_id) { | |
385 | goto error; | |
386 | } | |
387 | ||
388 | PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id); | |
389 | py_listener_id = NULL; | |
390 | ||
391 | /* filter input port */ | |
392 | status = bt_graph_add_filter_component_input_port_added_listener( | |
393 | graph, filter_component_input_port_added_listener, | |
394 | graph_listener_removed, py_callable, &listener_id); | |
395 | if (status != BT_GRAPH_STATUS_OK) { | |
396 | goto error; | |
397 | } | |
398 | ||
399 | py_listener_id = PyLong_FromLong(listener_id); | |
400 | if (!py_listener_id) { | |
401 | goto error; | |
402 | } | |
403 | ||
404 | PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id); | |
405 | py_listener_id = NULL; | |
406 | ||
407 | /* filter output port */ | |
408 | status = bt_graph_add_filter_component_output_port_added_listener( | |
409 | graph, filter_component_output_port_added_listener, | |
410 | graph_listener_removed, py_callable, &listener_id); | |
411 | if (status != BT_GRAPH_STATUS_OK) { | |
412 | goto error; | |
413 | } | |
414 | ||
415 | py_listener_id = PyLong_FromLong(listener_id); | |
416 | if (!py_listener_id) { | |
417 | goto error; | |
418 | } | |
419 | ||
420 | PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id); | |
421 | py_listener_id = NULL; | |
422 | ||
423 | /* sink input port */ | |
424 | status = bt_graph_add_sink_component_input_port_added_listener( | |
425 | graph, sink_component_input_port_added_listener, | |
426 | graph_listener_removed, py_callable, &listener_id); | |
427 | if (status != BT_GRAPH_STATUS_OK) { | |
428 | goto error; | |
429 | } | |
430 | ||
431 | py_listener_id = PyLong_FromLong(listener_id); | |
432 | if (!py_listener_id) { | |
433 | goto error; | |
434 | } | |
435 | ||
436 | ||
437 | PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id); | |
438 | py_listener_id = NULL; | |
439 | ||
440 | Py_INCREF(py_callable); | |
441 | Py_INCREF(py_callable); | |
442 | Py_INCREF(py_callable); | |
443 | Py_INCREF(py_callable); | |
444 | ||
445 | goto end; | |
446 | ||
447 | error: | |
448 | Py_XDECREF(py_listener_ids); | |
449 | py_listener_ids = Py_None; | |
450 | Py_INCREF(py_listener_ids); | |
451 | ||
452 | end: | |
453 | ||
454 | Py_XDECREF(py_listener_id); | |
455 | return py_listener_ids; | |
456 | } | |
457 | ||
458 | static void | |
459 | ports_connected_listener(const bt_port_output *upstream_port, | |
460 | const bt_port_input *downstream_port, | |
461 | void *py_callable) | |
462 | { | |
463 | PyObject *py_upstream_port_ptr = NULL; | |
464 | PyObject *py_downstream_port_ptr = NULL; | |
465 | PyObject *py_res = NULL; | |
466 | ||
467 | py_upstream_port_ptr = SWIG_NewPointerObj( | |
468 | SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0); | |
469 | if (!py_upstream_port_ptr) { | |
470 | BT_LOGF_STR("Failed to create a SWIG pointer object."); | |
471 | abort(); | |
472 | } | |
473 | ||
474 | py_downstream_port_ptr = SWIG_NewPointerObj( | |
475 | SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0); | |
476 | if (!py_downstream_port_ptr) { | |
477 | BT_LOGF_STR("Failed to create a SWIG pointer object."); | |
478 | abort(); | |
479 | } | |
480 | ||
481 | py_res = PyObject_CallFunction(py_callable, "(OO)", | |
482 | py_upstream_port_ptr, py_downstream_port_ptr); | |
483 | if (!py_res) { | |
484 | bt2_py_loge_exception(); | |
485 | PyErr_Clear(); | |
486 | } else { | |
487 | BT_ASSERT(py_res == Py_None); | |
488 | } | |
489 | ||
490 | Py_DECREF(py_upstream_port_ptr); | |
491 | Py_DECREF(py_downstream_port_ptr); | |
492 | Py_XDECREF(py_res); | |
493 | } | |
494 | ||
495 | static void | |
496 | source_filter_component_ports_connected_listener( | |
497 | const bt_component_source *source_component, | |
498 | const bt_component_filter *filter_component, | |
499 | const bt_port_output *upstream_port, | |
500 | const bt_port_input *downstream_port, void *py_callable) | |
501 | { | |
502 | ports_connected_listener(upstream_port, downstream_port, py_callable); | |
503 | } | |
504 | ||
505 | static void | |
506 | source_sink_component_ports_connected_listener( | |
507 | const bt_component_source *source_component, | |
508 | const bt_component_sink *sink_component, | |
509 | const bt_port_output *upstream_port, | |
510 | const bt_port_input *downstream_port, void *py_callable) | |
511 | { | |
512 | ports_connected_listener(upstream_port, downstream_port, py_callable); | |
513 | } | |
514 | ||
515 | static void | |
516 | filter_filter_component_ports_connected_listener( | |
517 | const bt_component_filter *filter_component_left, | |
518 | const bt_component_filter *filter_component_right, | |
519 | const bt_port_output *upstream_port, | |
520 | const bt_port_input *downstream_port, void *py_callable) | |
521 | { | |
522 | ports_connected_listener(upstream_port, downstream_port, py_callable); | |
523 | } | |
524 | ||
525 | static void | |
526 | filter_sink_component_ports_connected_listener( | |
527 | const bt_component_filter *filter_component, | |
528 | const bt_component_sink *sink_component, | |
529 | const bt_port_output *upstream_port, | |
530 | const bt_port_input *downstream_port, void *py_callable) | |
531 | { | |
532 | ports_connected_listener(upstream_port, downstream_port, py_callable); | |
533 | } | |
534 | ||
535 | ||
536 | static PyObject* | |
537 | bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph, | |
538 | PyObject *py_callable) | |
539 | { | |
540 | PyObject *py_listener_ids = NULL; | |
541 | PyObject *py_listener_id = NULL; | |
542 | int listener_id; | |
543 | bt_graph_status status; | |
544 | ||
545 | BT_ASSERT(graph); | |
546 | BT_ASSERT(py_callable); | |
547 | ||
548 | /* Behind the scene, we will be registering 4 different listeners and | |
549 | * return all of their ids. */ | |
550 | py_listener_ids = PyTuple_New(4); | |
551 | if (!py_listener_ids) { | |
552 | goto error; | |
553 | } | |
554 | ||
555 | /* source -> filter connection */ | |
556 | status = bt_graph_add_source_filter_component_ports_connected_listener( | |
557 | graph, source_filter_component_ports_connected_listener, | |
558 | graph_listener_removed, py_callable, &listener_id); | |
559 | if (status != BT_GRAPH_STATUS_OK) { | |
560 | goto error; | |
561 | } | |
562 | ||
563 | py_listener_id = PyLong_FromLong(listener_id); | |
564 | if (!py_listener_id) { | |
565 | goto error; | |
566 | } | |
567 | ||
568 | PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id); | |
569 | py_listener_id = NULL; | |
570 | ||
571 | /* source -> sink connection */ | |
572 | status = bt_graph_add_source_sink_component_ports_connected_listener( | |
573 | graph, source_sink_component_ports_connected_listener, | |
574 | graph_listener_removed, py_callable, &listener_id); | |
575 | if (status != BT_GRAPH_STATUS_OK) { | |
576 | goto error; | |
577 | } | |
578 | ||
579 | py_listener_id = PyLong_FromLong(listener_id); | |
580 | if (!py_listener_id) { | |
581 | goto error; | |
582 | } | |
583 | ||
584 | PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id); | |
585 | py_listener_id = NULL; | |
586 | ||
587 | /* filter -> filter connection */ | |
588 | status = bt_graph_add_filter_filter_component_ports_connected_listener( | |
589 | graph, filter_filter_component_ports_connected_listener, | |
590 | graph_listener_removed, py_callable, &listener_id); | |
591 | if (status != BT_GRAPH_STATUS_OK) { | |
592 | goto error; | |
593 | } | |
594 | ||
595 | py_listener_id = PyLong_FromLong(listener_id); | |
596 | if (!py_listener_id) { | |
597 | goto error; | |
598 | } | |
599 | ||
600 | PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id); | |
601 | py_listener_id = NULL; | |
602 | ||
603 | /* filter -> sink connection */ | |
604 | status = bt_graph_add_filter_sink_component_ports_connected_listener( | |
605 | graph, filter_sink_component_ports_connected_listener, | |
606 | graph_listener_removed, py_callable, &listener_id); | |
607 | if (status != BT_GRAPH_STATUS_OK) { | |
608 | goto error; | |
609 | } | |
610 | ||
611 | py_listener_id = PyLong_FromLong(listener_id); | |
612 | if (!py_listener_id) { | |
613 | goto error; | |
614 | } | |
615 | ||
616 | PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id); | |
617 | py_listener_id = NULL; | |
618 | ||
619 | Py_INCREF(py_callable); | |
620 | Py_INCREF(py_callable); | |
621 | Py_INCREF(py_callable); | |
622 | Py_INCREF(py_callable); | |
623 | ||
624 | goto end; | |
625 | ||
626 | error: | |
627 | Py_XDECREF(py_listener_ids); | |
628 | py_listener_ids = Py_None; | |
629 | Py_INCREF(py_listener_ids); | |
630 | ||
631 | end: | |
632 | ||
633 | Py_XDECREF(py_listener_id); | |
634 | return py_listener_ids; | |
635 | } | |
636 | ||
637 | %} | |
638 | ||
639 | PyObject *bt_py3_graph_add_port_added_listener(struct bt_graph *graph, | |
640 | PyObject *py_callable); | |
641 | PyObject *bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph, | |
642 | PyObject *py_callable); |