2 * The MIT License (MIT)
4 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
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) {
33 (const bt_connection **BTOUTCONN) {
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));
40 /* SWIG_Python_AppendOutput() steals Py_None */
42 $result = SWIG_Python_AppendOutput($result, Py_None);
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) {
53 %typemap(in, numinputs=0)
54 (const bt_component_filter **OUT)
55 (bt_component_filter *temp_comp = NULL) {
59 %typemap(in, numinputs=0)
60 (const bt_component_sink **OUT)
61 (bt_component_sink *temp_comp = NULL) {
65 %typemap(argout) (const bt_component_source **OUT) {
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));
72 /* SWIG_Python_AppendOutput() steals Py_None */
74 $result = SWIG_Python_AppendOutput($result, Py_None);
78 %typemap(argout) (const bt_component_filter **OUT) {
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));
85 /* SWIG_Python_AppendOutput() steals Py_None */
87 $result = SWIG_Python_AppendOutput($result, Py_None);
91 %typemap(argout) (const bt_component_sink **OUT) {
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));
98 /* SWIG_Python_AppendOutput() steals Py_None */
100 $result = SWIG_Python_AppendOutput($result, Py_None);
104 /* From graph-const.h */
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,
116 extern bt_bool bt_graph_is_canceled(const bt_graph *graph);
118 extern void bt_graph_get_ref(const bt_graph *graph);
120 extern void bt_graph_put_ref(const bt_graph *graph);
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);
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);
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);
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);
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);
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);
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,
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);
165 typedef void (* bt_graph_listener_removed_func)(void *data);
167 extern bt_graph *bt_graph_create(void);
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);
174 extern bt_graph_status bt_graph_add_source_component_with_init_method_data(
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);
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);
186 extern bt_graph_status bt_graph_add_filter_component_with_init_method_data(
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);
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);
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);
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);
209 extern bt_graph_status bt_graph_run(bt_graph *graph);
211 extern bt_graph_status bt_graph_consume(bt_graph *graph);
213 extern bt_graph_status bt_graph_add_filter_component_input_port_added_listener(
215 bt_graph_filter_component_input_port_added_listener_func listener,
216 bt_graph_listener_removed_func listener_removed, void *data,
219 extern bt_graph_status bt_graph_add_sink_component_input_port_added_listener(
221 bt_graph_sink_component_input_port_added_listener_func listener,
222 bt_graph_listener_removed_func listener_removed, void *data,
225 extern bt_graph_status bt_graph_add_source_component_output_port_added_listener(
227 bt_graph_source_component_output_port_added_listener_func listener,
228 bt_graph_listener_removed_func listener_removed, void *data,
231 extern bt_graph_status bt_graph_add_filter_component_output_port_added_listener(
233 bt_graph_filter_component_output_port_added_listener_func listener,
234 bt_graph_listener_removed_func listener_removed, void *data,
237 extern bt_graph_status
238 bt_graph_add_source_filter_component_ports_connected_listener(
240 bt_graph_source_filter_component_ports_connected_listener_func listener,
241 bt_graph_listener_removed_func listener_removed, void *data,
244 extern bt_graph_status
245 bt_graph_add_filter_filter_component_ports_connected_listener(
247 bt_graph_filter_filter_component_ports_connected_listener_func listener,
248 bt_graph_listener_removed_func listener_removed, void *data,
251 extern bt_graph_status
252 bt_graph_add_source_sink_component_ports_connected_listener(
254 bt_graph_source_sink_component_ports_connected_listener_func listener,
255 bt_graph_listener_removed_func listener_removed, void *data,
258 extern bt_graph_status
259 bt_graph_add_filter_sink_component_ports_connected_listener(
261 bt_graph_filter_sink_component_ports_connected_listener_func listener,
262 bt_graph_listener_removed_func listener_removed, void *data,
265 extern bt_graph_status bt_graph_cancel(bt_graph *graph);
267 /* Helper functions for Python */
271 static void graph_listener_removed(void *py_callable)
273 BT_ASSERT(py_callable);
274 Py_DECREF(py_callable);
279 const void *component,
280 swig_type_info *component_swig_type,
281 bt_component_class_type component_class_type,
283 swig_type_info *port_swig_type,
284 bt_port_type port_type,
287 PyObject *py_component_ptr = NULL;
288 PyObject *py_port_ptr = NULL;
289 PyObject *py_res = NULL;
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.");
297 py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0);
299 BT_LOGF_STR("Failed to create port SWIG pointer object.");
303 py_res = PyObject_CallFunction(py_callable, "(OiOi)",
304 py_component_ptr, component_class_type, py_port_ptr, port_type);
306 bt2_py_loge_exception();
309 BT_ASSERT(py_res == Py_None);
314 Py_XDECREF(py_port_ptr);
315 Py_XDECREF(py_component_ptr);
319 source_component_output_port_added_listener(const bt_component_source *component_source,
320 const bt_port_output *port_output, void *py_callable)
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);
328 filter_component_input_port_added_listener(const bt_component_filter *component_filter,
329 const bt_port_input *port_input, void *py_callable)
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);
337 filter_component_output_port_added_listener(const bt_component_filter *component_filter,
338 const bt_port_output *port_output, void *py_callable)
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);
346 sink_component_input_port_added_listener(const bt_component_sink *component_sink,
347 const bt_port_input *port_input, void *py_callable)
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);
355 bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
356 PyObject *py_callable)
358 PyObject *py_listener_ids = NULL;
359 PyObject *py_listener_id = NULL;
361 bt_graph_status status;
364 BT_ASSERT(py_callable);
367 * Behind the scene, we will be registering 4 different listeners and
368 * return all of their ids.
370 py_listener_ids = PyTuple_New(4);
371 if (!py_listener_ids) {
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) {
383 py_listener_id = PyLong_FromLong(listener_id);
384 if (!py_listener_id) {
388 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
389 py_listener_id = NULL;
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) {
399 py_listener_id = PyLong_FromLong(listener_id);
400 if (!py_listener_id) {
404 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
405 py_listener_id = NULL;
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) {
415 py_listener_id = PyLong_FromLong(listener_id);
416 if (!py_listener_id) {
420 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
421 py_listener_id = NULL;
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) {
431 py_listener_id = PyLong_FromLong(listener_id);
432 if (!py_listener_id) {
437 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
438 py_listener_id = NULL;
440 Py_INCREF(py_callable);
441 Py_INCREF(py_callable);
442 Py_INCREF(py_callable);
443 Py_INCREF(py_callable);
448 Py_XDECREF(py_listener_ids);
449 py_listener_ids = Py_None;
450 Py_INCREF(py_listener_ids);
454 Py_XDECREF(py_listener_id);
455 return py_listener_ids;
459 ports_connected_listener(const bt_port_output *upstream_port,
460 const bt_port_input *downstream_port,
463 PyObject *py_upstream_port_ptr = NULL;
464 PyObject *py_downstream_port_ptr = NULL;
465 PyObject *py_res = NULL;
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.");
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.");
481 py_res = PyObject_CallFunction(py_callable, "(OO)",
482 py_upstream_port_ptr, py_downstream_port_ptr);
484 bt2_py_loge_exception();
487 BT_ASSERT(py_res == Py_None);
490 Py_DECREF(py_upstream_port_ptr);
491 Py_DECREF(py_downstream_port_ptr);
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)
502 ports_connected_listener(upstream_port, downstream_port, py_callable);
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)
512 ports_connected_listener(upstream_port, downstream_port, py_callable);
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)
522 ports_connected_listener(upstream_port, downstream_port, py_callable);
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)
532 ports_connected_listener(upstream_port, downstream_port, py_callable);
537 bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
538 PyObject *py_callable)
540 PyObject *py_listener_ids = NULL;
541 PyObject *py_listener_id = NULL;
543 bt_graph_status status;
546 BT_ASSERT(py_callable);
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) {
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) {
563 py_listener_id = PyLong_FromLong(listener_id);
564 if (!py_listener_id) {
568 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
569 py_listener_id = NULL;
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) {
579 py_listener_id = PyLong_FromLong(listener_id);
580 if (!py_listener_id) {
584 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
585 py_listener_id = NULL;
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) {
595 py_listener_id = PyLong_FromLong(listener_id);
596 if (!py_listener_id) {
600 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
601 py_listener_id = NULL;
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) {
611 py_listener_id = PyLong_FromLong(listener_id);
612 if (!py_listener_id) {
616 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
617 py_listener_id = NULL;
619 Py_INCREF(py_callable);
620 Py_INCREF(py_callable);
621 Py_INCREF(py_callable);
622 Py_INCREF(py_callable);
627 Py_XDECREF(py_listener_ids);
628 py_listener_ids = Py_None;
629 Py_INCREF(py_listener_ids);
633 Py_XDECREF(py_listener_id);
634 return py_listener_ids;
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);