diff options
-rw-r--r-- | include/libcamera/object.h | 4 | ||||
-rw-r--r-- | include/libcamera/signal.h | 55 | ||||
-rw-r--r-- | src/libcamera/signal.cpp | 8 |
3 files changed, 40 insertions, 27 deletions
diff --git a/include/libcamera/object.h b/include/libcamera/object.h index d61dfb1e..5c251a82 100644 --- a/include/libcamera/object.h +++ b/include/libcamera/object.h @@ -13,9 +13,10 @@ namespace libcamera { class Message; -class SignalBase; template<typename... Args> class Signal; +class SignalBase; +class SlotBase; class Thread; class Object @@ -33,6 +34,7 @@ public: private: template<typename... Args> friend class Signal; + friend class SlotBase; friend class Thread; void connect(SignalBase *signal); diff --git a/include/libcamera/signal.h b/include/libcamera/signal.h index 11ffb857..d3be3626 100644 --- a/include/libcamera/signal.h +++ b/include/libcamera/signal.h @@ -18,23 +18,28 @@ namespace libcamera { template<typename... Args> class Signal; +class SignalBase; class SlotBase { public: - SlotBase(void *obj, bool isObject) - : obj_(obj), isObject_(isObject) {} + SlotBase(void *obj, Object *object) + : obj_(obj), object_(object) {} virtual ~SlotBase() {} - void *obj() { return obj_; } - bool isObject() const { return isObject_; } + template<typename T> + bool match(T *obj) { return obj == obj_; } + template<> + bool match(Object *object) { return object == object_; } + + void disconnect(SignalBase *signal); void activatePack(void *pack); virtual void invokePack(void *pack) = 0; protected: void *obj_; - bool isObject_; + Object *object_; }; template<typename... Args> @@ -71,8 +76,8 @@ private: } public: - SlotArgs(void *obj, bool isObject) - : SlotBase(obj, isObject) {} + SlotArgs(void *obj, Object *object) + : SlotBase(obj, object) {} void invokePack(void *pack) override { @@ -89,12 +94,12 @@ class SlotMember : public SlotArgs<Args...> public: using PackType = std::tuple<typename std::remove_reference<Args>::type...>; - SlotMember(T *obj, bool isObject, void (T::*func)(Args...)) - : SlotArgs<Args...>(obj, isObject), func_(func) {} + SlotMember(T *obj, Object *object, void (T::*func)(Args...)) + : SlotArgs<Args...>(obj, object), func_(func) {} void activate(Args... args) { - if (this->isObject_) + if (this->object_) SlotBase::activatePack(new PackType{ args... }); else (static_cast<T *>(this->obj_)->*func_)(args...); @@ -115,7 +120,7 @@ class SlotStatic : public SlotArgs<Args...> { public: SlotStatic(void (*func)(Args...)) - : SlotArgs<Args...>(nullptr, false), func_(func) {} + : SlotArgs<Args...>(nullptr, nullptr), func_(func) {} void activate(Args... args) { (*func_)(args...); } void invoke(Args... args) {} @@ -129,11 +134,11 @@ class SignalBase { public: template<typename T> - void disconnect(T *object) + void disconnect(T *obj) { for (auto iter = slots_.begin(); iter != slots_.end(); ) { SlotBase *slot = *iter; - if (slot->obj() == object) { + if (slot->match(obj)) { iter = slots_.erase(iter); delete slot; } else { @@ -155,27 +160,27 @@ public: ~Signal() { for (SlotBase *slot : slots_) { - if (slot->isObject()) - static_cast<Object *>(slot->obj())->disconnect(this); + slot->disconnect(this); delete slot; } } #ifndef __DOXYGEN__ template<typename T, typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr> - void connect(T *object, void (T::*func)(Args...)) + void connect(T *obj, void (T::*func)(Args...)) { + Object *object = static_cast<Object *>(obj); object->connect(this); - slots_.push_back(new SlotMember<T, Args...>(object, true, func)); + slots_.push_back(new SlotMember<T, Args...>(obj, object, func)); } template<typename T, typename std::enable_if<!std::is_base_of<Object, T>::value>::type * = nullptr> #else template<typename T> #endif - void connect(T *object, void (T::*func)(Args...)) + void connect(T *obj, void (T::*func)(Args...)) { - slots_.push_back(new SlotMember<T, Args...>(object, false, func)); + slots_.push_back(new SlotMember<T, Args...>(obj, nullptr, func)); } void connect(void (*func)(Args...)) @@ -191,23 +196,23 @@ public: } template<typename T> - void disconnect(T *object) + void disconnect(T *obj) { - SignalBase::disconnect(object); + SignalBase::disconnect(obj); } template<typename T> - void disconnect(T *object, void (T::*func)(Args...)) + void disconnect(T *obj, void (T::*func)(Args...)) { for (auto iter = slots_.begin(); iter != slots_.end(); ) { SlotArgs<Args...> *slot = static_cast<SlotArgs<Args...> *>(*iter); /* - * If the obj() pointer matches the object, the slot is + * If the object matches the slot, the slot is * guaranteed to be a member slot, so we can safely * cast it to SlotMember<T, Args...> and access its * func_ member. */ - if (slot->obj() == object && + if (slot->match(obj) && static_cast<SlotMember<T, Args...> *>(slot)->func_ == func) { iter = slots_.erase(iter); delete slot; @@ -221,7 +226,7 @@ public: { for (auto iter = slots_.begin(); iter != slots_.end(); ) { SlotArgs<Args...> *slot = *iter; - if (slot->obj() == nullptr && + if (slot->match(nullptr) && static_cast<SlotStatic<Args...> *>(slot)->func_ == func) { iter = slots_.erase(iter); delete slot; diff --git a/src/libcamera/signal.cpp b/src/libcamera/signal.cpp index 53c18535..ab7dba50 100644 --- a/src/libcamera/signal.cpp +++ b/src/libcamera/signal.cpp @@ -57,9 +57,15 @@ namespace libcamera { * passed through the signal will remain valid after the signal is emitted. */ +void SlotBase::disconnect(SignalBase *signal) +{ + if (object_) + object_->disconnect(signal); +} + void SlotBase::activatePack(void *pack) { - Object *obj = static_cast<Object *>(obj_); + Object *obj = static_cast<Object *>(object_); if (Thread::current() == obj->thread()) { invokePack(pack); |