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