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 static bt_graph_listener_func_status
port_added_listener(
26 const void *component
,
27 swig_type_info
*component_swig_type
,
28 bt_component_class_type component_class_type
,
30 swig_type_info
*port_swig_type
,
31 bt_port_type port_type
,
34 PyObject
*py_component_ptr
= NULL
;
35 PyObject
*py_port_ptr
= NULL
;
36 PyObject
*py_res
= NULL
;
37 bt_graph_listener_func_status status
;
39 py_component_ptr
= SWIG_NewPointerObj(SWIG_as_voidptr(component
), component_swig_type
, 0);
40 if (!py_component_ptr
) {
41 BT_LOGF_STR("Failed to create component SWIG pointer object.");
42 status
= __BT_FUNC_STATUS_MEMORY_ERROR
;
46 py_port_ptr
= SWIG_NewPointerObj(SWIG_as_voidptr(port
), port_swig_type
, 0);
48 BT_LOGF_STR("Failed to create port SWIG pointer object.");
49 status
= __BT_FUNC_STATUS_MEMORY_ERROR
;
53 py_res
= PyObject_CallFunction(py_callable
, "(OiOi)",
54 py_component_ptr
, component_class_type
, py_port_ptr
, port_type
);
56 loge_exception_append_cause_clear(
57 "Graph's port added listener (Python)",
59 status
= __BT_FUNC_STATUS_ERROR
;
63 BT_ASSERT(py_res
== Py_None
);
64 status
= __BT_FUNC_STATUS_OK
;
68 Py_XDECREF(py_port_ptr
);
69 Py_XDECREF(py_component_ptr
);
74 bt_graph_listener_func_status
75 source_component_output_port_added_listener(const bt_component_source
*component_source
,
76 const bt_port_output
*port_output
, void *py_callable
)
78 return port_added_listener(
79 component_source
, SWIGTYPE_p_bt_component_source
, BT_COMPONENT_CLASS_TYPE_SOURCE
,
80 port_output
, SWIGTYPE_p_bt_port_output
, BT_PORT_TYPE_OUTPUT
, py_callable
);
84 bt_graph_listener_func_status
85 filter_component_input_port_added_listener(const bt_component_filter
*component_filter
,
86 const bt_port_input
*port_input
, void *py_callable
)
88 return port_added_listener(
89 component_filter
, SWIGTYPE_p_bt_component_filter
, BT_COMPONENT_CLASS_TYPE_FILTER
,
90 port_input
, SWIGTYPE_p_bt_port_input
, BT_PORT_TYPE_INPUT
, py_callable
);
94 bt_graph_listener_func_status
95 filter_component_output_port_added_listener(const bt_component_filter
*component_filter
,
96 const bt_port_output
*port_output
, void *py_callable
)
98 return port_added_listener(
99 component_filter
, SWIGTYPE_p_bt_component_filter
, BT_COMPONENT_CLASS_TYPE_FILTER
,
100 port_output
, SWIGTYPE_p_bt_port_output
, BT_PORT_TYPE_OUTPUT
, py_callable
);
104 bt_graph_listener_func_status
105 sink_component_input_port_added_listener(const bt_component_sink
*component_sink
,
106 const bt_port_input
*port_input
, void *py_callable
)
108 return port_added_listener(
109 component_sink
, SWIGTYPE_p_bt_component_sink
, BT_COMPONENT_CLASS_TYPE_SINK
,
110 port_input
, SWIGTYPE_p_bt_port_input
, BT_PORT_TYPE_INPUT
, py_callable
);
114 PyObject
*bt_bt2_graph_add_port_added_listener(struct bt_graph
*graph
,
115 PyObject
*py_callable
)
117 PyObject
*py_listener_ids
= NULL
;
118 PyObject
*py_listener_id
= NULL
;
119 bt_listener_id listener_id
;
120 bt_graph_add_listener_status status
;
121 const char * const module_name
=
122 "graph_add_port_added_listener() (Python)";
125 BT_ASSERT(py_callable
);
128 * Behind the scene, we will be registering 4 different listeners and
129 * return all of their ids.
131 py_listener_ids
= PyTuple_New(4);
132 if (!py_listener_ids
) {
133 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
134 "Failed to allocate one PyTuple.");
138 /* source output port */
139 status
= bt_graph_add_source_component_output_port_added_listener(
140 graph
, source_component_output_port_added_listener
,
141 py_callable
, &listener_id
);
142 if (status
!= __BT_FUNC_STATUS_OK
) {
144 * bt_graph_add_source_component_output_port_added_listener has
145 * already logged/appended an error cause.
150 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
151 if (!py_listener_id
) {
152 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
153 "Failed to allocate one PyLong.");
157 PyTuple_SET_ITEM(py_listener_ids
, 0, py_listener_id
);
158 py_listener_id
= NULL
;
160 /* filter input port */
161 status
= bt_graph_add_filter_component_input_port_added_listener(
162 graph
, filter_component_input_port_added_listener
,
163 py_callable
, &listener_id
);
164 if (status
!= __BT_FUNC_STATUS_OK
) {
166 * bt_graph_add_filter_component_input_port_added_listener has
167 * already logged/appended an error cause.
172 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
173 if (!py_listener_id
) {
174 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
175 "Failed to allocate one PyLong.");
179 PyTuple_SET_ITEM(py_listener_ids
, 1, py_listener_id
);
180 py_listener_id
= NULL
;
182 /* filter output port */
183 status
= bt_graph_add_filter_component_output_port_added_listener(
184 graph
, filter_component_output_port_added_listener
,
185 py_callable
, &listener_id
);
186 if (status
!= __BT_FUNC_STATUS_OK
) {
188 * bt_graph_add_filter_component_output_port_added_listener has
189 * already logged/appended an error cause.
194 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
195 if (!py_listener_id
) {
196 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
197 "Failed to allocate one PyLong.");
201 PyTuple_SET_ITEM(py_listener_ids
, 2, py_listener_id
);
202 py_listener_id
= NULL
;
204 /* sink input port */
205 status
= bt_graph_add_sink_component_input_port_added_listener(
206 graph
, sink_component_input_port_added_listener
,
207 py_callable
, &listener_id
);
208 if (status
!= __BT_FUNC_STATUS_OK
) {
210 * bt_graph_add_sink_component_input_port_added_listener has
211 * already logged/appended an error cause.
216 py_listener_id
= PyLong_FromUnsignedLongLong(listener_id
);
217 if (!py_listener_id
) {
218 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name
,
219 "Failed to allocate one PyLong.");
223 PyTuple_SET_ITEM(py_listener_ids
, 3, py_listener_id
);
224 py_listener_id
= NULL
;
228 Py_XDECREF(py_listener_ids
);
229 py_listener_ids
= Py_None
;
230 Py_INCREF(py_listener_ids
);
233 Py_XDECREF(py_listener_id
);
234 return py_listener_ids
;
238 bt_graph_add_component_status
239 bt_bt2_graph_add_source_component(
241 const bt_component_class_source
*component_class
,
242 const char *name
, const bt_value
*params
,
243 PyObject
*obj
, bt_logging_level log_level
,
244 const bt_component_source
**component
)
246 return bt_graph_add_source_component_with_initialize_method_data(graph
,
247 component_class
, name
, params
, obj
== Py_None
? NULL
: obj
,
248 log_level
, component
);
252 bt_graph_add_component_status
253 bt_bt2_graph_add_filter_component(
255 const bt_component_class_filter
*component_class
,
256 const char *name
, const bt_value
*params
,
257 PyObject
*obj
, bt_logging_level log_level
,
258 const bt_component_filter
**component
)
260 return bt_graph_add_filter_component_with_initialize_method_data(graph
,
261 component_class
, name
, params
, obj
== Py_None
? NULL
: obj
,
262 log_level
, component
);
266 bt_graph_add_component_status
267 bt_bt2_graph_add_sink_component(
269 const bt_component_class_sink
*component_class
,
270 const char *name
, const bt_value
*params
,
271 PyObject
*obj
, bt_logging_level log_level
,
272 const bt_component_sink
**component
)
274 return bt_graph_add_sink_component_with_initialize_method_data(graph
,
275 component_class
, name
, params
, obj
== Py_None
? NULL
: obj
,
276 log_level
, component
);