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