summaryrefslogtreecommitdiffstats
path: root/engine
diff options
context:
space:
mode:
authorancarola <raffaele.ancarola@epfl.ch>2019-01-23 23:46:30 +0100
committerancarola <raffaele.ancarola@epfl.ch>2019-01-23 23:46:30 +0100
commite41dcda98ca49f1c21f89c5a8ad8ce4a95c40641 (patch)
tree5b95562eb53ceed8f2e4ebc101cfda2361f116ea /engine
parentMerge remote-tracking branch 'nao/master' (diff)
downloadflatland-e41dcda98ca49f1c21f89c5a8ad8ce4a95c40641.tar.gz
flatland-e41dcda98ca49f1c21f89c5a8ad8ce4a95c40641.zip
Fixes on signals
Diffstat (limited to 'engine')
-rw-r--r--engine/flatcomponent.cpp19
-rw-r--r--engine/flatsurface.cpp36
-rw-r--r--engine/include/core/signal.hpp108
-rw-r--r--engine/include/flatcomponent.h16
-rw-r--r--engine/include/flatsurface.h17
-rw-r--r--engine/labelled.cpp2
-rw-r--r--engine/signal.cpp72
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)