mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-23 16:45:07 +03:00
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 <laurent.pinchart@ideasonboard.com> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>
This commit is contained in:
parent
c4e2b00d51
commit
58720e1dc9
5 changed files with 114 additions and 0 deletions
|
@ -128,6 +128,37 @@ public:
|
|||
virtual R invoke(Args... args) = 0;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename Func, typename... Args>
|
||||
class BoundMethodFunctor : public BoundMethodArgs<R, Args...>
|
||||
{
|
||||
public:
|
||||
using PackType = typename BoundMethodArgs<R, Args...>::PackType;
|
||||
|
||||
BoundMethodFunctor(T *obj, Object *object, Func func,
|
||||
ConnectionType type = ConnectionTypeAuto)
|
||||
: BoundMethodArgs<R, Args...>(obj, object, type), func_(func)
|
||||
{
|
||||
}
|
||||
|
||||
R activate(Args... args, bool deleteMethod = false) override
|
||||
{
|
||||
if (!this->object_)
|
||||
return func_(args...);
|
||||
|
||||
auto pack = std::make_shared<PackType>(args...);
|
||||
bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
|
||||
return sync ? pack->returnValue() : R();
|
||||
}
|
||||
|
||||
R invoke(Args... args) override
|
||||
{
|
||||
return func_(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
Func func_;
|
||||
};
|
||||
|
||||
template<typename T, typename R, typename... Args>
|
||||
class BoundMethodMember : public BoundMethodArgs<R, Args...>
|
||||
{
|
||||
|
|
|
@ -61,6 +61,25 @@ public:
|
|||
SignalBase::connect(new BoundMethodMember<T, R, Args...>(obj, nullptr, func));
|
||||
}
|
||||
|
||||
#ifndef __DOXYGEN__
|
||||
template<typename T, typename Func,
|
||||
typename std::enable_if_t<std::is_base_of<Object, T>::value> * = nullptr>
|
||||
void connect(T *obj, Func func, ConnectionType type = ConnectionTypeAuto)
|
||||
{
|
||||
Object *object = static_cast<Object *>(obj);
|
||||
SignalBase::connect(new BoundMethodFunctor<T, void, Func, Args...>(obj, object, func, type));
|
||||
}
|
||||
|
||||
template<typename T, typename Func,
|
||||
typename std::enable_if_t<!std::is_base_of<Object, T>::value> * = nullptr>
|
||||
#else
|
||||
template<typename T, typename Func>
|
||||
#endif
|
||||
void connect(T *obj, Func func)
|
||||
{
|
||||
SignalBase::connect(new BoundMethodFunctor<T, void, Func, Args...>(obj, nullptr, func));
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
void connect(R (*func)(Args...))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue