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) | |
d6bb425c | 27 | (const bt_connection **) |
6945df9a SM |
28 | (bt_connection *temp_conn = NULL) { |
29 | $1 = &temp_conn; | |
30 | } | |
31 | ||
32 | %typemap(argout) | |
d6bb425c | 33 | (const bt_connection **) { |
6945df9a SM |
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) | |
d6bb425c | 48 | (const bt_component_source **) |
6945df9a SM |
49 | (bt_component_source *temp_comp = NULL) { |
50 | $1 = &temp_comp; | |
51 | } | |
52 | ||
53 | %typemap(in, numinputs=0) | |
d6bb425c | 54 | (const bt_component_filter **) |
6945df9a SM |
55 | (bt_component_filter *temp_comp = NULL) { |
56 | $1 = &temp_comp; | |
57 | } | |
58 | ||
59 | %typemap(in, numinputs=0) | |
d6bb425c | 60 | (const bt_component_sink **) |
6945df9a SM |
61 | (bt_component_sink *temp_comp = NULL) { |
62 | $1 = &temp_comp; | |
63 | } | |
64 | ||
d6bb425c | 65 | %typemap(argout) (const bt_component_source **) { |
6945df9a SM |
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 | ||
d6bb425c | 78 | %typemap(argout) (const bt_component_filter **) { |
6945df9a SM |
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 | ||
d6bb425c | 91 | %typemap(argout) (const bt_component_sink **) { |
6945df9a SM |
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 | ||
d6bb425c SM |
104 | %include <babeltrace2/graph/graph-const.h> |
105 | %include <babeltrace2/graph/graph.h> | |
6945df9a SM |
106 | |
107 | /* Helper functions for Python */ | |
108 | ||
109 | %{ | |
d24d5663 PP |
110 | static |
111 | void graph_listener_removed(void *py_callable) | |
6945df9a SM |
112 | { |
113 | BT_ASSERT(py_callable); | |
114 | Py_DECREF(py_callable); | |
115 | } | |
116 | ||
d24d5663 | 117 | static bt_graph_listener_func_status port_added_listener( |
6945df9a SM |
118 | const void *component, |
119 | swig_type_info *component_swig_type, | |
8cc56726 | 120 | bt_component_class_type component_class_type, |
6945df9a SM |
121 | const void *port, |
122 | swig_type_info *port_swig_type, | |
123 | bt_port_type port_type, | |
124 | void *py_callable) | |
125 | { | |
126 | PyObject *py_component_ptr = NULL; | |
127 | PyObject *py_port_ptr = NULL; | |
128 | PyObject *py_res = NULL; | |
d24d5663 | 129 | bt_graph_listener_func_status status; |
6945df9a SM |
130 | |
131 | py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0); | |
132 | if (!py_component_ptr) { | |
133 | BT_LOGF_STR("Failed to create component SWIG pointer object."); | |
d24d5663 | 134 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
6945df9a SM |
135 | goto end; |
136 | } | |
137 | ||
138 | py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0); | |
139 | if (!py_port_ptr) { | |
140 | BT_LOGF_STR("Failed to create port SWIG pointer object."); | |
d24d5663 | 141 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
6945df9a SM |
142 | goto end; |
143 | } | |
144 | ||
145 | py_res = PyObject_CallFunction(py_callable, "(OiOi)", | |
146 | py_component_ptr, component_class_type, py_port_ptr, port_type); | |
147 | if (!py_res) { | |
d24d5663 | 148 | loge_exception(); |
6945df9a | 149 | PyErr_Clear(); |
d24d5663 | 150 | status = __BT_FUNC_STATUS_ERROR; |
5f25509b | 151 | goto end; |
6945df9a | 152 | } |
e874da19 | 153 | |
5f25509b | 154 | BT_ASSERT(py_res == Py_None); |
d24d5663 | 155 | status = __BT_FUNC_STATUS_OK; |
6945df9a SM |
156 | |
157 | end: | |
158 | Py_XDECREF(py_res); | |
159 | Py_XDECREF(py_port_ptr); | |
160 | Py_XDECREF(py_component_ptr); | |
8cc56726 | 161 | return status; |
6945df9a SM |
162 | } |
163 | ||
d24d5663 PP |
164 | static |
165 | bt_graph_listener_func_status | |
6945df9a SM |
166 | source_component_output_port_added_listener(const bt_component_source *component_source, |
167 | const bt_port_output *port_output, void *py_callable) | |
168 | { | |
8cc56726 | 169 | return port_added_listener( |
6945df9a SM |
170 | component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, |
171 | port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable); | |
172 | } | |
173 | ||
d24d5663 PP |
174 | static |
175 | bt_graph_listener_func_status | |
6945df9a SM |
176 | filter_component_input_port_added_listener(const bt_component_filter *component_filter, |
177 | const bt_port_input *port_input, void *py_callable) | |
178 | { | |
8cc56726 | 179 | return port_added_listener( |
6945df9a SM |
180 | component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, |
181 | port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable); | |
182 | } | |
183 | ||
d24d5663 PP |
184 | static |
185 | bt_graph_listener_func_status | |
6945df9a SM |
186 | filter_component_output_port_added_listener(const bt_component_filter *component_filter, |
187 | const bt_port_output *port_output, void *py_callable) | |
188 | { | |
8cc56726 | 189 | return port_added_listener( |
6945df9a SM |
190 | component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, |
191 | port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable); | |
192 | } | |
193 | ||
d24d5663 PP |
194 | static |
195 | bt_graph_listener_func_status | |
6945df9a SM |
196 | sink_component_input_port_added_listener(const bt_component_sink *component_sink, |
197 | const bt_port_input *port_input, void *py_callable) | |
198 | { | |
8cc56726 | 199 | return port_added_listener( |
6945df9a SM |
200 | component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK, |
201 | port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable); | |
202 | } | |
203 | ||
d24d5663 PP |
204 | static |
205 | PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph, | |
206 | PyObject *py_callable) | |
6945df9a SM |
207 | { |
208 | PyObject *py_listener_ids = NULL; | |
209 | PyObject *py_listener_id = NULL; | |
210 | int listener_id; | |
d24d5663 | 211 | bt_graph_add_listener_status status; |
6945df9a SM |
212 | |
213 | BT_ASSERT(graph); | |
214 | BT_ASSERT(py_callable); | |
215 | ||
216 | /* | |
217 | * Behind the scene, we will be registering 4 different listeners and | |
218 | * return all of their ids. | |
219 | */ | |
220 | py_listener_ids = PyTuple_New(4); | |
221 | if (!py_listener_ids) { | |
222 | goto error; | |
223 | } | |
224 | ||
225 | /* source output port */ | |
226 | status = bt_graph_add_source_component_output_port_added_listener( | |
227 | graph, source_component_output_port_added_listener, | |
228 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 229 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
230 | goto error; |
231 | } | |
232 | ||
233 | py_listener_id = PyLong_FromLong(listener_id); | |
234 | if (!py_listener_id) { | |
235 | goto error; | |
236 | } | |
237 | ||
238 | PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id); | |
239 | py_listener_id = NULL; | |
240 | ||
241 | /* filter input port */ | |
242 | status = bt_graph_add_filter_component_input_port_added_listener( | |
243 | graph, filter_component_input_port_added_listener, | |
244 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 245 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
246 | goto error; |
247 | } | |
248 | ||
249 | py_listener_id = PyLong_FromLong(listener_id); | |
250 | if (!py_listener_id) { | |
251 | goto error; | |
252 | } | |
253 | ||
254 | PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id); | |
255 | py_listener_id = NULL; | |
256 | ||
257 | /* filter output port */ | |
258 | status = bt_graph_add_filter_component_output_port_added_listener( | |
259 | graph, filter_component_output_port_added_listener, | |
260 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 261 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
262 | goto error; |
263 | } | |
264 | ||
265 | py_listener_id = PyLong_FromLong(listener_id); | |
266 | if (!py_listener_id) { | |
267 | goto error; | |
268 | } | |
269 | ||
270 | PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id); | |
271 | py_listener_id = NULL; | |
272 | ||
273 | /* sink input port */ | |
274 | status = bt_graph_add_sink_component_input_port_added_listener( | |
275 | graph, sink_component_input_port_added_listener, | |
276 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 277 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
278 | goto error; |
279 | } | |
280 | ||
281 | py_listener_id = PyLong_FromLong(listener_id); | |
282 | if (!py_listener_id) { | |
283 | goto error; | |
284 | } | |
285 | ||
286 | ||
287 | PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id); | |
288 | py_listener_id = NULL; | |
289 | ||
290 | Py_INCREF(py_callable); | |
291 | Py_INCREF(py_callable); | |
292 | Py_INCREF(py_callable); | |
293 | Py_INCREF(py_callable); | |
294 | ||
295 | goto end; | |
296 | ||
297 | error: | |
298 | Py_XDECREF(py_listener_ids); | |
299 | py_listener_ids = Py_None; | |
300 | Py_INCREF(py_listener_ids); | |
301 | ||
302 | end: | |
303 | ||
304 | Py_XDECREF(py_listener_id); | |
305 | return py_listener_ids; | |
306 | } | |
307 | ||
d24d5663 PP |
308 | static |
309 | bt_graph_listener_func_status ports_connected_listener( | |
5f25509b SM |
310 | const void *upstream_component, |
311 | swig_type_info *upstream_component_swig_type, | |
312 | bt_component_class_type upstream_component_class_type, | |
313 | const bt_port_output *upstream_port, | |
314 | const void *downstream_component, | |
315 | swig_type_info *downstream_component_swig_type, | |
316 | bt_component_class_type downstream_component_class_type, | |
317 | const bt_port_input *downstream_port, | |
318 | void *py_callable) | |
6945df9a | 319 | { |
5f25509b | 320 | PyObject *py_upstream_component_ptr = NULL; |
6945df9a | 321 | PyObject *py_upstream_port_ptr = NULL; |
5f25509b | 322 | PyObject *py_downstream_component_ptr = NULL; |
6945df9a SM |
323 | PyObject *py_downstream_port_ptr = NULL; |
324 | PyObject *py_res = NULL; | |
d24d5663 | 325 | bt_graph_listener_func_status status; |
5f25509b SM |
326 | |
327 | py_upstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(upstream_component), | |
328 | upstream_component_swig_type, 0); | |
329 | if (!py_upstream_component_ptr) { | |
330 | BT_LOGF_STR("Failed to create upstream component SWIG pointer object."); | |
d24d5663 | 331 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b SM |
332 | goto end; |
333 | } | |
6945df9a SM |
334 | |
335 | py_upstream_port_ptr = SWIG_NewPointerObj( | |
336 | SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0); | |
337 | if (!py_upstream_port_ptr) { | |
5f25509b | 338 | BT_LOGF_STR("Failed to create upstream port SWIG pointer object."); |
d24d5663 | 339 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b SM |
340 | goto end; |
341 | } | |
e874da19 | 342 | |
5f25509b SM |
343 | py_downstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(downstream_component), |
344 | downstream_component_swig_type, 0); | |
345 | if (!py_downstream_component_ptr) { | |
346 | BT_LOGF_STR("Failed to create downstream component SWIG pointer object."); | |
d24d5663 | 347 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b | 348 | goto end; |
6945df9a SM |
349 | } |
350 | ||
351 | py_downstream_port_ptr = SWIG_NewPointerObj( | |
352 | SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0); | |
353 | if (!py_downstream_port_ptr) { | |
5f25509b | 354 | BT_LOGF_STR("Failed to create downstream port SWIG pointer object."); |
d24d5663 | 355 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b | 356 | goto end; |
6945df9a SM |
357 | } |
358 | ||
5f25509b SM |
359 | py_res = PyObject_CallFunction(py_callable, "(OiOOiO)", |
360 | py_upstream_component_ptr, upstream_component_class_type, | |
361 | py_upstream_port_ptr, | |
362 | py_downstream_component_ptr, downstream_component_class_type, | |
363 | py_downstream_port_ptr); | |
6945df9a | 364 | if (!py_res) { |
d24d5663 | 365 | loge_exception(); |
6945df9a | 366 | PyErr_Clear(); |
d24d5663 | 367 | status = __BT_FUNC_STATUS_ERROR; |
5f25509b | 368 | goto end; |
6945df9a | 369 | } |
e874da19 | 370 | |
5f25509b | 371 | BT_ASSERT(py_res == Py_None); |
d24d5663 | 372 | status = __BT_FUNC_STATUS_OK; |
6945df9a | 373 | |
5f25509b SM |
374 | end: |
375 | Py_XDECREF(py_upstream_component_ptr); | |
376 | Py_XDECREF(py_upstream_port_ptr); | |
377 | Py_XDECREF(py_downstream_component_ptr); | |
378 | Py_XDECREF(py_downstream_port_ptr); | |
6945df9a | 379 | Py_XDECREF(py_res); |
8cc56726 | 380 | return status; |
6945df9a SM |
381 | } |
382 | ||
d24d5663 PP |
383 | static |
384 | bt_graph_listener_func_status source_filter_component_ports_connected_listener( | |
6945df9a SM |
385 | const bt_component_source *source_component, |
386 | const bt_component_filter *filter_component, | |
387 | const bt_port_output *upstream_port, | |
388 | const bt_port_input *downstream_port, void *py_callable) | |
389 | { | |
5f25509b SM |
390 | return ports_connected_listener( |
391 | source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, | |
392 | upstream_port, | |
393 | filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
394 | downstream_port, | |
395 | py_callable); | |
6945df9a SM |
396 | } |
397 | ||
d24d5663 PP |
398 | static |
399 | bt_graph_listener_func_status source_sink_component_ports_connected_listener( | |
6945df9a SM |
400 | const bt_component_source *source_component, |
401 | const bt_component_sink *sink_component, | |
402 | const bt_port_output *upstream_port, | |
403 | const bt_port_input *downstream_port, void *py_callable) | |
404 | { | |
5f25509b SM |
405 | return ports_connected_listener( |
406 | source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, | |
407 | upstream_port, | |
408 | sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK, | |
409 | downstream_port, | |
410 | py_callable); | |
6945df9a SM |
411 | } |
412 | ||
d24d5663 PP |
413 | static |
414 | bt_graph_listener_func_status filter_filter_component_ports_connected_listener( | |
6945df9a SM |
415 | const bt_component_filter *filter_component_left, |
416 | const bt_component_filter *filter_component_right, | |
417 | const bt_port_output *upstream_port, | |
418 | const bt_port_input *downstream_port, void *py_callable) | |
419 | { | |
5f25509b SM |
420 | return ports_connected_listener( |
421 | filter_component_left, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
422 | upstream_port, | |
423 | filter_component_right, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
424 | downstream_port, | |
425 | py_callable); | |
6945df9a SM |
426 | } |
427 | ||
d24d5663 PP |
428 | static |
429 | bt_graph_listener_func_status filter_sink_component_ports_connected_listener( | |
6945df9a SM |
430 | const bt_component_filter *filter_component, |
431 | const bt_component_sink *sink_component, | |
432 | const bt_port_output *upstream_port, | |
433 | const bt_port_input *downstream_port, void *py_callable) | |
434 | { | |
5f25509b SM |
435 | return ports_connected_listener( |
436 | filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
437 | upstream_port, | |
438 | sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK, | |
439 | downstream_port, | |
440 | py_callable); | |
6945df9a SM |
441 | } |
442 | ||
d24d5663 PP |
443 | static |
444 | PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph, | |
445 | PyObject *py_callable) | |
6945df9a SM |
446 | { |
447 | PyObject *py_listener_ids = NULL; | |
448 | PyObject *py_listener_id = NULL; | |
449 | int listener_id; | |
d24d5663 | 450 | bt_graph_add_listener_status status; |
6945df9a SM |
451 | |
452 | BT_ASSERT(graph); | |
453 | BT_ASSERT(py_callable); | |
454 | ||
455 | /* Behind the scene, we will be registering 4 different listeners and | |
456 | * return all of their ids. */ | |
457 | py_listener_ids = PyTuple_New(4); | |
458 | if (!py_listener_ids) { | |
459 | goto error; | |
460 | } | |
461 | ||
462 | /* source -> filter connection */ | |
463 | status = bt_graph_add_source_filter_component_ports_connected_listener( | |
464 | graph, source_filter_component_ports_connected_listener, | |
465 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 466 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
467 | goto error; |
468 | } | |
469 | ||
470 | py_listener_id = PyLong_FromLong(listener_id); | |
471 | if (!py_listener_id) { | |
472 | goto error; | |
473 | } | |
474 | ||
475 | PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id); | |
476 | py_listener_id = NULL; | |
477 | ||
478 | /* source -> sink connection */ | |
479 | status = bt_graph_add_source_sink_component_ports_connected_listener( | |
480 | graph, source_sink_component_ports_connected_listener, | |
481 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 482 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
483 | goto error; |
484 | } | |
485 | ||
486 | py_listener_id = PyLong_FromLong(listener_id); | |
487 | if (!py_listener_id) { | |
488 | goto error; | |
489 | } | |
490 | ||
491 | PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id); | |
492 | py_listener_id = NULL; | |
493 | ||
494 | /* filter -> filter connection */ | |
495 | status = bt_graph_add_filter_filter_component_ports_connected_listener( | |
496 | graph, filter_filter_component_ports_connected_listener, | |
497 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 498 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
499 | goto error; |
500 | } | |
501 | ||
502 | py_listener_id = PyLong_FromLong(listener_id); | |
503 | if (!py_listener_id) { | |
504 | goto error; | |
505 | } | |
506 | ||
507 | PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id); | |
508 | py_listener_id = NULL; | |
509 | ||
510 | /* filter -> sink connection */ | |
511 | status = bt_graph_add_filter_sink_component_ports_connected_listener( | |
512 | graph, filter_sink_component_ports_connected_listener, | |
513 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 514 | if (status != __BT_FUNC_STATUS_OK) { |
6945df9a SM |
515 | goto error; |
516 | } | |
517 | ||
518 | py_listener_id = PyLong_FromLong(listener_id); | |
519 | if (!py_listener_id) { | |
520 | goto error; | |
521 | } | |
522 | ||
523 | PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id); | |
524 | py_listener_id = NULL; | |
525 | ||
526 | Py_INCREF(py_callable); | |
527 | Py_INCREF(py_callable); | |
528 | Py_INCREF(py_callable); | |
529 | Py_INCREF(py_callable); | |
530 | ||
531 | goto end; | |
532 | ||
533 | error: | |
534 | Py_XDECREF(py_listener_ids); | |
535 | py_listener_ids = Py_None; | |
536 | Py_INCREF(py_listener_ids); | |
537 | ||
538 | end: | |
539 | ||
540 | Py_XDECREF(py_listener_id); | |
541 | return py_listener_ids; | |
542 | } | |
6945df9a SM |
543 | %} |
544 | ||
d24d5663 | 545 | PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph, |
6945df9a | 546 | PyObject *py_callable); |
d24d5663 | 547 | PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph, |
6945df9a | 548 | PyObject *py_callable); |