libcamera: object: Add connection type parameter to invokeMethod()

Allow specifying a different connection type than ConnectionTypeQueued
for Object::invokeMethod().

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Jacopo Mondi 2019-10-27 02:45:17 +02:00 committed by Laurent Pinchart
parent 06008b9156
commit fb1a5c0416
6 changed files with 21 additions and 16 deletions

View file

@ -30,12 +30,11 @@ public:
void postMessage(std::unique_ptr<Message> msg); void postMessage(std::unique_ptr<Message> msg);
template<typename T, typename... Args, typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr> template<typename T, typename... Args, typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr>
void invokeMethod(void (T::*func)(Args...), Args... args) void invokeMethod(void (T::*func)(Args...), ConnectionType type, Args... args)
{ {
T *obj = static_cast<T *>(this); T *obj = static_cast<T *>(this);
BoundMethodBase *method = BoundMethodBase *method =
new BoundMemberMethod<T, Args...>(obj, this, func, new BoundMemberMethod<T, Args...>(obj, this, func, type);
ConnectionTypeQueued);
void *pack = new typename BoundMemberMethod<T, Args...>::PackType{ args... }; void *pack = new typename BoundMemberMethod<T, Args...>::PackType{ args... };
method->activatePack(pack, true); method->activatePack(pack, true);

View file

@ -187,6 +187,7 @@ int CameraProxy::processCaptureRequest(camera3_capture_request_t *request)
void CameraProxy::threadRpcCall(ThreadRpc &rpcRequest) void CameraProxy::threadRpcCall(ThreadRpc &rpcRequest)
{ {
cameraDevice_->invokeMethod(&CameraDevice::call, &rpcRequest); cameraDevice_->invokeMethod(&CameraDevice::call, ConnectionTypeQueued,
&rpcRequest);
rpcRequest.waitDelivery(); rpcRequest.waitDelivery();
} }

View file

@ -128,7 +128,8 @@ void EventNotifier::message(Message *msg)
if (msg->type() == Message::ThreadMoveMessage) { if (msg->type() == Message::ThreadMoveMessage) {
if (enabled_) { if (enabled_) {
setEnabled(false); setEnabled(false);
invokeMethod(&EventNotifier::setEnabled, true); invokeMethod(&EventNotifier::setEnabled,
ConnectionTypeQueued, true);
} }
} }

View file

@ -139,14 +139,15 @@ void Object::message(Message *msg)
} }
/** /**
* \fn void Object::invokeMethod(void (T::*func)(Args...), Args... args) * \fn void Object::invokeMethod()
* \brief Invoke a method asynchronously on an Object instance * \brief Invoke a method asynchronously on an Object instance
* \param[in] func The object method to invoke * \param[in] func The object method to invoke
* \param[in] type Connection type for method invocation
* \param[in] args The method arguments * \param[in] args The method arguments
* *
* This method invokes the member method \a func when control returns to the * This method invokes the member method \a func with arguments \a args, based
* event loop of the object's thread. The method is executed in the object's * on the connection \a type. Depending on the type, the method will be called
* thread with arguments \a args. * synchronously in the same thread or asynchronously in the object's thread.
* *
* Arguments \a args passed by value or reference are copied, while pointers * Arguments \a args passed by value or reference are copied, while pointers
* are passed untouched. The caller shall ensure that any pointer argument * are passed untouched. The caller shall ensure that any pointer argument

View file

@ -170,7 +170,8 @@ void Timer::message(Message *msg)
if (msg->type() == Message::ThreadMoveMessage) { if (msg->type() == Message::ThreadMoveMessage) {
if (isRunning()) { if (isRunning()) {
unregisterTimer(); unregisterTimer();
invokeMethod(&Timer::registerTimer); invokeMethod(&Timer::registerTimer,
ConnectionTypeQueued);
} }
} }

View file

@ -64,10 +64,11 @@ protected:
InvokedObject object; InvokedObject object;
/* /*
* Test that method invocation in the same thread goes through * Test that queued method invocation in the same thread goes
* the event dispatcher. * through the event dispatcher.
*/ */
object.invokeMethod(&InvokedObject::method, 42); object.invokeMethod(&InvokedObject::method,
ConnectionTypeQueued, 42);
if (object.status() != InvokedObject::NoCall) { if (object.status() != InvokedObject::NoCall) {
cerr << "Method not invoked asynchronously" << endl; cerr << "Method not invoked asynchronously" << endl;
@ -93,15 +94,16 @@ protected:
} }
/* /*
* Move the object to a thread and verify that the method is * Move the object to a thread and verify that auto method
* delivered in the correct thread. * invocation is delivered in the correct thread.
*/ */
object.reset(); object.reset();
object.moveToThread(&thread_); object.moveToThread(&thread_);
thread_.start(); thread_.start();
object.invokeMethod(&InvokedObject::method, 42); object.invokeMethod(&InvokedObject::method,
ConnectionTypeAuto, 42);
this_thread::sleep_for(chrono::milliseconds(100)); this_thread::sleep_for(chrono::milliseconds(100));
switch (object.status()) { switch (object.status()) {