#pragma once #include #include #include #include struct Listener { virtual bool isValid() { return false; } virtual void call() {} virtual std::type_index get_type() { return typeid(Listener); } }; template struct BindedListener : public Listener { std::function 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 func; bool isValid() override { return static_cast(func); } void call() override { return func(); } }; template class EventDispatcher; template class EventDispatcher { public: void Register(std::function func) { auto listener = new FunctionListener; listener->func = func; m_listeners.push_back(listener); } template 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 void Register(F&& f, R* r) { auto listener = new BindedListener; 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 m_listeners; };