2 * SPDX-License-Identifier: MIT
4 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
7 static bt_graph_listener_func_status
port_added_listener(
9 swig_type_info
*component_swig_type
,
10 bt_component_class_type component_class_type
,
12 swig_type_info
*port_swig_type
,
13 bt_port_type port_type
,
16 PyObject
*py_component_ptr
= NULL
;
17 PyObject
*py_port_ptr
= NULL
;
18 PyObject
*py_res
= NULL
;
19 bt_graph_listener_func_status status
;
21 py_component_ptr
= SWIG_NewPointerObj(SWIG_as_voidptr(component
), component_swig_type
, 0);
22 if (!py_component_ptr
) {
23 BT_LOGF_STR("Failed to create component SWIG pointer object.");
24 status
= __BT_FUNC_STATUS_MEMORY_ERROR
;
28 py_port_ptr
= SWIG_NewPointerObj(SWIG_as_voidptr(port
), port_swig_type
, 0);
30 BT_LOGF_STR("Failed to create port SWIG pointer object.");
31 status
= __BT_FUNC_STATUS_MEMORY_ERROR
;
35 py_res
= PyObject_CallFunction(py_callable
, "(OiOi)",
36 py_component_ptr
, component_class_type
, py_port_ptr
, port_type
);
38 loge_exception_append_cause_clear(
39 "Graph's port added listener (Python)",
41 status
= __BT_FUNC_STATUS_ERROR
;
45 BT_ASSERT(py_res
== Py_None
);
46 status
= __BT_FUNC_STATUS_OK
;
50 Py_XDECREF(py_port_ptr
);
51 Py_XDECREF(py_component_ptr
);
56 bt_graph_listener_func_status
57 source_component_output_port_added_listener(const bt_component_source
*component_source
,
58 const bt_port_output
*port_output
, void *py_callable
)
60 return port_added_listener(
61 component_source
, SWIGTYPE_p_bt_component_source
, BT_COMPONENT_CLASS_TYPE_SOURCE
,
62 port_output
, SWIGTYPE_p_bt_port_output
, BT_PORT_TYPE_OUTPUT
, py_callable
);
66 bt_graph_listener_func_status
67 filter_component_input_port_added_listener(const bt_component_filter
*component_filter
,
68 const bt_port_input
*port_input
, void *py_callable
)
70 return port_added_listener(
71 component_filter
, SWIGTYPE_p_bt_component_filter
, BT_COMPONENT_CLASS_TYPE_FILTER
,
72 port_input
, SWIGTYPE_p_bt_port_input
, BT_PORT_TYPE_INPUT
, py_callable
);
76 bt_graph_listener_func_status
77 filter_component_output_port_added_listener(const bt_component_filter
*component_filter
,
78 const bt_port_output
*port_output
, void *py_callable
)
80 return port_added_listener(
81 component_filter
, SWIGTYPE_p_bt_component_filter
, BT_COMPONENT_CLASS_TYPE_FILTER
,
82 port_output
, SWIGTYPE_p_bt_port_output
, BT_PORT_TYPE_OUTPUT
, py_callable
);
86 bt_graph_listener_func_status
87 sink_component_input_port_added_listener(const bt_component_sink
*component_sink
,
88 const bt_port_input
*port_input
, void *py_callable
)
90 return port_added_listener(
91 component_sink
, SWIGTYPE_p_bt_component_sink
, BT_COMPONENT_CLASS_TYPE_SINK
,
92 port_input
, SWIGTYPE_p_bt_port_input
, BT_PORT_TYPE_INPUT
, py_callable
);
96 PyObject
*bt_bt2_graph_add_port_added_listener(struct bt_graph
*graph
,
97 PyObject
*py_callable
)
99 PyObject
*py_listener_ids
= NULL
;
100 PyObject
*py_listener_id
= NULL
;
101 bt_listener_id listener_id
;
102 bt_graph_add_listener_status status
;
103 const char * const module_name
=
104 "graph_add_port_added_listener() (Python)";
107 BT_ASSERT(py_callable
);
110 * Behind the scene, we will be registering 4 different listeners and
111 * return all of their ids.
113 py_listener_ids
= PyTuple_New(4);
114 if (!py_listener_ids
) {
115 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
116 "Failed to allocate one PyTuple.");
120 /* source output port */
121 status
= bt_graph_add_source_component_output_port_added_listener(
122 graph
, source_component_output_port_added_listener
,
123 py_callable
, &listener_id
);
124 if (status
!= __BT_FUNC_STATUS_OK
) {
126 * bt_graph_add_source_component_output_port_added_listener has
127 * already logged/appended an error cause.
132 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
133 if (!py_listener_id
) {
134 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
135 "Failed to allocate one PyLong.");
139 PyTuple_SET_ITEM(py_listener_ids
, 0, py_listener_id
);
140 py_listener_id
= NULL
;
142 /* filter input port */
143 status
= bt_graph_add_filter_component_input_port_added_listener(
144 graph
, filter_component_input_port_added_listener
,
145 py_callable
, &listener_id
);
146 if (status
!= __BT_FUNC_STATUS_OK
) {
148 * bt_graph_add_filter_component_input_port_added_listener has
149 * already logged/appended an error cause.
154 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
155 if (!py_listener_id
) {
156 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
157 "Failed to allocate one PyLong.");
161 PyTuple_SET_ITEM(py_listener_ids
, 1, py_listener_id
);
162 py_listener_id
= NULL
;
164 /* filter output port */
165 status
= bt_graph_add_filter_component_output_port_added_listener(
166 graph
, filter_component_output_port_added_listener
,
167 py_callable
, &listener_id
);
168 if (status
!= __BT_FUNC_STATUS_OK
) {
170 * bt_graph_add_filter_component_output_port_added_listener has
171 * already logged/appended an error cause.
176 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
177 if (!py_listener_id
) {
178 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
179 "Failed to allocate one PyLong.");
183 PyTuple_SET_ITEM(py_listener_ids
, 2, py_listener_id
);
184 py_listener_id
= NULL
;
186 /* sink input port */
187 status
= bt_graph_add_sink_component_input_port_added_listener(
188 graph
, sink_component_input_port_added_listener
,
189 py_callable
, &listener_id
);
190 if (status
!= __BT_FUNC_STATUS_OK
) {
192 * bt_graph_add_sink_component_input_port_added_listener has
193 * already logged/appended an error cause.
198 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
199 if (!py_listener_id
) {
200 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
201 "Failed to allocate one PyLong.");
205 PyTuple_SET_ITEM(py_listener_ids
, 3, py_listener_id
);
206 py_listener_id
= NULL
;
210 Py_XDECREF(py_listener_ids
);
211 py_listener_ids
= Py_None
;
212 Py_INCREF(py_listener_ids
);
215 Py_XDECREF(py_listener_id
);
216 return py_listener_ids
;
220 bt_graph_add_component_status
221 bt_bt2_graph_add_source_component(
223 const bt_component_class_source
*component_class
,
224 const char *name
, const bt_value
*params
,
225 PyObject
*obj
, bt_logging_level log_level
,
226 const bt_component_source
**component
)
228 return bt_graph_add_source_component_with_initialize_method_data(graph
,
229 component_class
, name
, params
, obj
== Py_None
? NULL
: obj
,
230 log_level
, component
);
234 bt_graph_add_component_status
235 bt_bt2_graph_add_filter_component(
237 const bt_component_class_filter
*component_class
,
238 const char *name
, const bt_value
*params
,
239 PyObject
*obj
, bt_logging_level log_level
,
240 const bt_component_filter
**component
)
242 return bt_graph_add_filter_component_with_initialize_method_data(graph
,
243 component_class
, name
, params
, obj
== Py_None
? NULL
: obj
,
244 log_level
, component
);
248 bt_graph_add_component_status
249 bt_bt2_graph_add_sink_component(
251 const bt_component_class_sink
*component_class
,
252 const char *name
, const bt_value
*params
,
253 PyObject
*obj
, bt_logging_level log_level
,
254 const bt_component_sink
**component
)
256 return bt_graph_add_sink_component_with_initialize_method_data(graph
,
257 component_class
, name
, params
, obj
== Py_None
? NULL
: obj
,
258 log_level
, component
);