summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--engine/flatland.cpp4
-rw-r--r--engine/flatserial.cpp2
-rw-r--r--engine/focusable.cpp2
-rw-r--r--engine/include/core/labelled.hpp26
-rw-r--r--engine/include/core/object.hpp38
-rw-r--r--engine/include/core/signal.hpp64
-rw-r--r--engine/include/flatcollector.h2
-rw-r--r--engine/include/flatcomponent.h5
-rw-r--r--engine/include/flatland.h20
-rw-r--r--engine/include/flatsurface.h2
-rw-r--r--engine/include/flatwindow.h2
-rw-r--r--engine/labelled.cpp20
-rw-r--r--engine/object.cpp62
-rw-r--r--engine/signal.cpp127
14 files changed, 191 insertions, 185 deletions
diff --git a/engine/flatland.cpp b/engine/flatland.cpp
index 97829a4..badc8a2 100644
--- a/engine/flatland.cpp
+++ b/engine/flatland.cpp
@@ -9,8 +9,8 @@
using namespace std;
-#include "task.hpp"
-#include "signal.h"
+#include "core/task.hpp"
+#include "core/signal.hpp"
#include "flatwindow.h"
#include "flatexception.h"
#include "exceptions/forcequit.h"
diff --git a/engine/flatserial.cpp b/engine/flatserial.cpp
index 826e001..2413bb5 100644
--- a/engine/flatserial.cpp
+++ b/engine/flatserial.cpp
@@ -1,5 +1,5 @@
#include "flatserial.h"
-#include "task.hpp"
+#include "core/task.hpp"
SDL_EventCollector::SDL_EventCollector()
{
diff --git a/engine/focusable.cpp b/engine/focusable.cpp
index d6fa84b..5638621 100644
--- a/engine/focusable.cpp
+++ b/engine/focusable.cpp
@@ -1,5 +1,5 @@
#include "serial/focusable.h"
-#include "task.hpp"
+#include "core/task.hpp"
#include "flatserial.h"
Focusable::Focusable(bool focused) : focused(focused)
diff --git a/engine/include/core/labelled.hpp b/engine/include/core/labelled.hpp
new file mode 100644
index 0000000..8b458b3
--- /dev/null
+++ b/engine/include/core/labelled.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <list>
+#include <vector>
+#include <string>
+#include <initializer_list>
+
+#include "types.hpp"
+
+namespace flat
+{
+ namespace core
+ {
+ class labelled;
+ }
+}
+
+struct flat::core::labelled
+{
+ const std::string label;
+
+ labelled(const std::string& label = "", bool allow_null = false);
+
+ static std::string random_label(uint8_t length = 8);
+};
+
diff --git a/engine/include/core/object.hpp b/engine/include/core/object.hpp
index 1992d2a..cd5da5e 100644
--- a/engine/include/core/object.hpp
+++ b/engine/include/core/object.hpp
@@ -1,42 +1,12 @@
#pragma once
-#include <list>
-#include <vector>
-#include <string>
-#include <initializer_list>
-
-#include "types.hpp"
-
namespace flat
{
namespace core
{
- class object;
+ struct object
+ {
+ // it exists
+ };
}
}
-
-class flat::core::object
-{
- std::string id;
-
- /* Common list of objects */
- static std::list<object*> all_objects;
-
-public:
-
- object();
- ~object();
-
- void set_id(const std::string&);
-
- const std::string& get_id() const;
-
- /* Static accessors to allObject */
-
- static bool is_allocated(object*);
-
- static std::vector<object*>& get_by_id(const std::string& id, std::vector<object*>&);
-
- static std::string random_id(uint8_t length = 8);
-};
-
diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp
index 2393bc7..be1644a 100644
--- a/engine/include/core/signal.hpp
+++ b/engine/include/core/signal.hpp
@@ -6,75 +6,94 @@
#include <initializer_list>
#include "object.hpp"
#include "task.hpp"
-#include "types.h"
+#include "types.hpp"
#include <functional>
+#include <memory>
#include "priority.hpp"
+#include "labelled.hpp"
namespace flat
{
namespace core
{
- class signal : virtual public object, public prioritized
+ class signal : virtual public labelled, virtual public prioritized
{
public:
object * sender;
- void * data; // TODO, avoid this void pointer
+ package m_package;
priority_t prior;
signal( object * sender,
const std::string& id = "",
- void * data,
+ void * data = 0,
priority_t prior = priority_t::none);
/* Alias to flat::core::channel::emit() */
bool emit(const std::string& channel) const;
+
+ struct package
+ {
+ package(void *data) : data(data) {}
+
+ template<class T>
+ T * get() {
+
+ return dynamic_cast<T>(data);
+ }
+
+ void * data;
+ };
};
/* Channel class */
- class channel : virtual public object
+ class channel : virtual public labelled
{
/* Post processing signal stacking */
queue<signal> stack;
/* Listeners list */
- std::list<listener*> listeners;
+ std::list<std::weak_ptr<listener>> listeners;
/* Synchronous task checking for signals */
- task * checker;
+ task::ptr checker;
/* Channel mapping */
- static std::map<std::string, channel*> channels;
+ static std::map<std::string, std::weak_ptr<channel>> channels;
public:
channel(const std::string& id = "", priority_t task_priority = priority_t::none);
~channel();
+
+ void start();
+ bool map();
void emit(const signal&);
- void connect(const listener*);
- void disconnect(const listener*);
+ bool connect(listener::ptr l);
+ void disconnect(listener::ptr l);
- static channel * find_channel(const std::string&);
+ static ptr find(const std::string&);
+
+ static ptr create(const string& id, priority_t prior);
- void post_processing();
+ void check_and_call();
+
+ typedef shared_ptr<channel> ptr;
};
/* Listener class */
- class listener : virtual public object
+ class listener
{
-
std::list<std::string> filters;
bool check_in_filters(const std::string&) const;
callback_t m_callback;
-
- channel * parent;
public:
@@ -91,16 +110,17 @@ namespace flat
void invoke(const signal&);
- /* Allow to safely bind e functor */
+ /* Allow to safely bind a functor */
template<class T>
- static listener create( const (T::*method(const object*, void*))& fct,
- T* ptr,
- const std::initializer_list<std::string>& filters = {})
+ static ptr create( const (T::*method(const object*, void*))& fct,
+ T* obj,
+ const std::initializer_list<std::string>& filters = {})
{
- return listener(std::bind(fct, ptr), filters);
+ return new listener(std::bind(fct, ptr), filters);
}
- typedef std::function<void(const object*, void*)> callback_t;
+ typedef std::function<void(const object*, signal::package)> callback_t;
+ typedef shared_ptr<listener> ptr;
};
}
diff --git a/engine/include/flatcollector.h b/engine/include/flatcollector.h
index d7edf55..5b1e718 100644
--- a/engine/include/flatcollector.h
+++ b/engine/include/flatcollector.h
@@ -1,7 +1,7 @@
#ifndef __FLATCOLLECTOR_H__
#define __FLATCOLLECTOR_H__
-#include "object.hpp"
+#include "core/object.hpp"
#include <set>
class FlatCollector : virtual public flat::core::object
diff --git a/engine/include/flatcomponent.h b/engine/include/flatcomponent.h
index 807bcaa..881e34f 100644
--- a/engine/include/flatcomponent.h
+++ b/engine/include/flatcomponent.h
@@ -1,10 +1,11 @@
#ifndef __FLAT_COMPONENT_H__
#define __FLAT_COMPONENT_H__
-#include "object.hpp"
+#include "core/object.hpp"
+#include "core/labelled.hpp"
#include <string>
-class Component : virtual public flat::core::object
+class Component : virtual public flat::core::object, virtual public flat::core::labelled
{
Component * parent;
diff --git a/engine/include/flatland.h b/engine/include/flatland.h
index 27d2d12..e01201f 100644
--- a/engine/include/flatland.h
+++ b/engine/include/flatland.h
@@ -1,6 +1,8 @@
#ifndef __FLATLAND_H__
#define __FLATLAND_H__
+namespace flat {
+
class FlatWindow;
typedef void (*gameloop)(float);
@@ -38,11 +40,21 @@ struct flat_status
int init_flatland(FlatWindow*, gameloop, const flat_status&, float fps = 60);
void quit_flatland();
-/* Core channel */
+namespace core {
+
+ class job;
+ class task;
+ class channel;
+}
+
+/* Engine channels */
-class SignalChannel;
+core::channel& core_chan();
+core::channel& error_chan();
-SignalChannel * getCoreChannel();
+/* Main job access */
+
+core::job& game_job();
/* Window and status accessors */
@@ -58,4 +70,6 @@ void load_flatland_status(const flat_status&);
extern float flatland_dt;
+}
+
#endif
diff --git a/engine/include/flatsurface.h b/engine/include/flatsurface.h
index 3b64734..fff07dd 100644
--- a/engine/include/flatsurface.h
+++ b/engine/include/flatsurface.h
@@ -1,7 +1,7 @@
#ifndef __FLATSURFACE_H__
#define __FLATSURFACE_H__
-#include "object.hpp"
+#include "core/object.hpp"
#include <SDL2/SDL.h>
class FlatSurface : public flat::core::object
diff --git a/engine/include/flatwindow.h b/engine/include/flatwindow.h
index c03a3a9..37e834d 100644
--- a/engine/include/flatwindow.h
+++ b/engine/include/flatwindow.h
@@ -26,7 +26,7 @@ struct window_status
unsigned char focus:1;
};
-#include "object.hpp"
+#include "core/object.hpp"
#include "serial/keyfocusable.h"
class SDL_Window;
diff --git a/engine/labelled.cpp b/engine/labelled.cpp
new file mode 100644
index 0000000..023023e
--- /dev/null
+++ b/engine/labelled.cpp
@@ -0,0 +1,20 @@
+#include "core/labelled.hpp"
+
+#include <stdlib.h>
+
+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) {}
+
+string labelled::random_label(uint8_t length) {
+
+ string out;
+
+ for (uint8_t i = 0; i < length; ++i)
+ out += (char)(rand() % 93 + 33);
+
+ return out;
+}
+
diff --git a/engine/object.cpp b/engine/object.cpp
deleted file mode 100644
index 7134061..0000000
--- a/engine/object.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "core/object.hpp"
-
-#include <stdlib.h>
-
-using namespace std;
-using namespace flat::core;
-
-list<object*> object::all_objects;
-
-object::object()
-{
- /* Collect this object */
- object::all_objects.push_back(this);
-}
-
-object::~object()
-{
- /* Eliminate this object reference */
- object::all_objects.remove(this);
-}
-
-void object::set_id(const string& id)
-{
- this->id = id;
-}
-
-const string& object::get_id() const
-{
- return id;
-}
-
-string object::random_id(uint8_t length) {
-
- string out;
-
- for (uint8_t i = 0; i < length; ++i)
- out += (char)(rand() % 93 + 33);
-
- return out;
-}
-
-bool object::is_allocated(object *obj)
-{
- for (object * o : object::all_objects)
- {
- if (o == obj)
- return true;
- }
-
- return false;
-}
-
-vector<object*>& object::get_by_id(const string& id, vector<object*>& l)
-{
- for (object * obj : object::all_objects)
- {
- if (id == obj->get_id())
- l.push_back(obj);
- }
-
- return l;
-}
diff --git a/engine/signal.cpp b/engine/signal.cpp
index 5eac3eb..dc8dbf4 100644
--- a/engine/signal.cpp
+++ b/engine/signal.cpp
@@ -1,36 +1,33 @@
#include "core/signal.hpp"
#include <functional>
+#include "flatland.h"
using namespace std;
using namespace flat::core;
map<string, channel*> channel::channels;
-channel::channel(const string& id, priority_t prior)
+channel::channel(const string& id, priority_t prior) : labelled(id)
{
- channel * other = find_channel(id);
-
- if (!other)
- //TODO throw exception
- ;
-
- /* Initialize task, post-process, fifth priority */
- checker = new task( bind(&channel::post_processing, this),
- prior);
-
- string ID = (id.empty()) ? object::random_id() : id;
+}
- set_id(ID);
+channel::~channel()
+{
+ // by default it should be there
+ channels.erase(label);
+}
- channels.insert(pair<string, channel*>(ID, this));
+void channel::start()
+{
+ // Initialize task
+ checker = flat::game_job().delegate_task<channel>(&channel::check_and_call, this, prior);
}
-channel::~channel()
+bool channel::map()
{
- channels.erase(get_id());
+ channel * other = find_channel(label);
- /* Finalize task */
- delete checker;
+ return other ? false : channels.insert(pair<string, channel*>(label, this));
}
void channel::emit(const signal& sig)
@@ -38,52 +35,77 @@ void channel::emit(const signal& sig)
stack.insert(sig);
}
-void channel::connect(const listener* l)
+bool channel::connect(listener::ptr l)
{
/* Control not to double */
for (auto lis : listeners)
{
- if (lis == l)
- return;
+ if (lis.get() == l.get())
+ return false;
}
listeners.push_back(l);
+ return true;
}
-void channel::disconnect(const listener* l)
+void channel::disconnect(listener::ptr l)
{
listeners.remove(l);
}
+channel::ptr channel::create(const string& id, priority_t prior)
+{
+ ptr out = std::make_ptr(new channel(id, prior));
+
+ if (!out.map())
+ return nullptr;
+
+ out.start();
+
+ return out;
+}
-channel * channel::find_channel(const string& id)
+channel::ptr channel::find(const string& id)
{
if (id.empty())
- return 0;
+ return nullptr;
auto it = channels.find(id);
- return (it == channels.end()) ? 0 : (*it).second;
+ return (it == channels.end()) ? nullptr : (*it).second.lock();
}
-void channel::post_processing()
+void channel::check_and_call()
{
if (!stack.empty()) {
+ vector<weak_ptr<listener>> to_erase;
+
// TODO, maybe it exists pop
/* for each listener_s, catch signal */
- for (const auto& signal : stack)
+
+ for (auto l : listeners)
{
- for (auto l : listeners)
- l->invoke(signal);
+ listener::ptr pt;
+
+ if (pt = l.lock())
+ {
+ for (const auto& sig : stack)
+ l->invoke(sig);
+ }
+ else
+ to_erase.push_back(l);
}
+
+ /* Erase invalidated listeners */
+ for (auto e : to_erase)
+ listeners.remove(e);
- stack.clear();
+ stack.clear(); // TODO not so efficient
}
}
-
/* signal class */
signal::signal( object *sender,
@@ -91,40 +113,39 @@ signal::signal( object *sender,
void *data,
priority_t priority)
- : sender(sender), data(data), priority(priority)
+ : labelled(id, true),
+ sender(sender),
+ m_package(package(data)),
+ priority(priority)
{
- set_id(id);
}
-bool signal::emit(const string& channel) const
+bool signal::emit(const string& chan) const
{
- channel * chan = channel::find_channel(channel);
+ channel::ptr c = channel::find(chan);
- if (!chan)
+ if (!c)
return false;
/* Finally emit in channel */
- chan->emit(*this);
+ c->emit(*this);
return true;
}
-
/* listener_s class */
listener::listener( callback_t m_callback,
const initializer_list<string>& filters)
- : m_callback(m_callback), filters(filters), parent(0)
+ : m_callback(m_callback), filters(filters)
{
}
listener::~listener()
{
- if (parent != 0)
- parent->disconnect(this);
}
bool listener::check_in_filters(const string& filter) const
@@ -150,32 +171,28 @@ void listener::remove_filter(const string& f)
bool listener::connect(const string& chan)
{
- channel * c = channel::find_channel(chan);
+ channel::ptr c = channel::find(chan);
if (!c)
c->connect(this);
- parent = c;
-
- return c != 0;
+ return c;
}
-bool listener_s::disconnect(const string& chan)
+bool listener::disconnect(const string& chan)
{
- channel * c = channel::find_channel(chan);
+ channel::ptr c = channel::find_channel(chan);
if (!c)
- c->connect(this);
-
- parent = 0;
+ c->disconnect(this);
- return c != 0;
+ return c;
}
-void listener::invoke(const signal&)
+void listener::invoke(const signal& sig)
{
- if ( (!sig.get_id().empty() && check_in_filters(sig.get_id())) ||
- (sig.get_id().empty() && filters.empty()))
- m_callback(sig.sender);
+ if ( (!sig.label.empty() && check_in_filters(sig.label)) ||
+ (sig.label.empty() && filters.empty()))
+ m_callback(sig.sender, sig.m_package);
}