diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/libcamera/bound_method.h | 99 | ||||
-rw-r--r-- | include/libcamera/object.h | 6 |
2 files changed, 89 insertions, 16 deletions
diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h index a74d2c50..0a91f44a 100644 --- a/include/libcamera/bound_method.h +++ b/include/libcamera/bound_method.h @@ -28,7 +28,7 @@ public: virtual ~BoundMethodPackBase() {} }; -template<typename... Args> +template<typename R, typename... Args> class BoundMethodPack : public BoundMethodPackBase { public: @@ -38,6 +38,19 @@ public: } std::tuple<typename std::remove_reference<Args>::type...> args_; + R ret_; +}; + +template<typename... Args> +class BoundMethodPack<void, Args...> : public BoundMethodPackBase +{ +public: + BoundMethodPack(const Args &... args) + : args_(args...) + { + } + + std::tuple<typename std::remove_reference<Args>::type...> args_; }; class BoundMethodBase @@ -77,7 +90,7 @@ protected: }; #endif - void activatePack(std::shared_ptr<BoundMethodPackBase> pack, + bool activatePack(std::shared_ptr<BoundMethodPackBase> pack, bool deleteMethod); void *obj_; @@ -91,7 +104,34 @@ template<typename R, typename... Args> class BoundMethodArgs : public BoundMethodBase { public: - using PackType = BoundMethodPack<Args...>; + using PackType = BoundMethodPack<R, Args...>; + +private: + template<int... S> + void invokePack(BoundMethodPackBase *pack, BoundMethodBase::sequence<S...>) + { + PackType *args = static_cast<PackType *>(pack); + args->ret_ = invoke(std::get<S>(args->args_)...); + } + +public: + BoundMethodArgs(void *obj, Object *object, ConnectionType type) + : BoundMethodBase(obj, object, type) {} + + void invokePack(BoundMethodPackBase *pack) override + { + invokePack(pack, typename BoundMethodBase::generator<sizeof...(Args)>::type()); + } + + virtual R activate(Args... args, bool deleteMethod = false) = 0; + virtual R invoke(Args... args) = 0; +}; + +template<typename... Args> +class BoundMethodArgs<void, Args...> : public BoundMethodBase +{ +public: + using PackType = BoundMethodPack<void, Args...>; private: template<int... S> @@ -129,15 +169,45 @@ public: bool match(R (T::*func)(Args...)) const { return func == func_; } + R activate(Args... args, bool deleteMethod = false) override + { + if (!this->object_) + return (static_cast<T *>(this->obj_)->*func_)(args...); + + auto pack = std::make_shared<PackType>(args...); + bool sync = BoundMethodBase::activatePack(pack, deleteMethod); + return sync ? pack->ret_ : R(); + } + + R invoke(Args... args) override + { + return (static_cast<T *>(this->obj_)->*func_)(args...); + } + +private: + R (T::*func_)(Args...); +}; + +template<typename T, typename... Args> +class BoundMemberMethod<T, void, Args...> : public BoundMethodArgs<void, Args...> +{ +public: + using PackType = typename BoundMethodArgs<void *, Args...>::PackType; + + BoundMemberMethod(T *obj, Object *object, void (T::*func)(Args...), + ConnectionType type = ConnectionTypeAuto) + : BoundMethodArgs<void, Args...>(obj, object, type), func_(func) + { + } + + bool match(void (T::*func)(Args...)) const { return func == func_; } + void activate(Args... args, bool deleteMethod = false) override { - if (!this->object_) { - (static_cast<T *>(this->obj_)->*func_)(args...); - return; - } + if (!this->object_) + return (static_cast<T *>(this->obj_)->*func_)(args...); - std::shared_ptr<BoundMethodPackBase> pack = - std::make_shared<typename BoundMemberMethod<T, R, Args...>::PackType>(args...); + auto pack = std::make_shared<PackType>(args...); BoundMethodBase::activatePack(pack, deleteMethod); } @@ -147,7 +217,7 @@ public: } private: - R (T::*func_)(Args...); + void (T::*func_)(Args...); }; template<typename R, typename... Args> @@ -162,12 +232,15 @@ public: bool match(R (*func)(Args...)) const { return func == func_; } - void activate(Args... args, bool deleteMethod = false) override + R activate(Args... args, bool deleteMethod = false) override { - (*func_)(args...); + return (*func_)(args...); } - void invoke(Args...) override {} + R invoke(Args...) override + { + return R(); + } private: R (*func_)(Args...); diff --git a/include/libcamera/object.h b/include/libcamera/object.h index 586c2cf6..04aa1839 100644 --- a/include/libcamera/object.h +++ b/include/libcamera/object.h @@ -31,12 +31,12 @@ public: template<typename T, typename R, typename... FuncArgs, typename... Args, typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr> - void invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type, - Args... args) + R invokeMethod(R (T::*func)(FuncArgs...), ConnectionType type, + Args... args) { T *obj = static_cast<T *>(this); auto *method = new BoundMemberMethod<T, R, FuncArgs...>(obj, this, func, type); - method->activate(args..., true); + return method->activate(args..., true); } Thread *thread() const { return thread_; } |