From 58720e1dc98186e79ef4e758a851b58df562f7b4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 27 Aug 2021 04:05:33 +0300 Subject: libcamera: base: signal: Support connecting signals to functors It can be useful to connect a signal to a functor, and in particular a lambda function, while still operating in the context of a receiver object (to support both object-based disconnection and queued connections to Object instances). Add a BoundMethodFunctor class to bind a functor, and a corresponding Signal::connect() function. There is no corresponding disconnect() function, as a lambda passed to connect() can't be later passed to disconnect(). Disconnection typically uses disconnect(T *object), which will cover the vast majority of use cases. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain --- include/libcamera/base/bound_method.h | 31 +++++++++++++++++++++++++++++++ include/libcamera/base/signal.h | 19 +++++++++++++++++++ 2 files changed, 50 insertions(+) (limited to 'include') diff --git a/include/libcamera/base/bound_method.h b/include/libcamera/base/bound_method.h index 76ce8017..ebd297ab 100644 --- a/include/libcamera/base/bound_method.h +++ b/include/libcamera/base/bound_method.h @@ -128,6 +128,37 @@ public: virtual R invoke(Args... args) = 0; }; +template +class BoundMethodFunctor : public BoundMethodArgs +{ +public: + using PackType = typename BoundMethodArgs::PackType; + + BoundMethodFunctor(T *obj, Object *object, Func func, + ConnectionType type = ConnectionTypeAuto) + : BoundMethodArgs(obj, object, type), func_(func) + { + } + + R activate(Args... args, bool deleteMethod = false) override + { + if (!this->object_) + return func_(args...); + + auto pack = std::make_shared(args...); + bool sync = BoundMethodBase::activatePack(pack, deleteMethod); + return sync ? pack->returnValue() : R(); + } + + R invoke(Args... args) override + { + return func_(args...); + } + +private: + Func func_; +}; + template class BoundMethodMember : public BoundMethodArgs { diff --git a/include/libcamera/base/signal.h b/include/libcamera/base/signal.h index c2521769..8d9f82f6 100644 --- a/include/libcamera/base/signal.h +++ b/include/libcamera/base/signal.h @@ -61,6 +61,25 @@ public: SignalBase::connect(new BoundMethodMember(obj, nullptr, func)); } +#ifndef __DOXYGEN__ + template::value> * = nullptr> + void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto) + { + Object *object = static_cast(obj); + SignalBase::connect(new BoundMethodFunctor(obj, object, func, type)); + } + + template::value> * = nullptr> +#else + template +#endif + void connect(T *obj, Func func) + { + SignalBase::connect(new BoundMethodFunctor(obj, nullptr, func)); + } + template void connect(R (*func)(Args...)) { -- cgit v1.2.1