summaryrefslogtreecommitdiffstats
path: root/engine/include/core
diff options
context:
space:
mode:
authorancarola <raffaele.ancarola@epfl.ch>2019-01-22 23:52:04 +0100
committerancarola <raffaele.ancarola@epfl.ch>2019-01-22 23:52:04 +0100
commit23a4f6aa162cf42eae31cc6bb4486949f4aaafa7 (patch)
tree51f1abe2b3ab642784d30cd8682100e69d77d78f /engine/include/core
parentAdd include headers of libraries (diff)
downloadflatland-23a4f6aa162cf42eae31cc6bb4486949f4aaafa7.tar.gz
flatland-23a4f6aa162cf42eae31cc6bb4486949f4aaafa7.zip
Here we go
Diffstat (limited to 'engine/include/core')
-rw-r--r--engine/include/core/object.hpp42
-rw-r--r--engine/include/core/priority.hpp63
-rw-r--r--engine/include/core/signal.hpp108
-rw-r--r--engine/include/core/task.hpp38
4 files changed, 251 insertions, 0 deletions
diff --git a/engine/include/core/object.hpp b/engine/include/core/object.hpp
new file mode 100644
index 0000000..1992d2a
--- /dev/null
+++ b/engine/include/core/object.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <list>
+#include <vector>
+#include <string>
+#include <initializer_list>
+
+#include "types.hpp"
+
+namespace flat
+{
+ namespace core
+ {
+ class object;
+ }
+}
+
+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/priority.hpp b/engine/include/core/priority.hpp
new file mode 100644
index 0000000..7a23803
--- /dev/null
+++ b/engine/include/core/priority.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <set>
+
+namespace flat
+{
+ namespace core
+ {
+ enum class prior_t : unsigned
+ {
+ max = 0,
+ higher = 1,
+ high = 2,
+ none = 3,
+ low = 4,
+ lower = 5,
+ min = 6,
+ };
+
+ class prioritized
+ {
+ const prior_t m_priority;
+
+ public:
+
+ prioritized(prior_t m_priority = prior_t::none) : m_priority(m_priority) {}
+
+ const prior priority() const
+ {
+ return m_priority;
+ }
+ };
+
+ struct prior_criteria
+ {
+ bool operator()(const prioritized& a, const prioritized& b) const
+ {
+ return a.priority() < b.priority();
+ }
+ };
+
+ /* Compiler will complain if don't pass a non prioritized object */
+
+ template <class T>
+ using prior_set = std::set<T, prior_criteria>;
+
+
+ /* Equivalent but with pointers */
+
+ struct prior_ptr_criteria
+ {
+ bool operator()(const prioritized* a, const prioritized* b) const
+ {
+ return a->priority() < b->priority();
+ }
+ };
+
+ /* Compiler will complain if don't pass a non prioritized object */
+
+ template <class T>
+ using prior_ptr_set = std::set<T*, prior_criteria>;
+ }
+};
diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp
new file mode 100644
index 0000000..1057f3f
--- /dev/null
+++ b/engine/include/core/signal.hpp
@@ -0,0 +1,108 @@
+#pragma once
+
+#include <map>
+#include <list>
+#include <set>
+#include <initializer_list>
+#include "object.hpp"
+#include "task.hpp"
+#include "types.h"
+#include <functional>
+#include "priority.hpp"
+
+namespace flat
+{
+ namespace core
+ {
+
+ class signal : virtual public object, public prioritized
+ {
+
+ public:
+
+ object * sender;
+ void * data; // TODO, avoid this void pointer
+ priority prior;
+
+ signal( object * sender,
+ const std::string& id = "",
+ void * data,
+ prior_t prior = prior_t::none);
+
+ /* Alias to flat::core::channel::emit() */
+ bool emit(const std::string& channel) const;
+ };
+
+
+ /* Channel class */
+ class channel : virtual public object
+ {
+ /* Post processing signal stacking */
+ prior_set<signal> stack;
+
+ /* Listeners list */
+ std::list<listener*> listeners;
+
+ /* Synchronous task checking for signals */
+ task * checker;
+
+ /* Channel mapping */
+ static std::map<std::string, channel*> channels;
+
+ public:
+
+ channel(const std::string& id = "", prior_t priority = prior_t::none);
+ ~channel();
+
+ void emit(const signal&);
+
+ void connect(const listener*);
+ void disconnect(const listener*);
+
+ static channel * find_channel(const std::string&);
+
+ void post_processing();
+ };
+
+ /* Listener class */
+ class listener : virtual public object
+ {
+
+ std::list<std::string> filters;
+
+ bool check_in_filters(const std::string&) const;
+
+ callback_t m_callback;
+
+ channel * parent;
+
+ 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 e functor */
+ template<class T>
+ static listener create( const (T::*method(const object*, void*))& fct,
+ T* ptr,
+ const std::initializer_list<std::string>& filters = {})
+ {
+ return listener(std::bind(fct, ptr), filters);
+ }
+
+ typedef std::function<void(const object*, void*)> callback_t;
+ };
+
+ }
+}
+
diff --git a/engine/include/core/task.hpp b/engine/include/core/task.hpp
new file mode 100644
index 0000000..9422a23
--- /dev/null
+++ b/engine/include/core/task.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <functional>
+#include <set>
+
+namespace flat {
+ namespace core {
+ class task {
+ public:
+ enum class priority : unsigned {
+ max = 0,
+ high = 1,
+ none = 2,
+ low = 3,
+ min = 4,
+ };
+
+ // to pass a member function (method) use std::bind(f, obj)
+ task(std::function<void()> callback, priority p = priority::none);
+ task() = delete;
+
+ inline void operator()() const { m_callback(); }
+ friend bool operator<(const task& lhs, const task& rhs);
+
+ private:
+ const priority m_priority;
+ std::function<void()> m_callback;
+ };
+
+ struct job : public std::multiset<task> {
+ inline void add_task(task t) {
+ this->insert(t);
+ }
+
+ void invoke_tasks();
+ };
+ }
+} \ No newline at end of file