unsubscribe automatically at destruction

This commit is contained in:
Frank DeMarco 2019-05-18 21:25:27 -04:00
parent e45806f8bc
commit 10cc649f45
8 changed files with 53 additions and 13 deletions

View File

@ -129,9 +129,13 @@ struct Demo : Game
Mix_PlayMusic(music, -1);
load_gl_context();
delegate.subscribe(&Demo::respond, this);
// Input input = Input(this);
Input* l = new Input(this);
delete l;
// input.print_branch();
// mushroom.print_branch();
// Input* i = new Input(this);
// get_delegate().unsubscribe(i);
// delete i;
}
std::string get_class_name()

View File

@ -38,10 +38,11 @@ $(GLEW_DIR)%.o: $(GLEW_DIR)%.c $(GLEW_DIR)%.h
$(SFW_SRC_DIR)Sprite.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Location.*pp Node.*pp)
$(SFW_SRC_DIR)Game.o: $(addprefix $(SFW_SRC_DIR),Sprite.*pp Configuration.*pp Delegate.*pp Display.*pp \
Recorder.*pp Node.*pp)
$(SFW_SRC_DIR)Node.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Configuration.*pp Node.*pp)
Recorder.*pp Node.*pp Input.*pp)
$(SFW_SRC_DIR)Node.o: $(addprefix $(SFW_SRC_DIR),Game.*pp Configuration.*pp Delegate.*pp)
$(SFW_SRC_DIR)Animation.o: $(addprefix $(SFW_SRC_DIR),Timer.*pp)
$(SFW_SRC_DIR)Recorder.o: $(addprefix $(SFW_SRC_DIR),extension.*pp Node.*pp)
$(SFW_SRC_DIR)Recorder.o: $(addprefix $(SFW_SRC_DIR),extension.*pp Node.*pp Delegate.*pp)
$(SFW_SRC_DIR)Input.o: $(addprefix $(SFW_SRC_DIR),Delegate.*pp)
$(SFW_SRC_DIR)%.o: $(addprefix $(SFW_SRC_DIR),%.cpp %.hpp)
$(CPPC_LINUX) $(CPP_FLAGS) $(SDL_FLAGS) $< -o $@

View File

@ -4,7 +4,7 @@ int Delegate::command_event_type = SDL_RegisterEvents(1);
Delegate::Delegate(Node* parent) : Node(parent) {}
void Delegate::add_subscriber(subscriber s, int type)
void Delegate::add_subscriber(Subscriber s, int type)
{
if (subscribers.count(type) == 0)
{
@ -22,9 +22,9 @@ void Delegate::dispatch()
{
if (event.type == iter->first)
{
for (subscriber s : iter->second)
for (Subscriber s : iter->second)
{
s(event);
s.f(event);
}
}
}

View File

@ -5,29 +5,57 @@
#include <map>
#include <list>
#include <functional>
#include <typeinfo>
#include <typeindex>
#include "Node.hpp"
#include "SDL.h"
typedef std::function<void(SDL_Event&)> subscriber;
struct Subscriber
{
std::function<void(SDL_Event&)> f;
void* o;
};
struct Delegate : Node
{
std::map<int, std::vector<subscriber>> subscribers;
std::map<int, std::vector<Subscriber>> subscribers;
static int command_event_type;
Delegate(Node*);
void add_subscriber(subscriber, int);
void add_subscriber(Subscriber, int);
void dispatch();
bool compare(SDL_Event&, std::string);
void remove_subscriber(subscriber, int);
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), type);
add_subscriber({std::bind(f, o, std::placeholders::_1), 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++;
}
}
}
}
};

View File

@ -59,6 +59,11 @@ Game::Game()
}
}
Game::~Game()
{
get_delegate().unsubscribe(this);
}
void Game::print_error(std::string message)
{
std::cerr << message << std::endl;

View File

@ -45,6 +45,7 @@ struct Game : Node
Input input = Input(this);
Game();
~Game();
void print_error(std::string);
void print_sdl_error(std::string);
void print_gl_attributes();

View File

@ -14,6 +14,7 @@ Node::~Node()
{
std::cout << "Destructing ";
print_branch();
get_delegate().unsubscribe(this);
}
nlohmann::json& Node::get_configuration()

View File

@ -20,7 +20,7 @@ struct Node
Node();
Node(Node*);
~Node();
virtual ~Node();
Game* get_root();
nlohmann::json& get_configuration();
Delegate& get_delegate();