diff options
-rw-r--r-- | Documentation/Doxyfile.in | 1 | ||||
-rw-r--r-- | include/libcamera/bound_method.h | 54 | ||||
-rw-r--r-- | src/libcamera/bound_method.cpp | 5 | ||||
-rw-r--r-- | src/libcamera/include/message.h | 5 | ||||
-rw-r--r-- | src/libcamera/message.cpp | 5 |
5 files changed, 43 insertions, 27 deletions
diff --git a/Documentation/Doxyfile.in b/Documentation/Doxyfile.in index 9e5efae3..5ae8773b 100644 --- a/Documentation/Doxyfile.in +++ b/Documentation/Doxyfile.in @@ -874,6 +874,7 @@ EXCLUDE_SYMBOLS = libcamera::BoundMemberMethod \ libcamera::BoundMethodArgs \ libcamera::BoundMethodBase \ libcamera::BoundMethodPack \ + libcamera::BoundMethodPackBase \ libcamera::BoundStaticMethod \ libcamera::SignalBase \ std::* diff --git a/include/libcamera/bound_method.h b/include/libcamera/bound_method.h index b50072ff..a74d2c50 100644 --- a/include/libcamera/bound_method.h +++ b/include/libcamera/bound_method.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_BOUND_METHOD_H__ #define __LIBCAMERA_BOUND_METHOD_H__ +#include <memory> #include <tuple> #include <type_traits> @@ -21,6 +22,24 @@ enum ConnectionType { ConnectionTypeBlocking, }; +class BoundMethodPackBase +{ +public: + virtual ~BoundMethodPackBase() {} +}; + +template<typename... Args> +class BoundMethodPack : public BoundMethodPackBase +{ +public: + BoundMethodPack(const Args &... args) + : args_(args...) + { + } + + std::tuple<typename std::remove_reference<Args>::type...> args_; +}; + class BoundMethodBase { public: @@ -36,7 +55,7 @@ public: Object *object() const { return object_; } - virtual void invokePack(void *pack) = 0; + virtual void invokePack(BoundMethodPackBase *pack) = 0; protected: #ifndef __DOXYGEN__ @@ -58,7 +77,8 @@ protected: }; #endif - void activatePack(void *pack, bool deleteMethod); + void activatePack(std::shared_ptr<BoundMethodPackBase> pack, + bool deleteMethod); void *obj_; Object *object_; @@ -67,18 +87,6 @@ private: ConnectionType connectionType_; }; -template<typename... Args> -class BoundMethodPack -{ -public: - BoundMethodPack(const Args &... args) - : args_(args...) - { - } - - std::tuple<typename std::remove_reference<Args>::type...> args_; -}; - template<typename R, typename... Args> class BoundMethodArgs : public BoundMethodBase { @@ -87,18 +95,18 @@ public: private: template<int... S> - void invokePack(void *pack, BoundMethodBase::sequence<S...>) + void invokePack(BoundMethodPackBase *pack, BoundMethodBase::sequence<S...>) { - PackType *args = static_cast<PackType *>(pack); + /* args is effectively unused when the sequence S is empty. */ + PackType *args [[gnu::unused]] = static_cast<PackType *>(pack); invoke(std::get<S>(args->args_)...); - delete args; } public: BoundMethodArgs(void *obj, Object *object, ConnectionType type) : BoundMethodBase(obj, object, type) {} - void invokePack(void *pack) override + void invokePack(BoundMethodPackBase *pack) override { invokePack(pack, typename BoundMethodBase::generator<sizeof...(Args)>::type()); } @@ -123,10 +131,14 @@ public: void activate(Args... args, bool deleteMethod = false) override { - if (this->object_) - BoundMethodBase::activatePack(new PackType{ args... }, deleteMethod); - else + if (!this->object_) { (static_cast<T *>(this->obj_)->*func_)(args...); + return; + } + + std::shared_ptr<BoundMethodPackBase> pack = + std::make_shared<typename BoundMemberMethod<T, R, Args...>::PackType>(args...); + BoundMethodBase::activatePack(pack, deleteMethod); } void invoke(Args... args) override diff --git a/src/libcamera/bound_method.cpp b/src/libcamera/bound_method.cpp index 45c76577..82339b7e 100644 --- a/src/libcamera/bound_method.cpp +++ b/src/libcamera/bound_method.cpp @@ -48,7 +48,8 @@ namespace libcamera { * deadlock will occur. */ -void BoundMethodBase::activatePack(void *pack, bool deleteMethod) +void BoundMethodBase::activatePack(std::shared_ptr<BoundMethodPackBase> pack, + bool deleteMethod) { ConnectionType type = connectionType_; if (type == ConnectionTypeAuto) { @@ -61,7 +62,7 @@ void BoundMethodBase::activatePack(void *pack, bool deleteMethod) switch (type) { case ConnectionTypeDirect: default: - invokePack(pack); + invokePack(pack.get()); if (deleteMethod) delete this; break; diff --git a/src/libcamera/include/message.h b/src/libcamera/include/message.h index 311755cc..8e8b013d 100644 --- a/src/libcamera/include/message.h +++ b/src/libcamera/include/message.h @@ -48,7 +48,8 @@ private: class InvokeMessage : public Message { public: - InvokeMessage(BoundMethodBase *method, void *pack, + InvokeMessage(BoundMethodBase *method, + std::shared_ptr<BoundMethodPackBase> pack, Semaphore *semaphore = nullptr, bool deleteMethod = false); ~InvokeMessage(); @@ -59,7 +60,7 @@ public: private: BoundMethodBase *method_; - void *pack_; + std::shared_ptr<BoundMethodPackBase> pack_; Semaphore *semaphore_; bool deleteMethod_; }; diff --git a/src/libcamera/message.cpp b/src/libcamera/message.cpp index c35bb33d..77f2bdd5 100644 --- a/src/libcamera/message.cpp +++ b/src/libcamera/message.cpp @@ -123,7 +123,8 @@ Message::Type Message::registerMessageType() * \param[in] deleteMethod True to delete the \a method when the message is * destroyed */ -InvokeMessage::InvokeMessage(BoundMethodBase *method, void *pack, +InvokeMessage::InvokeMessage(BoundMethodBase *method, + std::shared_ptr<BoundMethodPackBase> pack, Semaphore *semaphore, bool deleteMethod) : Message(Message::InvokeMessage), method_(method), pack_(pack), semaphore_(semaphore), deleteMethod_(deleteMethod) @@ -148,7 +149,7 @@ InvokeMessage::~InvokeMessage() */ void InvokeMessage::invoke() { - method_->invokePack(pack_); + method_->invokePack(pack_.get()); } /** |