diff options
author | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-23 23:46:30 +0100 |
---|---|---|
committer | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-23 23:46:30 +0100 |
commit | e41dcda98ca49f1c21f89c5a8ad8ce4a95c40641 (patch) | |
tree | 5b95562eb53ceed8f2e4ebc101cfda2361f116ea /engine | |
parent | Merge remote-tracking branch 'nao/master' (diff) | |
download | flatland-e41dcda98ca49f1c21f89c5a8ad8ce4a95c40641.tar.gz flatland-e41dcda98ca49f1c21f89c5a8ad8ce4a95c40641.zip |
Fixes on signals
Diffstat (limited to 'engine')
-rw-r--r-- | engine/flatcomponent.cpp | 19 | ||||
-rw-r--r-- | engine/flatsurface.cpp | 36 | ||||
-rw-r--r-- | engine/include/core/signal.hpp | 108 | ||||
-rw-r--r-- | engine/include/flatcomponent.h | 16 | ||||
-rw-r--r-- | engine/include/flatsurface.h | 17 | ||||
-rw-r--r-- | engine/labelled.cpp | 2 | ||||
-rw-r--r-- | engine/signal.cpp | 72 |
7 files changed, 154 insertions, 116 deletions
diff --git a/engine/flatcomponent.cpp b/engine/flatcomponent.cpp index 06b558c..925feaa 100644 --- a/engine/flatcomponent.cpp +++ b/engine/flatcomponent.cpp @@ -1,36 +1,35 @@ #include "flatcomponent.h" #include "signal.h" -Component::Component(Component *parent, const std::string& id) - : parent(parent) +using namespace flat; + +component::component(component *parent, const std::string& id) + : m_parent(parent) { // TODO, check flatland initialization - if (id.empty()) - setID(flat::core::object::randomID()); - if (parent == 0) { // TODO set screen as parent layer } } -Component::~Component() +component::~component() { } -void Component::setParent(Component *parent) +void component::set_parent(component *parent) { if (parent == 0) // TODO set screen as parent layer ; - this->parent = parent; + this->m_parent = m_parent; } -Component * Component::getParent() +component * component::parent() { - return parent; + return m_parent; } diff --git a/engine/flatsurface.cpp b/engine/flatsurface.cpp index b3291d6..baf63e8 100644 --- a/engine/flatsurface.cpp +++ b/engine/flatsurface.cpp @@ -6,14 +6,12 @@ using namespace std; FlatSurface::FlatSurface(const char *filename, uint32_t format, SDL_Surface *parent) - : flat::core::object(), parent(parent), hide(false) + : flat::core::labelled(filename, true), parent(parent), hide(false) { - setID(filename); - cout << "FlatSurface: loading " << filename << endl; - surface = loadOptimizedSurface(filename, format); + sdl_surface = loadOptimizedSurface(filename, format); - if (!surface) + if (!sdl_surface) { cout << "Warning: could not load surface " << filename << endl; } @@ -22,36 +20,36 @@ FlatSurface::FlatSurface(const char *filename, uint32_t format, SDL_Surface *par offset->x = 0; offset->y = 0; - offset->w = surface->w; - offset->h = surface->h; + offset->w = sdl_surface->w; + offset->h = sdl_surface->h; viewport = new SDL_Rect; viewport->x = 0; viewport->y = 0; - viewport->w = surface->w; - viewport->h = surface->h; + viewport->w = sdl_surface->w; + viewport->h = sdl_surface->h; } -FlatSurface::FlatSurface(SDL_Surface *surface, SDL_Surface *parent) +FlatSurface::FlatSurface(SDL_Surface *sdl_surface, SDL_Surface *parent) : flat::core::object(), parent(parent), hide(false) { - this->surface = new SDL_Surface(*surface); + this->sdl_surface = new SDL_Surface(*sdl_surface); offset = new SDL_Rect; offset->x = 0; offset->y = 0; - offset->w = surface->w; - offset->h = surface->h; + offset->w = sdl_surface->w; + offset->h = sdl_surface->h; viewport = new SDL_Rect; viewport->x = 0; viewport->y = 0; - viewport->w = surface->w; - viewport->h = surface->h; + viewport->w = sdl_surface->w; + viewport->h = sdl_surface->h; } FlatSurface::FlatSurface(const FlatSurface &sprite) @@ -63,12 +61,12 @@ FlatSurface::FlatSurface(const FlatSurface &sprite) viewport = new SDL_Rect(*sprite.viewport); - surface = copySurface(sprite.surface); + sdl_surface = copySurface(sprite.surface); } FlatSurface::~FlatSurface() { - SDL_FreeSurface(surface); + SDL_FreeSurface(sdl_surface); delete offset; delete viewport; @@ -127,7 +125,7 @@ SDL_Surface * FlatSurface::getParent() SDL_Surface * FlatSurface::getSurface() { - return surface; + return sdl_surface; } void FlatSurface::setHidden(bool flag) @@ -143,7 +141,7 @@ bool FlatSurface::isHidden() const void FlatSurface::blit() { if (!hide) - SDL_BlitSurface(surface, viewport, parent, offset); + SDL_BlitSurface(sdl_surface, viewport, parent, offset); } SDL_Surface * FlatSurface::loadOptimizedSurface(const char *filename, uint32_t format) diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp index be1644a..8a3d639 100644 --- a/engine/include/core/signal.hpp +++ b/engine/include/core/signal.hpp @@ -21,10 +21,22 @@ namespace flat { public: + + struct package + { + package(void *data) : data(data) {} + + template<class T> + T * get() { + + return dynamic_cast<T>(data); + } + + void * data; + }; object * sender; package m_package; - priority_t prior; signal( object * sender, const std::string& id = "", @@ -33,24 +45,47 @@ namespace flat /* Alias to flat::core::channel::emit() */ bool emit(const std::string& channel) const; + }; + + /* Listener class */ + class listener + { + public: - struct package + using callback = std::function<void(const object*, signal::package)>; + using ptr = std::shared_ptr<listener>; + + listener(callback m_callback, const std::initializer_list<std::string>& filters = {}); + ~listener(); + + void add_filter(const std::string&); + void remove_filter(const std::string&); + + bool connect(const std::string&); + bool disconnect(const std::string&); + + void invoke(const signal&); + + /* Allow to safely bind a functor */ + template<typename R, typename T> + static ptr create( R T::*mf, + T& obj, + const std::initializer_list<std::string>& filters = {}) { - package(void *data) : data(data) {} + return std::make_shared<listener>(std::bind(mf, obj), filters); + } - template<class T> - T * get() { + private: - return dynamic_cast<T>(data); - } + callback m_callback; - void * data; - }; + std::list<std::string> filters; + + bool check_in_filters(const std::string&) const; }; - /* Channel class */ - class channel : virtual public labelled + class channel : virtual public labelled, public std::enable_shared_from_this<channel> { /* Post processing signal stacking */ queue<signal> stack; @@ -63,65 +98,34 @@ namespace flat /* Channel mapping */ static std::map<std::string, std::weak_ptr<channel>> channels; + + bool mapped; public: + + using ptr = std::shared_ptr<channel>; - channel(const std::string& id = "", priority_t task_priority = priority_t::none); + channel(const std::string& id = ""); ~channel(); - void start(); + void start(priority_t task_priority = priority_t::none); bool map(); void emit(const signal&); bool connect(listener::ptr l); void disconnect(listener::ptr l); + + bool connect(listener* l); + void disconnect(listener* l); static ptr find(const std::string&); - static ptr create(const string& id, priority_t prior); + static ptr create(const std::string& id, priority_t prior); void check_and_call(); - - typedef shared_ptr<channel> ptr; }; - - /* Listener class */ - class listener - { - std::list<std::string> filters; - - bool check_in_filters(const std::string&) const; - - callback_t m_callback; - - public: - - listener( callback_t m_callback, - const std::initializer_list<std::string>& filters = {}); - - ~listener(); - void add_filter(const std::string&); - void remove_filter(const std::string&); - - bool connect(const std::string&); - bool disconnect(const std::string&); - - void invoke(const signal&); - - /* Allow to safely bind a functor */ - template<class T> - static ptr create( const (T::*method(const object*, void*))& fct, - T* obj, - const std::initializer_list<std::string>& filters = {}) - { - return new listener(std::bind(fct, ptr), filters); - } - - typedef std::function<void(const object*, signal::package)> callback_t; - typedef shared_ptr<listener> ptr; - }; } } diff --git a/engine/include/flatcomponent.h b/engine/include/flatcomponent.h index 881e34f..4ad99c8 100644 --- a/engine/include/flatcomponent.h +++ b/engine/include/flatcomponent.h @@ -5,24 +5,28 @@ #include "core/labelled.hpp" #include <string> -class Component : virtual public flat::core::object, virtual public flat::core::labelled +namespace flat { + +class component : virtual public core::object, virtual public core::labelled { - Component * parent; + component * m_parent; public: /* Zero means attach to main window layer */ /* Send a 'created' signal in component reserved channel */ - Component(Component *parent = 0, const std::string& id = ""); + component(component *parent = 0, const std::string& id = ""); /* Send a 'deleted' signal in component reserved channel */ - virtual ~Component(); + virtual ~component(); - void setParent(Component*); - Component * getParent(); + void set_parent(component*); + component * parent(); virtual void render() = 0; }; +} + #endif diff --git a/engine/include/flatsurface.h b/engine/include/flatsurface.h index fff07dd..5364e8e 100644 --- a/engine/include/flatsurface.h +++ b/engine/include/flatsurface.h @@ -2,11 +2,14 @@ #define __FLATSURFACE_H__ #include "core/object.hpp" +#include "core/labelled.hpp" #include <SDL2/SDL.h> -class FlatSurface : public flat::core::object +namespace flat { + +class surface : virtual public core::object, virtual public core::labelled { - SDL_Surface * surface; + SDL_Surface * sdl_surface; SDL_Surface * parent; SDL_Rect * offset; @@ -16,12 +19,12 @@ class FlatSurface : public flat::core::object public: - FlatSurface(const char *filename, uint32_t format = SDL_PIXELFORMAT_RGBA32, SDL_Surface *parent = 0); - FlatSurface(SDL_Surface *surface, SDL_Surface *parent = 0); + surface(const char *filename, uint32_t format = SDL_PIXELFORMAT_RGBA32, SDL_Surface *parent = 0); + surface(SDL_Surface *surf, SDL_Surface *parent = 0); - FlatSurface(const FlatSurface&); + surface(const surface&); - ~FlatSurface(); + ~surface(); void setOffset(int, int, int w = -1, int h = -1); @@ -52,4 +55,6 @@ public: static SDL_Surface * copySurface(SDL_Surface*); }; +} + #endif diff --git a/engine/labelled.cpp b/engine/labelled.cpp index 023023e..48e6091 100644 --- a/engine/labelled.cpp +++ b/engine/labelled.cpp @@ -6,7 +6,7 @@ using namespace std; using namespace flat::core; labelled::labelled(const std::string& label, bool allow_null) - : label((!allow_null && label.empty()) ? object::random_label() : label) {} + : label((!allow_null && label.empty()) ? random_label() : label) {} string labelled::random_label(uint8_t length) { diff --git a/engine/signal.cpp b/engine/signal.cpp index dc8dbf4..08d69fa 100644 --- a/engine/signal.cpp +++ b/engine/signal.cpp @@ -5,29 +5,39 @@ using namespace std; using namespace flat::core; -map<string, channel*> channel::channels; +map<string, weak_ptr<channel>> channel::channels; -channel::channel(const string& id, priority_t prior) : labelled(id) +channel::channel(const string& id) : labelled(id), mapped(false) { } channel::~channel() { // by default it should be there - channels.erase(label); + if (mapped) + channels.erase(label); } -void channel::start() +void channel::start(priority_t prior) { // Initialize task - checker = flat::game_job().delegate_task<channel>(&channel::check_and_call, this, prior); + checker = flat::game_job().delegate_task(&channel::check_and_call, *this, prior); } bool channel::map() { - channel * other = find_channel(label); + if (!mapped) { - return other ? false : channels.insert(pair<string, channel*>(label, this)); + channel::ptr other = channel::find(label); + + if (!other) { + + channels.insert(pair<string, weak_ptr<channel>>(label, weak_from_this())); + mapped = true; + } + } + + return mapped; } void channel::emit(const signal& sig) @@ -40,7 +50,9 @@ bool channel::connect(listener::ptr l) /* Control not to double */ for (auto lis : listeners) { - if (lis.get() == l.get()) + auto pt = lis.lock(); + + if (pt.get() == l.get()) return false; } @@ -50,17 +62,34 @@ bool channel::connect(listener::ptr l) void channel::disconnect(listener::ptr l) { - listeners.remove(l); + listeners.remove_if( + [l](weak_ptr<listener> p){ + + listener::ptr pt = p.lock(); + return pt.get() == l.get(); + }); +} + +bool channel::connect(listener* l) +{ + listener::ptr pt(l); + return connect(pt); +} + +void channel::disconnect(listener* l) +{ + listener::ptr pt(l); + disconnect(pt); } channel::ptr channel::create(const string& id, priority_t prior) { - ptr out = std::make_ptr(new channel(id, prior)); + ptr out = std::make_shared<channel>(id); - if (!out.map()) + if (!out->map()) return nullptr; - out.start(); + out->start(prior); return out; } @@ -91,15 +120,15 @@ void channel::check_and_call() if (pt = l.lock()) { for (const auto& sig : stack) - l->invoke(sig); + pt->invoke(sig); } else to_erase.push_back(l); } /* Erase invalidated listeners */ - for (auto e : to_erase) - listeners.remove(e); + listeners.remove_if( + [](weak_ptr<listener> e) { return e.expired(); }); stack.clear(); // TODO not so efficient } @@ -114,9 +143,9 @@ signal::signal( object *sender, priority_t priority) : labelled(id, true), + prioritized(priority), sender(sender), - m_package(package(data)), - priority(priority) + m_package(package(data)) { } @@ -136,8 +165,7 @@ bool signal::emit(const string& chan) const /* listener_s class */ -listener::listener( callback_t m_callback, - const initializer_list<string>& filters) +listener::listener(callback m_callback, const initializer_list<string>& filters) : m_callback(m_callback), filters(filters) { @@ -176,17 +204,17 @@ bool listener::connect(const string& chan) if (!c) c->connect(this); - return c; + return bool(c); } bool listener::disconnect(const string& chan) { - channel::ptr c = channel::find_channel(chan); + channel::ptr c = channel::find(chan); if (!c) c->disconnect(this); - return c; + return bool(c); } void listener::invoke(const signal& sig) |