From dc43190b29953dd4aa2bbcdc86b34fb47d76a62c Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Fri, 1 Sep 2017 22:03:14 -0400 Subject: [PATCH] bt2: add bt2._OutputPort.create_notification_iterator() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This is the interface to create an output port notification iterator from a given (public) output port. Signed-off-by: Philippe Proulx Signed-off-by: Jérémie Galarneau --- bindings/python/bt2/bt2/connection.py | 14 ++----- bindings/python/bt2/bt2/native_bt.i | 37 +++++++++++++++++++ bindings/python/bt2/bt2/native_btconnection.i | 33 ++--------------- bindings/python/bt2/bt2/native_btnotifiter.i | 5 +++ bindings/python/bt2/bt2/native_btport.i | 25 +++++++++++++ bindings/python/bt2/bt2/notification.py | 13 +++++++ .../python/bt2/bt2/notification_iterator.py | 4 ++ bindings/python/bt2/bt2/port.py | 18 ++++++++- 8 files changed, 108 insertions(+), 41 deletions(-) diff --git a/bindings/python/bt2/bt2/connection.py b/bindings/python/bt2/bt2/connection.py index fdeb84d9..289667f5 100644 --- a/bindings/python/bt2/bt2/connection.py +++ b/bindings/python/bt2/bt2/connection.py @@ -82,17 +82,9 @@ class _Connection(object._Object): class _PrivateConnection(object._PrivateObject, _Connection): def create_notification_iterator(self, notification_types=None): - if notification_types is None: - notif_types = None - else: - for notif_cls in notification_types: - if notif_cls not in bt2.notification._NOTIF_TYPE_TO_CLS.values(): - raise ValueError("'{}' is not a notification class".format(notif_cls)) - - notif_types = [notif_cls._TYPE for notif_cls in notification_types] - - status, notif_iter_ptr = native_bt.py3_create_notif_iter(int(self._ptr), - notif_types) + notif_types = bt2.notification._notif_types_from_notif_classes(notification_types) + status, notif_iter_ptr = native_bt.py3_create_priv_conn_notif_iter(int(self._ptr), + notif_types) _handle_status(status, 'cannot create notification iterator object') assert(notif_iter_ptr) return bt2.notification_iterator._PrivateConnectionNotificationIterator._create_from_ptr(notif_iter_ptr) diff --git a/bindings/python/bt2/bt2/native_bt.i b/bindings/python/bt2/bt2/native_bt.i index 59595a31..ad227973 100644 --- a/bindings/python/bt2/bt2/native_bt.i +++ b/bindings/python/bt2/bt2/native_bt.i @@ -192,6 +192,43 @@ typedef int bt_bool; $result = $1; } +%{ +static enum bt_notification_type *bt_py3_notif_types_from_py_list( + PyObject *py_notif_types) +{ + enum bt_notification_type *notification_types = NULL; + size_t i; + + assert(!PyErr_Occurred()); + + if (py_notif_types == Py_None) { + goto end; + } + + assert(PyList_Check(py_notif_types)); + notification_types = g_new0(enum bt_notification_type, + PyList_Size(py_notif_types) + 1); + assert(notification_types); + notification_types[PyList_Size(py_notif_types)] = + BT_NOTIFICATION_TYPE_SENTINEL; + + for (i = 0; i < PyList_Size(py_notif_types); i++) { + PyObject *item = PyList_GetItem(py_notif_types, i); + long value; + int overflow; + + assert(item); + assert(PyLong_Check(item)); + value = PyLong_AsLongAndOverflow(item, &overflow); + assert(overflow == 0); + notification_types[i] = value; + } + +end: + return notification_types; +} +%} + /* Per-module interface files */ %include "native_btccpriomap.i" %include "native_btclockclass.i" diff --git a/bindings/python/bt2/bt2/native_btconnection.i b/bindings/python/bt2/bt2/native_btconnection.i index e9c1ab90..2432549f 100644 --- a/bindings/python/bt2/bt2/native_btconnection.i +++ b/bindings/python/bt2/bt2/native_btconnection.i @@ -64,7 +64,7 @@ struct bt_py3_create_notif_iter_ret { struct bt_notification_iterator *notif_iter; }; -static struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter( +static struct bt_py3_create_notif_iter_ret bt_py3_create_priv_conn_notif_iter( unsigned long long priv_conn_addr, PyObject *py_notif_types) { struct bt_private_connection *priv_conn; @@ -75,39 +75,14 @@ static struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter( assert(!PyErr_Occurred()); assert(priv_conn); - if (py_notif_types != Py_None) { - size_t i; - - assert(PyList_Check(py_notif_types)); - notification_types = g_new0(enum bt_notification_type, - PyList_Size(py_notif_types) + 1); - assert(notification_types); - notification_types[PyList_Size(py_notif_types)] = - BT_NOTIFICATION_TYPE_SENTINEL; - - for (i = 0; i < PyList_Size(py_notif_types); i++) { - PyObject *item = PyList_GetItem(py_notif_types, i); - long value; - int overflow; - - assert(item); - assert(PyLong_Check(item)); - value = PyLong_AsLongAndOverflow(item, &overflow); - assert(overflow == 0); - notification_types[i] = value; - } - } - + notification_types = bt_py3_notif_types_from_py_list(py_notif_types); ret.status = bt_private_connection_create_notification_iterator( priv_conn, notification_types, &ret.notif_iter); - - if (notification_types) { - g_free(notification_types); - } + g_free(notification_types); return ret; } %} -struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter( +struct bt_py3_create_notif_iter_ret bt_py3_create_priv_conn_notif_iter( unsigned long long priv_conn_addr, PyObject *notif_types); diff --git a/bindings/python/bt2/bt2/native_btnotifiter.i b/bindings/python/bt2/bt2/native_btnotifiter.i index 13cc9987..8963ec99 100644 --- a/bindings/python/bt2/bt2/native_btnotifiter.i +++ b/bindings/python/bt2/bt2/native_btnotifiter.i @@ -47,6 +47,11 @@ enum bt_notification_iterator_status bt_notification_iterator_next( struct bt_component *bt_private_connection_notification_iterator_get_component( struct bt_notification_iterator *iterator); +/* Functions (output port) */ +struct bt_notification_iterator *bt_output_port_notification_iterator_create( + struct bt_port *port, const char *colander_component_name, + const enum bt_notification_type *notification_types); + /* Helper functions for Python */ %{ static PyObject *bt_py3_get_user_component_from_user_notif_iter( diff --git a/bindings/python/bt2/bt2/native_btport.i b/bindings/python/bt2/bt2/native_btport.i index e88de583..c2b9867b 100644 --- a/bindings/python/bt2/bt2/native_btport.i +++ b/bindings/python/bt2/bt2/native_btport.i @@ -58,3 +58,28 @@ enum bt_port_status bt_private_port_remove_from_component( struct bt_private_port *private_port); void *bt_private_port_get_user_data( struct bt_private_port *private_port); + +%{ +static struct bt_notification_iterator *bt_py3_create_output_port_notif_iter( + unsigned long long port_addr, const char *colander_name, + PyObject *py_notif_types) +{ + struct bt_notification_iterator *notif_iter; + struct bt_port *output_port; + enum bt_notification_type *notification_types; + + output_port = (void *) port_addr; + assert(!PyErr_Occurred()); + assert(output_port); + + notification_types = bt_py3_notif_types_from_py_list(py_notif_types); + notif_iter = bt_output_port_notification_iterator_create(output_port, + colander_name, notification_types); + g_free(notification_types); + return notif_iter; +} +%} + +struct bt_notification_iterator *bt_py3_create_output_port_notif_iter( + unsigned long long port_addr, const char *colander_name, + PyObject *py_notif_types); diff --git a/bindings/python/bt2/bt2/notification.py b/bindings/python/bt2/bt2/notification.py index 2ad84878..c144ed4b 100644 --- a/bindings/python/bt2/bt2/notification.py +++ b/bindings/python/bt2/bt2/notification.py @@ -39,6 +39,19 @@ def _create_from_ptr(ptr): return _NOTIF_TYPE_TO_CLS[notif_type]._create_from_ptr(ptr) +def _notif_types_from_notif_classes(notification_types): + if notification_types is None: + notif_types = None + else: + for notif_cls in notification_types: + if notif_cls not in _NOTIF_TYPE_TO_CLS.values(): + raise ValueError("'{}' is not a notification class".format(notif_cls)) + + notif_types = [notif_cls._TYPE for notif_cls in notification_types] + + return notif_types + + class _Notification(object._Object): pass diff --git a/bindings/python/bt2/bt2/notification_iterator.py b/bindings/python/bt2/bt2/notification_iterator.py index 99bc8136..363f62d2 100644 --- a/bindings/python/bt2/bt2/notification_iterator.py +++ b/bindings/python/bt2/bt2/notification_iterator.py @@ -68,6 +68,10 @@ class _PrivateConnectionNotificationIterator(_GenericNotificationIterator): return bt2.component._create_generic_component_from_ptr(comp_ptr) +class _OutputPortNotificationIterator(_GenericNotificationIterator): + pass + + class _UserNotificationIterator(_NotificationIterator): def __new__(cls, ptr): # User iterator objects are always created by the native side, diff --git a/bindings/python/bt2/bt2/port.py b/bindings/python/bt2/bt2/port.py index ed168c4a..2cbcda52 100644 --- a/bindings/python/bt2/bt2/port.py +++ b/bindings/python/bt2/bt2/port.py @@ -24,6 +24,8 @@ from bt2 import native_bt, object, utils import collections.abc import bt2.component import bt2.connection +import bt2.notification_iterator +import bt2.notification import copy import bt2 @@ -112,7 +114,21 @@ class _InputPort(_Port): class _OutputPort(_Port): - pass + def create_notification_iterator(self, notification_types=None, + colander_component_name=None): + notif_types = bt2.notification._notif_types_from_notif_classes(notification_types) + + if colander_component_name is not None: + utils._check_str(colander_component_name) + + notif_iter_ptr = native_bt.py3_create_output_port_notif_iter(int(self._ptr), + colander_component_name, + notif_types) + + if notif_iter_ptr is None: + raise bt2.CreationError('cannot create output port notification iterator') + + return bt2.notification_iterator._OutputPortNotificationIterator._create_from_ptr(notif_iter_ptr) class _PrivatePort(object._PrivateObject, _Port): -- 2.34.1