7 #ifndef __LIBCAMERA_BOUND_METHOD_H__
8 #define __LIBCAMERA_BOUND_METHOD_H__
12 #include <type_traits>
26 class BoundMethodPackBase
29 virtual ~BoundMethodPackBase() {}
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_;
60 BoundMethodBase(
void *obj, Object *
object, ConnectionType type)
61 : obj_(obj), object_(object), connectionType_(type)
64 virtual ~BoundMethodBase() {}
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_)...);
100 BoundMethodArgs(
void *obj, Object *
object, ConnectionType type)
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_)...);
128 BoundMethodArgs(
void *obj, Object *
object, ConnectionType type)
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...),
147 ConnectionType type = ConnectionTypeAuto)
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
157 return (
static_cast<T *
>(this->obj_)->*func_)(args...);
159 auto pack = std::make_shared<PackType>(args...);
160 bool sync = BoundMethodBase::activatePack(pack, deleteMethod);
161 return sync ? pack->ret_ : R();
164 R invoke(Args... args)
override
166 return (
static_cast<T *
>(this->obj_)->*func_)(args...);
170 R (T::*func_)(Args...);
173 template<
typename T,
typename... Args>
174 class BoundMethodMember<T, void, Args...> :
public BoundMethodArgs<void, Args...>
177 using PackType =
typename BoundMethodArgs<
void *, Args...>::PackType;
179 BoundMethodMember(T *obj, Object *
object,
void (T::*func)(Args...),
180 ConnectionType type = ConnectionTypeAuto)
181 : BoundMethodArgs<void, Args...>(obj, object, type), func_(func)
185 bool match(
void (T::*func)(Args...))
const {
return func == func_; }
187 void activate(Args... args,
bool deleteMethod =
false)
override
190 return (
static_cast<T *
>(this->obj_)->*func_)(args...);
192 auto pack = std::make_shared<PackType>(args...);
193 BoundMethodBase::activatePack(pack, deleteMethod);
196 void invoke(Args... args)
override
198 (
static_cast<T *
>(this->obj_)->*func_)(args...);
202 void (T::*func_)(Args...);
205 template<
typename R,
typename... Args>
206 class BoundMethodStatic :
public BoundMethodArgs<R, Args...>
209 BoundMethodStatic(R (*func)(Args...))
215 bool match(R (*func)(Args...))
const {
return func == func_; }
217 R activate(Args... args,
bool deleteMethod =
false)
override
219 return (*func_)(args...);
222 R invoke(Args...)
override
ConnectionType
Connection type for asynchronous communication.
Definition: bound_method.h:19
@ ConnectionTypeDirect
The receiver is invoked immediately and synchronously in the sender's thread.
Definition: bound_method.h:21
@ ConnectionTypeBlocking
The receiver is invoked synchronously.
Definition: bound_method.h:23
@ ConnectionTypeAuto
If the sender and the receiver live in the same thread, ConnectionTypeDirect is used....
Definition: bound_method.h:20
@ ConnectionTypeQueued
The receiver is invoked asynchronously.
Definition: bound_method.h:22