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) { | |
12cd4490 PP |
148 | loge_exception("Graph's port added listener (Python)", |
149 | BT_LOG_OUTPUT_LEVEL); | |
6945df9a | 150 | PyErr_Clear(); |
d24d5663 | 151 | status = __BT_FUNC_STATUS_ERROR; |
5f25509b | 152 | goto end; |
6945df9a | 153 | } |
e874da19 | 154 | |
5f25509b | 155 | BT_ASSERT(py_res == Py_None); |
d24d5663 | 156 | status = __BT_FUNC_STATUS_OK; |
6945df9a SM |
157 | |
158 | end: | |
159 | Py_XDECREF(py_res); | |
160 | Py_XDECREF(py_port_ptr); | |
161 | Py_XDECREF(py_component_ptr); | |
8cc56726 | 162 | return status; |
6945df9a SM |
163 | } |
164 | ||
d24d5663 PP |
165 | static |
166 | bt_graph_listener_func_status | |
6945df9a SM |
167 | source_component_output_port_added_listener(const bt_component_source *component_source, |
168 | const bt_port_output *port_output, void *py_callable) | |
169 | { | |
8cc56726 | 170 | return port_added_listener( |
6945df9a SM |
171 | component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, |
172 | port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable); | |
173 | } | |
174 | ||
d24d5663 PP |
175 | static |
176 | bt_graph_listener_func_status | |
6945df9a SM |
177 | filter_component_input_port_added_listener(const bt_component_filter *component_filter, |
178 | const bt_port_input *port_input, void *py_callable) | |
179 | { | |
8cc56726 | 180 | return port_added_listener( |
6945df9a SM |
181 | component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, |
182 | port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable); | |
183 | } | |
184 | ||
d24d5663 PP |
185 | static |
186 | bt_graph_listener_func_status | |
6945df9a SM |
187 | filter_component_output_port_added_listener(const bt_component_filter *component_filter, |
188 | const bt_port_output *port_output, void *py_callable) | |
189 | { | |
8cc56726 | 190 | return port_added_listener( |
6945df9a SM |
191 | component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, |
192 | port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable); | |
193 | } | |
194 | ||
d24d5663 PP |
195 | static |
196 | bt_graph_listener_func_status | |
6945df9a SM |
197 | sink_component_input_port_added_listener(const bt_component_sink *component_sink, |
198 | const bt_port_input *port_input, void *py_callable) | |
199 | { | |
8cc56726 | 200 | return port_added_listener( |
6945df9a SM |
201 | component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK, |
202 | port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable); | |
203 | } | |
204 | ||
d24d5663 PP |
205 | static |
206 | PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph, | |
207 | PyObject *py_callable) | |
6945df9a SM |
208 | { |
209 | PyObject *py_listener_ids = NULL; | |
210 | PyObject *py_listener_id = NULL; | |
2054a0d1 | 211 | bt_listener_id listener_id; |
d24d5663 | 212 | bt_graph_add_listener_status status; |
416379bc SM |
213 | const char * const module_name = |
214 | "graph_add_port_added_listener() (Python)"; | |
6945df9a SM |
215 | |
216 | BT_ASSERT(graph); | |
217 | BT_ASSERT(py_callable); | |
218 | ||
219 | /* | |
220 | * Behind the scene, we will be registering 4 different listeners and | |
221 | * return all of their ids. | |
222 | */ | |
223 | py_listener_ids = PyTuple_New(4); | |
224 | if (!py_listener_ids) { | |
416379bc SM |
225 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
226 | "Failed to allocate one PyTuple."); | |
6945df9a SM |
227 | goto error; |
228 | } | |
229 | ||
230 | /* source output port */ | |
231 | status = bt_graph_add_source_component_output_port_added_listener( | |
232 | graph, source_component_output_port_added_listener, | |
233 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 234 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
235 | /* |
236 | * bt_graph_add_source_component_output_port_added_listener has | |
237 | * already logged/appended an error cause. | |
238 | */ | |
6945df9a SM |
239 | goto error; |
240 | } | |
241 | ||
2054a0d1 | 242 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 243 | if (!py_listener_id) { |
416379bc SM |
244 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
245 | "Failed to allocate one PyLong."); | |
6945df9a SM |
246 | goto error; |
247 | } | |
248 | ||
249 | PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id); | |
250 | py_listener_id = NULL; | |
251 | ||
252 | /* filter input port */ | |
253 | status = bt_graph_add_filter_component_input_port_added_listener( | |
254 | graph, filter_component_input_port_added_listener, | |
255 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 256 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
257 | /* |
258 | * bt_graph_add_filter_component_input_port_added_listener has | |
259 | * already logged/appended an error cause. | |
260 | */ | |
6945df9a SM |
261 | goto error; |
262 | } | |
263 | ||
2054a0d1 | 264 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 265 | if (!py_listener_id) { |
416379bc SM |
266 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
267 | "Failed to allocate one PyLong."); | |
6945df9a SM |
268 | goto error; |
269 | } | |
270 | ||
271 | PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id); | |
272 | py_listener_id = NULL; | |
273 | ||
274 | /* filter output port */ | |
275 | status = bt_graph_add_filter_component_output_port_added_listener( | |
276 | graph, filter_component_output_port_added_listener, | |
277 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 278 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
279 | /* |
280 | * bt_graph_add_filter_component_output_port_added_listener has | |
281 | * already logged/appended an error cause. | |
282 | */ | |
6945df9a SM |
283 | goto error; |
284 | } | |
285 | ||
2054a0d1 | 286 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 287 | if (!py_listener_id) { |
416379bc SM |
288 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
289 | "Failed to allocate one PyLong."); | |
6945df9a SM |
290 | goto error; |
291 | } | |
292 | ||
293 | PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id); | |
294 | py_listener_id = NULL; | |
295 | ||
296 | /* sink input port */ | |
297 | status = bt_graph_add_sink_component_input_port_added_listener( | |
298 | graph, sink_component_input_port_added_listener, | |
299 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 300 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
301 | /* |
302 | * bt_graph_add_sink_component_input_port_added_listener has | |
303 | * already logged/appended an error cause. | |
304 | */ | |
6945df9a SM |
305 | goto error; |
306 | } | |
307 | ||
2054a0d1 | 308 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 309 | if (!py_listener_id) { |
416379bc SM |
310 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
311 | "Failed to allocate one PyLong."); | |
6945df9a SM |
312 | goto error; |
313 | } | |
314 | ||
315 | ||
316 | PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id); | |
317 | py_listener_id = NULL; | |
318 | ||
319 | Py_INCREF(py_callable); | |
320 | Py_INCREF(py_callable); | |
321 | Py_INCREF(py_callable); | |
322 | Py_INCREF(py_callable); | |
323 | ||
324 | goto end; | |
325 | ||
326 | error: | |
327 | Py_XDECREF(py_listener_ids); | |
328 | py_listener_ids = Py_None; | |
329 | Py_INCREF(py_listener_ids); | |
330 | ||
331 | end: | |
332 | ||
333 | Py_XDECREF(py_listener_id); | |
334 | return py_listener_ids; | |
335 | } | |
336 | ||
d24d5663 PP |
337 | static |
338 | bt_graph_listener_func_status ports_connected_listener( | |
5f25509b SM |
339 | const void *upstream_component, |
340 | swig_type_info *upstream_component_swig_type, | |
341 | bt_component_class_type upstream_component_class_type, | |
342 | const bt_port_output *upstream_port, | |
343 | const void *downstream_component, | |
344 | swig_type_info *downstream_component_swig_type, | |
345 | bt_component_class_type downstream_component_class_type, | |
346 | const bt_port_input *downstream_port, | |
347 | void *py_callable) | |
6945df9a | 348 | { |
5f25509b | 349 | PyObject *py_upstream_component_ptr = NULL; |
6945df9a | 350 | PyObject *py_upstream_port_ptr = NULL; |
5f25509b | 351 | PyObject *py_downstream_component_ptr = NULL; |
6945df9a SM |
352 | PyObject *py_downstream_port_ptr = NULL; |
353 | PyObject *py_res = NULL; | |
d24d5663 | 354 | bt_graph_listener_func_status status; |
5f25509b SM |
355 | |
356 | py_upstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(upstream_component), | |
357 | upstream_component_swig_type, 0); | |
358 | if (!py_upstream_component_ptr) { | |
359 | BT_LOGF_STR("Failed to create upstream component SWIG pointer object."); | |
d24d5663 | 360 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b SM |
361 | goto end; |
362 | } | |
6945df9a SM |
363 | |
364 | py_upstream_port_ptr = SWIG_NewPointerObj( | |
365 | SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0); | |
366 | if (!py_upstream_port_ptr) { | |
5f25509b | 367 | BT_LOGF_STR("Failed to create upstream port SWIG pointer object."); |
d24d5663 | 368 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b SM |
369 | goto end; |
370 | } | |
e874da19 | 371 | |
5f25509b SM |
372 | py_downstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(downstream_component), |
373 | downstream_component_swig_type, 0); | |
374 | if (!py_downstream_component_ptr) { | |
375 | BT_LOGF_STR("Failed to create downstream component SWIG pointer object."); | |
d24d5663 | 376 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b | 377 | goto end; |
6945df9a SM |
378 | } |
379 | ||
380 | py_downstream_port_ptr = SWIG_NewPointerObj( | |
381 | SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0); | |
382 | if (!py_downstream_port_ptr) { | |
5f25509b | 383 | BT_LOGF_STR("Failed to create downstream port SWIG pointer object."); |
d24d5663 | 384 | status = __BT_FUNC_STATUS_MEMORY_ERROR; |
5f25509b | 385 | goto end; |
6945df9a SM |
386 | } |
387 | ||
5f25509b SM |
388 | py_res = PyObject_CallFunction(py_callable, "(OiOOiO)", |
389 | py_upstream_component_ptr, upstream_component_class_type, | |
390 | py_upstream_port_ptr, | |
391 | py_downstream_component_ptr, downstream_component_class_type, | |
392 | py_downstream_port_ptr); | |
6945df9a | 393 | if (!py_res) { |
12cd4490 PP |
394 | loge_exception("Graph's port connected listener (Python)", |
395 | BT_LOG_OUTPUT_LEVEL); | |
6945df9a | 396 | PyErr_Clear(); |
d24d5663 | 397 | status = __BT_FUNC_STATUS_ERROR; |
5f25509b | 398 | goto end; |
6945df9a | 399 | } |
e874da19 | 400 | |
5f25509b | 401 | BT_ASSERT(py_res == Py_None); |
d24d5663 | 402 | status = __BT_FUNC_STATUS_OK; |
6945df9a | 403 | |
5f25509b SM |
404 | end: |
405 | Py_XDECREF(py_upstream_component_ptr); | |
406 | Py_XDECREF(py_upstream_port_ptr); | |
407 | Py_XDECREF(py_downstream_component_ptr); | |
408 | Py_XDECREF(py_downstream_port_ptr); | |
6945df9a | 409 | Py_XDECREF(py_res); |
8cc56726 | 410 | return status; |
6945df9a SM |
411 | } |
412 | ||
d24d5663 PP |
413 | static |
414 | bt_graph_listener_func_status source_filter_component_ports_connected_listener( | |
6945df9a SM |
415 | const bt_component_source *source_component, |
416 | const bt_component_filter *filter_component, | |
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 | source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, | |
422 | upstream_port, | |
423 | filter_component, 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 source_sink_component_ports_connected_listener( | |
6945df9a SM |
430 | const bt_component_source *source_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 | source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE, | |
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 | bt_graph_listener_func_status filter_filter_component_ports_connected_listener( | |
6945df9a SM |
445 | const bt_component_filter *filter_component_left, |
446 | const bt_component_filter *filter_component_right, | |
447 | const bt_port_output *upstream_port, | |
448 | const bt_port_input *downstream_port, void *py_callable) | |
449 | { | |
5f25509b SM |
450 | return ports_connected_listener( |
451 | filter_component_left, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
452 | upstream_port, | |
453 | filter_component_right, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
454 | downstream_port, | |
455 | py_callable); | |
6945df9a SM |
456 | } |
457 | ||
d24d5663 PP |
458 | static |
459 | bt_graph_listener_func_status filter_sink_component_ports_connected_listener( | |
6945df9a SM |
460 | const bt_component_filter *filter_component, |
461 | const bt_component_sink *sink_component, | |
462 | const bt_port_output *upstream_port, | |
463 | const bt_port_input *downstream_port, void *py_callable) | |
464 | { | |
5f25509b SM |
465 | return ports_connected_listener( |
466 | filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER, | |
467 | upstream_port, | |
468 | sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK, | |
469 | downstream_port, | |
470 | py_callable); | |
6945df9a SM |
471 | } |
472 | ||
d24d5663 PP |
473 | static |
474 | PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph, | |
475 | PyObject *py_callable) | |
6945df9a SM |
476 | { |
477 | PyObject *py_listener_ids = NULL; | |
478 | PyObject *py_listener_id = NULL; | |
2054a0d1 | 479 | bt_listener_id listener_id; |
d24d5663 | 480 | bt_graph_add_listener_status status; |
416379bc SM |
481 | const char * const module_name = |
482 | "graph_add_ports_connected_listener() (Python)"; | |
6945df9a SM |
483 | |
484 | BT_ASSERT(graph); | |
485 | BT_ASSERT(py_callable); | |
486 | ||
487 | /* Behind the scene, we will be registering 4 different listeners and | |
488 | * return all of their ids. */ | |
489 | py_listener_ids = PyTuple_New(4); | |
490 | if (!py_listener_ids) { | |
416379bc SM |
491 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
492 | "Failed to allocate one PyTuple."); | |
6945df9a SM |
493 | goto error; |
494 | } | |
495 | ||
496 | /* source -> filter connection */ | |
497 | status = bt_graph_add_source_filter_component_ports_connected_listener( | |
498 | graph, source_filter_component_ports_connected_listener, | |
499 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 500 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
501 | /* |
502 | * bt_graph_add_source_filter_component_ports_connected_listener | |
503 | * has already logged/appended an error cause. | |
504 | */ | |
6945df9a SM |
505 | goto error; |
506 | } | |
507 | ||
2054a0d1 | 508 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 509 | if (!py_listener_id) { |
416379bc SM |
510 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
511 | "Failed to allocate one PyLong."); | |
6945df9a SM |
512 | goto error; |
513 | } | |
514 | ||
515 | PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id); | |
516 | py_listener_id = NULL; | |
517 | ||
518 | /* source -> sink connection */ | |
519 | status = bt_graph_add_source_sink_component_ports_connected_listener( | |
520 | graph, source_sink_component_ports_connected_listener, | |
521 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 522 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
523 | /* |
524 | * bt_graph_add_source_sink_component_ports_connected_listener | |
525 | * has already logged/appended an error cause. | |
526 | */ | |
6945df9a SM |
527 | goto error; |
528 | } | |
529 | ||
2054a0d1 | 530 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 531 | if (!py_listener_id) { |
416379bc SM |
532 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
533 | "Failed to allocate one PyLong."); | |
6945df9a SM |
534 | goto error; |
535 | } | |
536 | ||
537 | PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id); | |
538 | py_listener_id = NULL; | |
539 | ||
540 | /* filter -> filter connection */ | |
541 | status = bt_graph_add_filter_filter_component_ports_connected_listener( | |
542 | graph, filter_filter_component_ports_connected_listener, | |
543 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 544 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
545 | /* |
546 | * bt_graph_add_filter_filter_component_ports_connected_listener | |
547 | * has already logged/appended an error cause. | |
548 | */ | |
6945df9a SM |
549 | goto error; |
550 | } | |
551 | ||
2054a0d1 | 552 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 553 | if (!py_listener_id) { |
416379bc SM |
554 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
555 | "Failed to allocate one PyLong."); | |
6945df9a SM |
556 | goto error; |
557 | } | |
558 | ||
559 | PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id); | |
560 | py_listener_id = NULL; | |
561 | ||
562 | /* filter -> sink connection */ | |
563 | status = bt_graph_add_filter_sink_component_ports_connected_listener( | |
564 | graph, filter_sink_component_ports_connected_listener, | |
565 | graph_listener_removed, py_callable, &listener_id); | |
d24d5663 | 566 | if (status != __BT_FUNC_STATUS_OK) { |
416379bc SM |
567 | /* |
568 | * bt_graph_add_filter_sink_component_ports_connected_listener | |
569 | * has already logged/appended an error cause. | |
570 | */ | |
6945df9a SM |
571 | goto error; |
572 | } | |
573 | ||
2054a0d1 | 574 | py_listener_id = PyLong_FromUnsignedLongLong(listener_id); |
6945df9a | 575 | if (!py_listener_id) { |
416379bc SM |
576 | BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name, |
577 | "Failed to allocate one PyLong."); | |
6945df9a SM |
578 | goto error; |
579 | } | |
580 | ||
581 | PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id); | |
582 | py_listener_id = NULL; | |
583 | ||
584 | Py_INCREF(py_callable); | |
585 | Py_INCREF(py_callable); | |
586 | Py_INCREF(py_callable); | |
587 | Py_INCREF(py_callable); | |
588 | ||
589 | goto end; | |
590 | ||
591 | error: | |
592 | Py_XDECREF(py_listener_ids); | |
593 | py_listener_ids = Py_None; | |
594 | Py_INCREF(py_listener_ids); | |
595 | ||
596 | end: | |
597 | ||
598 | Py_XDECREF(py_listener_id); | |
599 | return py_listener_ids; | |
600 | } | |
6945df9a SM |
601 | %} |
602 | ||
d24d5663 | 603 | PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph, |
6945df9a | 604 | PyObject *py_callable); |
d24d5663 | 605 | PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph, |
6945df9a | 606 | PyObject *py_callable); |