# THE SOFTWARE.
from bt2 import native_bt, object, utils
-import bt2.component
-import bt2.logging
+from bt2 import interrupter as bt2_interrupter
+from bt2 import component as bt2_component
+from bt2 import logging as bt2_logging
+from bt2 import value as bt2_value
import bt2
-class QueryExecutor(object._SharedObject):
- _get_ref = staticmethod(native_bt.query_executor_get_ref)
- _put_ref = staticmethod(native_bt.query_executor_put_ref)
-
- def _handle_status(self, status, gen_error_msg):
- if status == native_bt.QUERY_EXECUTOR_STATUS_AGAIN:
- raise bt2.TryAgain
- elif status == native_bt.QUERY_EXECUTOR_STATUS_CANCELED:
- raise bt2.QueryExecutorCanceled
- elif status == native_bt.QUERY_EXECUTOR_STATUS_INVALID_OBJECT:
- raise bt2.InvalidQueryObject
- elif status == native_bt.QUERY_EXECUTOR_STATUS_INVALID_PARAMS:
- raise bt2.InvalidQueryParams
- elif status < 0:
- raise bt2.Error(gen_error_msg)
-
- def __init__(self):
- ptr = native_bt.query_executor_create()
+class _QueryExecutorCommon:
+ @property
+ def _common_ptr(self):
+ return self._as_query_executor_ptr()
- if ptr is None:
- raise bt2.CreationError('cannot create query executor object')
+ @property
+ def is_interrupted(self):
+ is_interrupted = native_bt.query_executor_is_interrupted(self._common_ptr)
+ return bool(is_interrupted)
- super().__init__(ptr)
+ @property
+ def logging_level(self):
+ return native_bt.query_executor_get_logging_level(self._common_ptr)
- def cancel(self):
- status = native_bt.query_executor_cancel(self._ptr)
- self._handle_status(status, 'cannot cancel query executor object')
- @property
- def is_canceled(self):
- is_canceled = native_bt.query_executor_is_canceled(self._ptr)
- assert(is_canceled >= 0)
- return is_canceled > 0
+class QueryExecutor(object._SharedObject, _QueryExecutorCommon):
+ _get_ref = staticmethod(native_bt.query_executor_get_ref)
+ _put_ref = staticmethod(native_bt.query_executor_put_ref)
- def query(self, component_class, object, params=None,
- logging_level=bt2.logging.LoggingLevel.NONE):
- if self.is_canceled:
- raise bt2.QueryExecutorCanceled
+ def _as_query_executor_ptr(self):
+ return self._ptr
- if not isinstance(component_class, bt2.component._GenericComponentClass):
+ def __init__(self, component_class, object, params=None, method_obj=None):
+ if not isinstance(component_class, bt2_component._ComponentClass):
err = False
try:
- if not issubclass(component_class, bt2.component._UserComponent):
+ if not issubclass(component_class, bt2_component._UserComponent):
err = True
except TypeError:
err = True
params = bt2.create_value(params)
params_ptr = params._ptr
- utils._check_log_level(logging_level)
- cc_ptr = component_class._component_class_ptr()
+ cc_ptr = component_class._bt_component_class_ptr()
+ assert cc_ptr is not None
+
+ if method_obj is not None and not native_bt.bt2_is_python_component_class(
+ cc_ptr
+ ):
+ raise ValueError(
+ 'cannot pass a Python object to a non-Python component class'
+ )
+
+ ptr = native_bt.bt2_query_executor_create(
+ cc_ptr, object, params_ptr, method_obj
+ )
+
+ if ptr is None:
+ raise bt2._MemoryError('cannot create query executor object')
+
+ super().__init__(ptr)
+
+ # Keep a reference of `method_obj` as the native query executor
+ # does not have any. This ensures that, when this object's
+ # query() method is called, the Python object still exists.
+ self._method_obj = method_obj
+
+ def add_interrupter(self, interrupter):
+ utils._check_type(interrupter, bt2_interrupter.Interrupter)
+ native_bt.query_executor_add_interrupter(self._ptr, interrupter._ptr)
+
+ def interrupt(self):
+ native_bt.query_executor_interrupt(self._ptr)
+
+ def _set_logging_level(self, log_level):
+ utils._check_log_level(log_level)
+ status = native_bt.query_executor_set_logging_level(self._ptr, log_level)
+ utils._handle_func_status(status, "cannot set query executor's logging level")
+
+ logging_level = property(
+ fget=_QueryExecutorCommon.logging_level, fset=_set_logging_level
+ )
+
+ @property
+ def is_interrupted(self):
+ is_interrupted = native_bt.query_executor_is_interrupted(self._ptr)
+ return bool(is_interrupted)
+
+ def query(self):
+ status, result_ptr = native_bt.query_executor_query(self._ptr)
+ utils._handle_func_status(status, 'cannot query component class')
+ assert result_ptr is not None
+ return bt2_value._create_from_ptr(result_ptr)
+
+
+class _PrivateQueryExecutor(_QueryExecutorCommon):
+ def __init__(self, ptr):
+ self._ptr = ptr
+
+ def _check_validity(self):
+ if self._ptr is None:
+ raise RuntimeError('this object is not valid anymore')
+
+ def _as_query_executor_ptr(self):
+ self._check_validity()
+ return native_bt.private_query_executor_as_query_executor_const(self._ptr)
- status, result_ptr = native_bt.query_executor_query(self._ptr, cc_ptr,
- object, params_ptr,
- logging_level)
- self._handle_status(status, 'cannot query component class')
- assert(result_ptr)
- return bt2.value._create_from_ptr(result_ptr)
+ def _invalidate(self):
+ self._ptr = None