Improve event handling

This commit is contained in:
2020-11-30 20:51:11 +01:00
parent 097669bc44
commit 37073bc9ae

View File

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