Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
graphite/engine/utility/eventdispatcher.hpp
2024-01-03 16:05:02 -05:00

109 lines
No EOL
1.9 KiB
C++

#pragma once
#include <functional>
#include <algorithm>
#include <vector>
#include <typeindex>
struct Listener
{
virtual bool isValid()
{
return false;
}
virtual void call() {}
virtual std::type_index get_type()
{
return typeid(Listener);
}
};
template<class T>
struct BindedListener : public Listener
{
std::function<void()> func;
T* caller;
bool isValid() override
{
return caller != nullptr;
}
void call() override
{
return func();
}
std::type_index get_type() override
{
return typeid(T);
}
};
struct FunctionListener : public Listener
{
std::function<void()> func;
bool isValid() override
{
return static_cast<bool>(func);
}
void call() override
{
return func();
}
};
template<class T>
class EventDispatcher;
template<class... Args>
class EventDispatcher<void(Args...)>
{
public:
void Register(std::function<void(Args...)> func)
{
auto listener = new FunctionListener;
listener->func = func;
m_listeners.push_back(listener);
}
template<class T>
void Unregister(T* t)
{
for(size_t i = 0; i < m_listeners.size(); i++)
{
if(std::type_index(typeid(T)) == m_listeners[i]->get_type())
m_listeners.erase(m_listeners.begin() + i);
}
}
template<class R, class F>
void Register(F&& f, R* r)
{
auto listener = new BindedListener<R>;
listener->caller = r;
listener->func = std::bind(f, r);
m_listeners.push_back(listener);
}
void operator()(Args&&... args)
{
//dispatch
for(size_t i = 0; i < m_listeners.size(); i++)
{
Listener* listener = m_listeners[i];
if(listener->isValid())
listener->call();
}
}
private:
std::vector<Listener*> m_listeners;
};