7 #ifndef __LIBCAMERA_BOUND_METHOD_H__ 8 #define __LIBCAMERA_BOUND_METHOD_H__ 12 #include <type_traits> 26 class BoundMethodPackBase
29 virtual ~BoundMethodPackBase() =
default;
32 template<
typename R,
typename... Args>
33 class BoundMethodPack :
public BoundMethodPackBase
36 BoundMethodPack(
const Args &... args)
41 std::tuple<typename std::remove_reference_t<Args>...> args_;
45 template<
typename... Args>
46 class BoundMethodPack<void, Args...> :
public BoundMethodPackBase
49 BoundMethodPack(
const Args &... args)
54 std::tuple<typename std::remove_reference_t<Args>...> args_;
61 : obj_(obj), object_(
object), connectionType_(type)
64 virtual ~BoundMethodBase() =
default;
66 template<typename T, typename std::enable_if_t<!std::is_same<Object, T>::value> * =
nullptr>
67 bool match(T *obj) {
return obj == obj_; }
68 bool match(
Object *
object) {
return object == object_; }
70 Object *object()
const {
return object_; }
72 virtual void invokePack(BoundMethodPackBase *pack) = 0;
75 bool activatePack(std::shared_ptr<BoundMethodPackBase> pack,
85 template<
typename R,
typename... Args>
86 class BoundMethodArgs :
public BoundMethodBase
89 using PackType = BoundMethodPack<R, Args...>;
92 template<std::size_t... I>
93 void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
95 PackType *args =
static_cast<PackType *
>(pack);
96 args->ret_ = invoke(std::get<I>(args->args_)...);
101 : BoundMethodBase(obj,
object, type) {}
103 void invokePack(BoundMethodPackBase *pack)
override 105 invokePack(pack, std::make_index_sequence<
sizeof...(Args)>{});
108 virtual R activate(Args... args,
bool deleteMethod =
false) = 0;
109 virtual R invoke(Args... args) = 0;
112 template<
typename... Args>
113 class BoundMethodArgs<void, Args...> :
public BoundMethodBase
116 using PackType = BoundMethodPack<void, Args...>;
119 template<std::size_t... I>
120 void invokePack(BoundMethodPackBase *pack, std::index_sequence<I...>)
123 PackType *args [[gnu::unused]] =
static_cast<PackType *
>(pack);
124 invoke(std::get<I>(args->args_)...);
129 : BoundMethodBase(obj,
object, type) {}
131 void invokePack(BoundMethodPackBase *pack)
override 133 invokePack(pack, std::make_index_sequence<
sizeof...(Args)>{});
136 virtual void activate(Args... args,
bool deleteMethod =
false) = 0;
137 virtual void invoke(Args... args) = 0;
140 template<
typename T,
typename R,
typename... Args>
141 class BoundMethodMember :
public BoundMethodArgs<R, Args...>
144 using PackType =
typename BoundMethodArgs<R, Args...>::PackType;
146 BoundMethodMember(T *obj,
Object *
object, R (T::*func)(Args...),
148 : BoundMethodArgs<R, Args...>(obj, object, type), func_(func)
152 bool match(R (T::*func)(Args...))
const {
return func == func_; }
154 R activate(Args... args,
bool deleteMethod =
false)
override 156 if (!this->object_) {
157 T *obj =
static_cast<T *
>(this->obj_);
158 return (obj->*func_)(args...);
161 auto pack = std::make_shared<PackType>(args...);
162 bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
163 return sync ? pack->ret_ : R();
166 R invoke(Args... args)
override 168 T *obj =
static_cast<T *
>(this->obj_);
169 return (obj->*func_)(args...);
173 R (T::*func_)(Args...);
176 template<
typename T,
typename... Args>
177 class BoundMethodMember<T, void, Args...> :
public BoundMethodArgs<void, Args...>
180 using PackType =
typename BoundMethodArgs<void, Args...>::PackType;
182 BoundMethodMember(T *obj,
Object *
object,
void (T::*func)(Args...),
184 : BoundMethodArgs<void, Args...>(obj, object, type), func_(func)
188 bool match(
void (T::*func)(Args...))
const {
return func == func_; }
190 void activate(Args... args,
bool deleteMethod =
false)
override 192 if (!this->object_) {
193 T *obj =
static_cast<T *
>(this->obj_);
194 return (obj->*func_)(args...);
197 auto pack = std::make_shared<PackType>(args...);
198 BoundMethodBase::activatePack(pack, deleteMethod);
201 void invoke(Args... args)
override 203 T *obj =
static_cast<T *
>(this->obj_);
204 return (obj->*func_)(args...);
208 void (T::*func_)(Args...);
211 template<
typename R,
typename... Args>
212 class BoundMethodStatic :
public BoundMethodArgs<R, Args...>
215 BoundMethodStatic(R (*func)(Args...))
221 bool match(R (*func)(Args...))
const {
return func == func_; }
223 R activate(Args... args, [[maybe_unused]]
bool deleteMethod =
false)
override 225 return (*func_)(args...);
228 R invoke(Args...)
override ConnectionType
Connection type for asynchronous communication.
Definition: bound_method.h:19
Top-level libcamera namespace.
Definition: bound_method.h:15
The receiver is invoked synchronously.
Definition: bound_method.h:23
The receiver is invoked asynchronously.
Definition: bound_method.h:22
The receiver is invoked immediately and synchronously in the sender's thread.
Definition: bound_method.h:21
Base object to support automatic signal disconnection.
Definition: object.h:24
If the sender and the receiver live in the same thread, ConnectionTypeDirect is used. Otherwise ConnectionTypeQueued is used.
Definition: bound_method.h:20