spacebox/src/Delegate.hpp

71 lines
1.9 KiB
C++

#ifndef Delegate_h_
#define Delegate_h_
#include <string>
#include <map>
#include <list>
#include <functional>
#include <typeinfo>
#include <typeindex>
#include "Node.hpp"
#include "SDL.h"
struct Subscriber
{
std::function<void(SDL_Event&)> f;
Node* o;
};
struct Delegate : Node
{
std::map<int, std::vector<Subscriber>> subscribers;
static int command_event_type;
bool cancelling_propagation = false;
Delegate(Node*);
void add_subscriber(Subscriber, int);
void dispatch();
bool compare(SDL_Event&, const std::vector<std::string>&, bool = false, bool = false);
bool compare(SDL_Event&, const std::string& = "", bool = false, bool = false);
bool compare_cancel(SDL_Event&, const std::string& = "");
bool compare_neutral(SDL_Event&, const std::string& = "");
void cancel_propagation();
const std::string& get_event_command(SDL_Event&) const;
bool get_event_cancel_state(SDL_Event&) const;
template<typename T>
void subscribe(void(T::*f)(SDL_Event&), T* o, int type = command_event_type)
{
add_subscriber({std::bind(f, o, std::placeholders::_1), static_cast<Node*>(o)}, type);
}
template<typename T>
void unsubscribe(T* p)
{
const std::type_info& info = typeid(p);
for (auto t = subscribers.begin(); t != subscribers.end(); t++)
{
for (auto s = t->second.begin(); s != t->second.end();)
{
std::cout << p << " " << s->o << " " << s->f.target_type().name() << " " << info.name() << " " <<
std::type_index(info).name() << " " <<
(s->f.target_type() == info) << std::endl;
if (p == s->o)
{
s = t->second.erase(s);
}
else
{
s++;
}
}
}
}
};
#endif