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 enum bt_graph_listener_status {
125 BT_GRAPH_LISTENER_STATUS_OK = 0,
126 BT_GRAPH_LISTENER_STATUS_ERROR = -1,
127 BT_GRAPH_LISTENER_STATUS_NOMEM = -12,
128 } bt_graph_listener_status;
131 typedef bt_graph_listener_status
132 (*bt_graph_filter_component_input_port_added_listener_func)(
133 const bt_component_filter *component,
134 const bt_port_input *port, void *data);
136 typedef bt_graph_listener_status
137 (*bt_graph_sink_component_input_port_added_listener_func)(
138 const bt_component_sink *component,
139 const bt_port_input *port, void *data);
141 typedef bt_graph_listener_status
142 (*bt_graph_source_component_output_port_added_listener_func)(
143 const bt_component_source *component,
144 const bt_port_output *port, void *data);
146 typedef bt_graph_listener_status
147 (*bt_graph_filter_component_output_port_added_listener_func)(
148 const bt_component_filter *component,
149 const bt_port_output *port, void *data);
151 typedef bt_graph_listener_status
152 (*bt_graph_source_filter_component_ports_connected_listener_func)(
153 const bt_component_source *source_component,
154 const bt_component_filter *filter_component,
155 const bt_port_output *upstream_port,
156 const bt_port_input *downstream_port, void *data);
158 typedef bt_graph_listener_status
159 (*bt_graph_source_sink_component_ports_connected_listener_func)(
160 const bt_component_source *source_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 bt_graph_listener_status
166 (*bt_graph_filter_filter_component_ports_connected_listener_func)(
167 const bt_component_filter *filter_component_upstream,
168 const bt_component_filter *filter_component_downstream,
169 const bt_port_output *upstream_port,
170 const bt_port_input *downstream_port,
173 typedef bt_graph_listener_status
174 (*bt_graph_filter_sink_component_ports_connected_listener_func)(
175 const bt_component_filter *filter_component,
176 const bt_component_sink *sink_component,
177 const bt_port_output *upstream_port,
178 const bt_port_input *downstream_port, void *data);
180 typedef void (* bt_graph_listener_removed_func)(void *data);
182 extern bt_graph *bt_graph_create(void);
184 extern bt_graph_status bt_graph_add_source_component(bt_graph *graph,
185 const bt_component_class_source *component_class,
186 const char *name, const bt_value *params,
187 const bt_component_source **OUT);
189 extern bt_graph_status bt_graph_add_source_component_with_init_method_data(
191 const bt_component_class_source *component_class,
192 const char *name, const bt_value *params,
193 void *init_method_data,
194 const bt_component_source **OUT);
196 extern bt_graph_status bt_graph_add_filter_component(bt_graph *graph,
197 const bt_component_class_filter *component_class,
198 const char *name, const bt_value *params,
199 const bt_component_filter **OUT);
201 extern bt_graph_status bt_graph_add_filter_component_with_init_method_data(
203 const bt_component_class_filter *component_class,
204 const char *name, const bt_value *params,
205 void *init_method_data,
206 const bt_component_filter **OUT);
208 extern bt_graph_status bt_graph_add_sink_component(
209 bt_graph *graph, const bt_component_class_sink *component_class,
210 const char *name, const bt_value *params,
211 const bt_component_sink **OUT);
213 extern bt_graph_status bt_graph_add_sink_component_with_init_method_data(
214 bt_graph *graph, const bt_component_class_sink *component_class,
215 const char *name, const bt_value *params,
216 void *init_method_data,
217 const bt_component_sink **OUT);
219 extern bt_graph_status bt_graph_connect_ports(bt_graph *graph,
220 const bt_port_output *upstream,
221 const bt_port_input *downstream,
222 const bt_connection **BTOUTCONN);
224 extern bt_graph_status bt_graph_run(bt_graph *graph);
226 extern bt_graph_status bt_graph_consume(bt_graph *graph);
228 extern bt_graph_status bt_graph_add_filter_component_input_port_added_listener(
230 bt_graph_filter_component_input_port_added_listener_func listener,
231 bt_graph_listener_removed_func listener_removed, void *data,
234 extern bt_graph_status bt_graph_add_sink_component_input_port_added_listener(
236 bt_graph_sink_component_input_port_added_listener_func listener,
237 bt_graph_listener_removed_func listener_removed, void *data,
240 extern bt_graph_status bt_graph_add_source_component_output_port_added_listener(
242 bt_graph_source_component_output_port_added_listener_func listener,
243 bt_graph_listener_removed_func listener_removed, void *data,
246 extern bt_graph_status bt_graph_add_filter_component_output_port_added_listener(
248 bt_graph_filter_component_output_port_added_listener_func listener,
249 bt_graph_listener_removed_func listener_removed, void *data,
252 extern bt_graph_status
253 bt_graph_add_source_filter_component_ports_connected_listener(
255 bt_graph_source_filter_component_ports_connected_listener_func listener,
256 bt_graph_listener_removed_func listener_removed, void *data,
259 extern bt_graph_status
260 bt_graph_add_filter_filter_component_ports_connected_listener(
262 bt_graph_filter_filter_component_ports_connected_listener_func listener,
263 bt_graph_listener_removed_func listener_removed, void *data,
266 extern bt_graph_status
267 bt_graph_add_source_sink_component_ports_connected_listener(
269 bt_graph_source_sink_component_ports_connected_listener_func listener,
270 bt_graph_listener_removed_func listener_removed, void *data,
273 extern bt_graph_status
274 bt_graph_add_filter_sink_component_ports_connected_listener(
276 bt_graph_filter_sink_component_ports_connected_listener_func listener,
277 bt_graph_listener_removed_func listener_removed, void *data,
280 extern bt_graph_status bt_graph_cancel(bt_graph *graph);
282 /* Helper functions for Python */
286 static void graph_listener_removed(void *py_callable)
288 BT_ASSERT(py_callable);
289 Py_DECREF(py_callable);
292 static bt_graph_listener_status
294 const void *component,
295 swig_type_info *component_swig_type,
296 bt_component_class_type component_class_type,
298 swig_type_info *port_swig_type,
299 bt_port_type port_type,
302 PyObject *py_component_ptr = NULL;
303 PyObject *py_port_ptr = NULL;
304 PyObject *py_res = NULL;
305 bt_graph_listener_status status;
307 py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0);
308 if (!py_component_ptr) {
309 BT_LOGF_STR("Failed to create component SWIG pointer object.");
310 status = BT_GRAPH_LISTENER_STATUS_NOMEM;
314 py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0);
316 BT_LOGF_STR("Failed to create port SWIG pointer object.");
317 status = BT_GRAPH_LISTENER_STATUS_NOMEM;
321 py_res = PyObject_CallFunction(py_callable, "(OiOi)",
322 py_component_ptr, component_class_type, py_port_ptr, port_type);
324 bt2_py_loge_exception();
326 status = BT_GRAPH_LISTENER_STATUS_ERROR;
330 BT_ASSERT(py_res == Py_None);
331 status = BT_GRAPH_LISTENER_STATUS_OK;
335 Py_XDECREF(py_port_ptr);
336 Py_XDECREF(py_component_ptr);
341 static bt_graph_listener_status
342 source_component_output_port_added_listener(const bt_component_source *component_source,
343 const bt_port_output *port_output, void *py_callable)
345 return port_added_listener(
346 component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
347 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
350 static bt_graph_listener_status
351 filter_component_input_port_added_listener(const bt_component_filter *component_filter,
352 const bt_port_input *port_input, void *py_callable)
354 return port_added_listener(
355 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
356 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
359 static bt_graph_listener_status
360 filter_component_output_port_added_listener(const bt_component_filter *component_filter,
361 const bt_port_output *port_output, void *py_callable)
363 return port_added_listener(
364 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
365 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
368 static bt_graph_listener_status
369 sink_component_input_port_added_listener(const bt_component_sink *component_sink,
370 const bt_port_input *port_input, void *py_callable)
372 return port_added_listener(
373 component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
374 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
378 bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
379 PyObject *py_callable)
381 PyObject *py_listener_ids = NULL;
382 PyObject *py_listener_id = NULL;
384 bt_graph_status status;
387 BT_ASSERT(py_callable);
390 * Behind the scene, we will be registering 4 different listeners and
391 * return all of their ids.
393 py_listener_ids = PyTuple_New(4);
394 if (!py_listener_ids) {
398 /* source output port */
399 status = bt_graph_add_source_component_output_port_added_listener(
400 graph, source_component_output_port_added_listener,
401 graph_listener_removed, py_callable, &listener_id);
402 if (status != BT_GRAPH_STATUS_OK) {
406 py_listener_id = PyLong_FromLong(listener_id);
407 if (!py_listener_id) {
411 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
412 py_listener_id = NULL;
414 /* filter input port */
415 status = bt_graph_add_filter_component_input_port_added_listener(
416 graph, filter_component_input_port_added_listener,
417 graph_listener_removed, py_callable, &listener_id);
418 if (status != BT_GRAPH_STATUS_OK) {
422 py_listener_id = PyLong_FromLong(listener_id);
423 if (!py_listener_id) {
427 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
428 py_listener_id = NULL;
430 /* filter output port */
431 status = bt_graph_add_filter_component_output_port_added_listener(
432 graph, filter_component_output_port_added_listener,
433 graph_listener_removed, py_callable, &listener_id);
434 if (status != BT_GRAPH_STATUS_OK) {
438 py_listener_id = PyLong_FromLong(listener_id);
439 if (!py_listener_id) {
443 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
444 py_listener_id = NULL;
446 /* sink input port */
447 status = bt_graph_add_sink_component_input_port_added_listener(
448 graph, sink_component_input_port_added_listener,
449 graph_listener_removed, py_callable, &listener_id);
450 if (status != BT_GRAPH_STATUS_OK) {
454 py_listener_id = PyLong_FromLong(listener_id);
455 if (!py_listener_id) {
460 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
461 py_listener_id = NULL;
463 Py_INCREF(py_callable);
464 Py_INCREF(py_callable);
465 Py_INCREF(py_callable);
466 Py_INCREF(py_callable);
471 Py_XDECREF(py_listener_ids);
472 py_listener_ids = Py_None;
473 Py_INCREF(py_listener_ids);
477 Py_XDECREF(py_listener_id);
478 return py_listener_ids;
481 static bt_graph_listener_status
482 ports_connected_listener(
483 const void *upstream_component,
484 swig_type_info *upstream_component_swig_type,
485 bt_component_class_type upstream_component_class_type,
486 const bt_port_output *upstream_port,
487 const void *downstream_component,
488 swig_type_info *downstream_component_swig_type,
489 bt_component_class_type downstream_component_class_type,
490 const bt_port_input *downstream_port,
493 PyObject *py_upstream_component_ptr = NULL;
494 PyObject *py_upstream_port_ptr = NULL;
495 PyObject *py_downstream_component_ptr = NULL;
496 PyObject *py_downstream_port_ptr = NULL;
497 PyObject *py_res = NULL;
498 bt_graph_listener_status status;
500 py_upstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(upstream_component),
501 upstream_component_swig_type, 0);
502 if (!py_upstream_component_ptr) {
503 BT_LOGF_STR("Failed to create upstream component SWIG pointer object.");
504 status = BT_GRAPH_LISTENER_STATUS_NOMEM;
508 py_upstream_port_ptr = SWIG_NewPointerObj(
509 SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0);
510 if (!py_upstream_port_ptr) {
511 BT_LOGF_STR("Failed to create upstream port SWIG pointer object.");
512 status = BT_GRAPH_LISTENER_STATUS_NOMEM;
516 py_downstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(downstream_component),
517 downstream_component_swig_type, 0);
518 if (!py_downstream_component_ptr) {
519 BT_LOGF_STR("Failed to create downstream component SWIG pointer object.");
520 status = BT_GRAPH_LISTENER_STATUS_NOMEM;
524 py_downstream_port_ptr = SWIG_NewPointerObj(
525 SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0);
526 if (!py_downstream_port_ptr) {
527 BT_LOGF_STR("Failed to create downstream port SWIG pointer object.");
528 status = BT_GRAPH_LISTENER_STATUS_NOMEM;
532 py_res = PyObject_CallFunction(py_callable, "(OiOOiO)",
533 py_upstream_component_ptr, upstream_component_class_type,
534 py_upstream_port_ptr,
535 py_downstream_component_ptr, downstream_component_class_type,
536 py_downstream_port_ptr);
538 bt2_py_loge_exception();
540 status = BT_GRAPH_LISTENER_STATUS_ERROR;
544 BT_ASSERT(py_res == Py_None);
545 status = BT_GRAPH_LISTENER_STATUS_OK;
548 Py_XDECREF(py_upstream_component_ptr);
549 Py_XDECREF(py_upstream_port_ptr);
550 Py_XDECREF(py_downstream_component_ptr);
551 Py_XDECREF(py_downstream_port_ptr);
557 static bt_graph_listener_status
558 source_filter_component_ports_connected_listener(
559 const bt_component_source *source_component,
560 const bt_component_filter *filter_component,
561 const bt_port_output *upstream_port,
562 const bt_port_input *downstream_port, void *py_callable)
564 return ports_connected_listener(
565 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
567 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
572 static bt_graph_listener_status
573 source_sink_component_ports_connected_listener(
574 const bt_component_source *source_component,
575 const bt_component_sink *sink_component,
576 const bt_port_output *upstream_port,
577 const bt_port_input *downstream_port, void *py_callable)
579 return ports_connected_listener(
580 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
582 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
587 static bt_graph_listener_status
588 filter_filter_component_ports_connected_listener(
589 const bt_component_filter *filter_component_left,
590 const bt_component_filter *filter_component_right,
591 const bt_port_output *upstream_port,
592 const bt_port_input *downstream_port, void *py_callable)
594 return ports_connected_listener(
595 filter_component_left, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
597 filter_component_right, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
602 static bt_graph_listener_status
603 filter_sink_component_ports_connected_listener(
604 const bt_component_filter *filter_component,
605 const bt_component_sink *sink_component,
606 const bt_port_output *upstream_port,
607 const bt_port_input *downstream_port, void *py_callable)
609 return ports_connected_listener(
610 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
612 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
618 bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
619 PyObject *py_callable)
621 PyObject *py_listener_ids = NULL;
622 PyObject *py_listener_id = NULL;
624 bt_graph_status status;
627 BT_ASSERT(py_callable);
629 /* Behind the scene, we will be registering 4 different listeners and
630 * return all of their ids. */
631 py_listener_ids = PyTuple_New(4);
632 if (!py_listener_ids) {
636 /* source -> filter connection */
637 status = bt_graph_add_source_filter_component_ports_connected_listener(
638 graph, source_filter_component_ports_connected_listener,
639 graph_listener_removed, py_callable, &listener_id);
640 if (status != BT_GRAPH_STATUS_OK) {
644 py_listener_id = PyLong_FromLong(listener_id);
645 if (!py_listener_id) {
649 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
650 py_listener_id = NULL;
652 /* source -> sink connection */
653 status = bt_graph_add_source_sink_component_ports_connected_listener(
654 graph, source_sink_component_ports_connected_listener,
655 graph_listener_removed, py_callable, &listener_id);
656 if (status != BT_GRAPH_STATUS_OK) {
660 py_listener_id = PyLong_FromLong(listener_id);
661 if (!py_listener_id) {
665 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
666 py_listener_id = NULL;
668 /* filter -> filter connection */
669 status = bt_graph_add_filter_filter_component_ports_connected_listener(
670 graph, filter_filter_component_ports_connected_listener,
671 graph_listener_removed, py_callable, &listener_id);
672 if (status != BT_GRAPH_STATUS_OK) {
676 py_listener_id = PyLong_FromLong(listener_id);
677 if (!py_listener_id) {
681 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
682 py_listener_id = NULL;
684 /* filter -> sink connection */
685 status = bt_graph_add_filter_sink_component_ports_connected_listener(
686 graph, filter_sink_component_ports_connected_listener,
687 graph_listener_removed, py_callable, &listener_id);
688 if (status != BT_GRAPH_STATUS_OK) {
692 py_listener_id = PyLong_FromLong(listener_id);
693 if (!py_listener_id) {
697 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
698 py_listener_id = NULL;
700 Py_INCREF(py_callable);
701 Py_INCREF(py_callable);
702 Py_INCREF(py_callable);
703 Py_INCREF(py_callable);
708 Py_XDECREF(py_listener_ids);
709 py_listener_ids = Py_None;
710 Py_INCREF(py_listener_ids);
714 Py_XDECREF(py_listener_id);
715 return py_listener_ids;
720 PyObject *bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
721 PyObject *py_callable);
722 PyObject *bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
723 PyObject *py_callable);