Improve event handling
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user