diff --git a/openVulkanoCpp/Base/Event.hpp b/openVulkanoCpp/Base/Event.hpp index 59b586d..0e393ba 100644 --- a/openVulkanoCpp/Base/Event.hpp +++ b/openVulkanoCpp/Base/Event.hpp @@ -14,14 +14,22 @@ namespace openVulkanoCpp public: typedef std::function Function; + class IEventHandler + { + public: + virtual ~IEventHandler() = default; + virtual void SetInvalid() = 0; + }; + private: enum class EventHandlerType { STATIC, INSTANCED, INSTANCED_SHARED_PTR, INSTANCED_WEAK_PTR, FUNCTIONAL }; - class EventHandler + class EventHandler : public IEventHandler { const EventHandlerType type; + bool invalid; protected: - EventHandler(EventHandlerType type) : type(type) {} + EventHandler(EventHandlerType type) : type(type), invalid(false) {} virtual bool ShouldDelete(EventHandler* other) const = 0; public: @@ -30,11 +38,16 @@ namespace openVulkanoCpp bool ShouldBeDelete(EventHandler* other) const { if (other == this) return true; + if (invalid) return true; if (!other || other->type != type) return false; return ShouldDelete(other); } virtual void Notify(Arguments... args) const = 0; + + bool IsInvalid() const { return invalid; } + + void SetInvalid() override { invalid = true; } }; class StaticEventHandler final : public EventHandler @@ -182,10 +195,11 @@ namespace openVulkanoCpp } } - void Add(EventHandler* handler) + IEventHandler* Add(EventHandler* handler) { std::unique_lock lock(mutex); handlers.push_back(handler); + return handler; } public: @@ -194,57 +208,58 @@ namespace openVulkanoCpp std::shared_lock lock(mutex); for(EventHandler* handler : handlers) { - handler->Notify(args...); + if (!handler->IsInvalid()) + handler->Notify(args...); } } - void operator()(Arguments... args) + void operator()(Arguments&&... args) const { - NotifyAll(args); + NotifyAll(std::forward(args)...); } template - void RegisterHandler(Instance* instance, Method method) + IEventHandler* RegisterHandler(Instance* instance, Method method) { - Add(new InstancedEventHandler(instance, method)); + return Add(new InstancedEventHandler(instance, method)); } template void UnregisterHandler(Instance* instance, Method method) { auto handler = InstancedEventHandler(instance, method); - Remove(&handler); + Remove(&handler); } template - void operator +=(std::pair instancedMethodPair) + IEventHandler* operator +=(std::pair instancedMethodPair) { - RegisterHandler(instancedMethodPair.first, instancedMethodPair.second); - } - - template - void operator -=(std::pair instancedMethodPair) + return RegisterHandler(instancedMethodPair.first, instancedMethodPair.second); + } + + template + void operator -=(std::pair instancedMethodPair) { UnregisterHandler(instancedMethodPair.first, instancedMethodPair.second); - } - - template - void RegisterHandler(std::shared_ptr instance, Method method) - { - Add(new InstancedSharedPtrEventHandler(instance, method)); } template - void UnregisterHandler(std::shared_ptr instance, Method method) + IEventHandler* RegisterHandler(const std::shared_ptr& instance, Method method) + { + return Add(new InstancedSharedPtrEventHandler(instance, method)); + } + + template + void UnregisterHandler(const std::shared_ptr& instance, Method method) { auto handler = InstancedSharedPtrEventHandler(instance, method); Remove(&handler); } template - void operator +=(std::pair, Method> instancedMethodPair) + IEventHandler* operator +=(std::pair, Method> instancedMethodPair) { - RegisterHandler(instancedMethodPair.first, instancedMethodPair.second); + return RegisterHandler(instancedMethodPair.first, instancedMethodPair.second); } template @@ -254,85 +269,86 @@ namespace openVulkanoCpp } template - void RegisterHandler(std::weak_ptr instance, Method method) + IEventHandler* RegisterHandler(const std::weak_ptr& instance, Method method) { - Add(new InstancedWeakPtrEventHandler(instance, method)); + return Add(new InstancedWeakPtrEventHandler(instance, method)); } template - void UnregisterHandler(std::weak_ptr instance, Method method) + void UnregisterHandler(const std::weak_ptr& instance, Method method) { auto handler = InstancedWeakPtrEventHandler(instance, method); Remove(&handler); } template - void RegisterHandlerWeak(std::weak_ptr instance, Method method) + IEventHandler* RegisterHandlerWeak(const std::weak_ptr& instance, Method method) { - Add(new InstancedWeakPtrEventHandler(instance, method)); + return Add(new InstancedWeakPtrEventHandler(instance, method)); } template - void UnregisterHandlerWeak(std::weak_ptr instance, Method method) + void UnregisterHandlerWeak(const std::weak_ptr& instance, Method method) { auto handler = InstancedWeakPtrEventHandler(instance, method); Remove(&handler); } template - void operator +=(std::pair, Method> instancedMethodPair) + IEventHandler* operator +=(std::pair, Method> instancedMethodPair) { - RegisterHandlerWeak(instancedMethodPair.first, instancedMethodPair.second); + return RegisterHandlerWeak(instancedMethodPair.first, instancedMethodPair.second); } template void operator -=(std::pair, Method> instancedMethodPair) { - RegisterHandlerWeak(instancedMethodPair.first, instancedMethodPair.second); + UnregisterHandlerWeak(instancedMethodPair.first, instancedMethodPair.second); } - void RegisterHandler(void (*method)(Arguments...)) + IEventHandler* RegisterHandler(void (*method)(Arguments...)) { - handlers.push_back(new StaticEventHandler(method)); + return Add(new StaticEventHandler(method)); } void UnregisterHandler(void (*method)(Arguments...)) { - auto handler = StaticEventHandler(method); - Remove(&handler); + auto handler = StaticEventHandler(method); + Remove(&handler); } - - void operator +=(void (*method)(Arguments...)) + + IEventHandler* operator +=(void (*method)(Arguments...)) { - RegisterHandler(method); - } - - void operator -=(void (*method)(Arguments...)) + return RegisterHandler(method); + } + + void operator -=(void (*method)(Arguments...)) { UnregisterHandler(method); - } + } - EventHandler* RegisterHandler(Function function) + IEventHandler* RegisterHandler(Function function) { - FunctionalEventHandler* handler = new FunctionalEventHandler(function); - Add(handler); - return handler; + return Add(new FunctionalEventHandler(function)); } void UnregisterHandler(EventHandler* handler) { Remove(handler); } - - EventHandler* operator +=(Function function) + + IEventHandler* operator +=(Function function) { return RegisterHandler(function); - } - - void operator -=(EventHandler* handler) + } + + void operator -=(IEventHandler* handler) { - Remove(handler); - } + if (EventHandler* handlerRef = dynamic_cast(handler)) + { + Remove(handlerRef); + } + } }; template @@ -342,19 +358,19 @@ namespace openVulkanoCpp } template - constexpr std::pair, Method> EventHandler(std::shared_ptr instance, Method method) + constexpr std::pair, Method> EventHandler(const std::shared_ptr& instance, Method method) { return std::pair, Method>(instance, method); } template - constexpr std::pair, Method> EventHandler(std::weak_ptr instance, Method method) + constexpr std::pair, Method> EventHandler(const std::weak_ptr& instance, Method method) { return std::pair, Method>(instance, method); } template - constexpr std::pair, Method> EventHandlerWeak(std::weak_ptr instance, Method method) + constexpr std::pair, Method> EventHandlerWeak(const std::weak_ptr& instance, Method method) { return std::pair, Method>(instance, method); }