diff options
author | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-22 01:29:43 +0100 |
---|---|---|
committer | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-22 01:29:43 +0100 |
commit | 7170c16a463fdb1f446ab7458270205bf08e7c89 (patch) | |
tree | 58be57180690416272be1167900b74d4a56bfed2 | |
parent | Fix typo to compile (diff) | |
download | flatland-7170c16a463fdb1f446ab7458270205bf08e7c89.tar.gz flatland-7170c16a463fdb1f446ab7458270205bf08e7c89.zip |
Signal change
-rw-r--r-- | engine/flatobject.cpp | 61 | ||||
-rw-r--r-- | engine/flatsignal.cpp | 176 | ||||
-rw-r--r-- | engine/include/flatobject.h | 36 | ||||
-rw-r--r-- | engine/include/flatsignal.h | 100 | ||||
-rw-r--r-- | engine/include/object.h | 42 | ||||
-rw-r--r-- | engine/include/signal.h | 138 | ||||
-rw-r--r-- | engine/include/types.h | 4 | ||||
-rw-r--r-- | engine/object.cpp | 62 | ||||
-rw-r--r-- | engine/signal.cpp | 169 |
9 files changed, 413 insertions, 375 deletions
diff --git a/engine/flatobject.cpp b/engine/flatobject.cpp deleted file mode 100644 index a325942..0000000 --- a/engine/flatobject.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "flatobject.h" - -#include <stdlib.h> - -using namespace std; - -list<FlatObject*> FlatObject::allObjects; - -FlatObject::FlatObject() -{ - /* Collect this object */ - FlatObject::allObjects.push_back(this); -} - -FlatObject::~FlatObject() -{ - /* Eliminate this object reference */ - FlatObject::allObjects.remove(this); -} - -void FlatObject::setID(const string& id) -{ - this->id = id; -} - -const string& FlatObject::getID() const -{ - return id; -} - -string FlatObject::randomID(Uint8 length) { - - string out; - - for (Uint8 i = 0; i < length; ++i) - out += (char)(rand() % 93 + 33); - - return out; -} - -bool FlatObject::isAllocated(FlatObject *obj) -{ - for (FlatObject * o : FlatObject::allObjects) - { - if (o == obj) - return true; - } - - return false; -} - -vector<FlatObject*>& FlatObject::getByID(const string& id, vector<FlatObject*>& l) -{ - for (FlatObject * obj : FlatObject::allObjects) - { - if (id == obj->getID()) - l.push_back(obj); - } - - return l; -} diff --git a/engine/flatsignal.cpp b/engine/flatsignal.cpp deleted file mode 100644 index a739efc..0000000 --- a/engine/flatsignal.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include "flatsignal.h" -#include "flattask.h" - -using namespace std; - -bool sig_prior_cmp::operator()(const FlatSignal& s, const FlatSignal& g) const -{ - return s.priority <= g.priority; -} - -map<string, SignalChannel*> SignalChannel::channels; - -SignalChannel::SignalChannel(const string& id, bool pre_process) -{ - SignalChannel * other = findChannel(id); - - if (!other) - //TODO throw exception - ; - - /* Initialize task, post-process, fifth priority */ - checker = new FlatTask<SignalChannel>( this, - &SignalChannel::post_processing, - 0, - pre_process, - pre_process ? 2 : 10); - - string ID = (id.empty()) ? FlatObject::randomID() : id; - - setID(ID); - - channels.insert(pair<string, SignalChannel*>(ID, this)); -} - -SignalChannel::~SignalChannel() -{ - channels.erase(getID()); - - /* Finalize task */ - delete checker; -} - -void SignalChannel::emit(const FlatSignal& sig) -{ - if (!sig.priority) { - - /* Execute immediately */ - for (auto listener : listeners) - listener->execute(sig); - - } else - /* Insert in order of priority */ - stack.insert(sig); -} - -void SignalChannel::connect(FlatListener* l) -{ - /* Control not to double */ - for (auto listener : listeners) - { - if (listener == l) - return; - } - - listeners.push_back(l); -} - -void SignalChannel::disconnect(FlatListener* l) -{ - listeners.remove(l); -} - - -SignalChannel * SignalChannel::findChannel(const string& id) -{ - if (id.empty()) - return 0; - - auto it = channels.find(id); - - return (it == channels.end()) ? 0 : (*it).second; -} - -void SignalChannel::post_processing(void*) -{ - if (!stack.empty()) { - - /* for each listener, catch signal */ - for (const auto& signal : stack) - { - for (auto listener : listeners) - listener->execute(signal); - } - - stack.clear(); - } -} - - - -/* FlatSignal class */ - -FlatSignal::FlatSignal(FlatObject *sender, const string& id, void *data, Uint8 priority) - : sender(sender), data(data), priority(priority) -{ - setID(id); -} - -bool FlatSignal::emit(const string& channel) const -{ - SignalChannel * chan = SignalChannel::findChannel(channel); - - if (!chan) - return false; - - /* Finally emit in channel */ - chan->emit(*this); - - return true; -} - - - -/* FlatListener class */ - -FlatListener::FlatListener(const initializer_list<string>& filters) - : filters(filters) {} - -bool FlatListener::checkInFilters(const std::string& filter) const -{ - for (const auto& f : filters) - { - if (filter == f) - return true; - } - - return false; -} - -void FlatListener::execute(const FlatSignal& sig) -{ - if ((!sig.getID().empty() && checkInFilters(sig.getID())) || - (sig.getID().empty() && filters.empty())) - callback(sig.sender, sig.data); -} - -void FlatListener::addFilter(const std::string& f) -{ - filters.push_back(f); -} - -void FlatListener::removeFilter(const std::string& f) -{ - filters.remove(f); -} - -bool FlatListener::connect(const std::string& chan) -{ - SignalChannel * c = SignalChannel::findChannel(chan); - - if (!c) - c->connect(this); - - return c != 0; -} - -bool FlatListener::disconnect(const std::string& chan) -{ - SignalChannel * c = SignalChannel::findChannel(chan); - - if (!c) - c->connect(this); - - return c != 0; -} - diff --git a/engine/include/flatobject.h b/engine/include/flatobject.h deleted file mode 100644 index 7ad1ddd..0000000 --- a/engine/include/flatobject.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __FLATOBJECT_H__ -#define __FLATOBJECT_H__ - -#include <list> -#include <vector> -#include <string> -#include <initializer_list> - -#include "types.h" - -class FlatObject -{ - std::string id; - - /* Common list of objects */ - static std::list<FlatObject*> allObjects; - -public: - - FlatObject(); - ~FlatObject(); - - void setID(const std::string&); - - const std::string& getID() const; - - /* Static accessors to allObject */ - - static bool isAllocated(FlatObject*); - - static std::vector<FlatObject*>& getByID(const std::string& id, std::vector<FlatObject*>&); - - static std::string randomID(Uint8 length = 8); -}; - -#endif diff --git a/engine/include/flatsignal.h b/engine/include/flatsignal.h deleted file mode 100644 index b20d082..0000000 --- a/engine/include/flatsignal.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef __FLAT_SIGNAL_H__ -#define __FLAT_SIGNAL_H__ - -#include <map> -#include <list> -#include <set> -#include <initializer_list> -#include "flatobject.h" -#include "types.h" - -/* Post-process signal delivery when it's emitted */ -#define FSIG_PRIOR_INSTANT 0 - -/* Process and emitted signal instantaneously */ -#define FSIG_PRIOR_DEFAULT 5 - -class FlatSignal : virtual public FlatObject -{ - -public: - - FlatObject * sender; - void * data; - Uint8 priority; - - FlatSignal( FlatObject * sender, - const std::string& id = "", - void *data = 0, - Uint8 priority = 5); - - /* Alias to SignalChannel::emit() */ - bool emit(const std::string& channel) const; -}; - -class FlatListener; - -/* Functor for order comparison */ -struct sig_prior_cmp { - - bool operator()(const FlatSignal&, const FlatSignal&) const; -}; - -typedef std::set<FlatSignal, sig_prior_cmp> SignalStack; - -/* Channel class */ -class SignalChannel : virtual public FlatObject -{ - /* Post processing signal stacking */ - SignalStack stack; - - /* Listeners list */ - std::list<FlatListener*> listeners; - - /* Synchronous task checking for signals */ - task_s * checker; - - /* Channel mapping */ - static std::map<std::string, SignalChannel*> channels; - -public: - - SignalChannel(const std::string& id = "", bool pre_process = false); - ~SignalChannel(); - - void emit(const FlatSignal&); - - void connect(FlatListener*); - void disconnect(FlatListener*); - - static SignalChannel * findChannel(const std::string&); - - void post_processing(void*); -}; - -/* Listener class */ -class FlatListener : virtual public FlatObject -{ - std::list<std::string> filters; - - bool checkInFilters(const std::string&) const; - -protected: - - virtual void callback(FlatObject *sender, void *) = 0; - -public: - - FlatListener(const std::initializer_list<std::string>& filters = {}); - virtual ~FlatListener() {} - - void execute(const FlatSignal&); - - void addFilter(const std::string&); - void removeFilter(const std::string&); - - bool connect(const std::string&); - bool disconnect(const std::string&); -}; - -#endif diff --git a/engine/include/object.h b/engine/include/object.h new file mode 100644 index 0000000..cb7ef36 --- /dev/null +++ b/engine/include/object.h @@ -0,0 +1,42 @@ +#pragma once + +#include <list> +#include <vector> +#include <string> +#include <initializer_list> + +#include "types.h" + +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/signal.h b/engine/include/signal.h new file mode 100644 index 0000000..0f16726 --- /dev/null +++ b/engine/include/signal.h @@ -0,0 +1,138 @@ +#pragma once + +#include <map> +#include <list> +#include <set> +#include <initializer_list> +#include "object.hpp" +#include "task.hpp" +#include "types.h" + +namespace flat +{ + namespace core + { + class signal; + class channel; + } +} + +class flat::core::signal : virtual public flat::core::object +{ + +public: + + flat::core::object * sender; + void * data; + priority prior; + + signal( flat::core::object * sender, + const std::string& id = "", + void *data = 0, + priority prior = 5); + + /* Alias to flat::core::channel::emit() */ + bool emit(const std::string& channel) const; + + enum class priority : uint8_t + { + instant = 0, + highest, + high, + none, + low, + lowest + }; +}; + + +/* Channel class */ +class flat::core::channel : virtual public flat::core::object +{ + /* Post processing signal stacking */ + stack_t stack; + + /* Listeners list */ + std::list<flat::core::listener_s*> listeners; + + /* Synchronous task checking for signals */ + task_s * checker; + + /* Channel mapping */ + static std::map<std::string, channel*> channels; + +public: + + flat::core::channel(const std::string& id = "", flat::core::task::priority prior = flat::core::task::priority::none); + ~flat::core::channel(); + + void emit(const flat::core::signal&); + + void connect(flat::core::listener_s*); + void disconnect(flat::core::listener_s*); + + static flat::core::channel * find_channel(const std::string&); + + void post_processing(void*); + + /* Functor for order comparison */ + struct sig_prior_cmp { + + bool operator()(const flat::core::signal&, const flat::core::signal&) const; + }; + + typedef std::set<flat::core::signal, sig_prior_cmp> stack_t; +}; + +/* Listener class */ +class flat::core::listener_s : virtual public flat::core::object +{ + std::list<std::string> filters; + + bool check_in_filters(const std::string&) const; + +public: + + flat::core::listener(const std::initializer_list<std::string>& filters = {}); + virtual ~flat::core::listener() {} + + virtual void execute(const flat::core::signal&) = 0; + + void add_filter(const std::string&); + void remove_filter(const std::string&); + + bool connect(const std::string&); + bool disconnect(const std::string&); +}; + +template<class T> +class flat::core::listener : public flat::core::listener_s +{ + typedef void (T::*callback_t)(void*); + + T * object; + callback_t callback; + + void *args; + +public: + + listener( T *object, + callback_t callback, + const std::initializer_list<std::string>& filters = {}, + void *args = 0) + + : flat::core::listener_s(filters), + object(object), + callback(callback), + args(args) {} + + virtual void execute(const flat::core::signal&) override + { + if ((!sig.get_id().empty() && check_in_filters(sig.get_id())) || + (sig.get_id().empty() && filters.empty())) + (object->*callback)(sig.sender, sig.data); + } +}; + + diff --git a/engine/include/types.h b/engine/include/types.h index 003c114..9482a46 100644 --- a/engine/include/types.h +++ b/engine/include/types.h @@ -26,8 +26,8 @@ class task_s; /* SDL types */ -typedef unsigned char Uint8; -typedef unsigned int Uint32; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; struct SDL_Surface; struct SDL_Rect; diff --git a/engine/object.cpp b/engine/object.cpp new file mode 100644 index 0000000..eb74e1a --- /dev/null +++ b/engine/object.cpp @@ -0,0 +1,62 @@ +#include "flatobject.h" + +#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 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->getID()) + l.push_back(obj); + } + + return l; +} diff --git a/engine/signal.cpp b/engine/signal.cpp new file mode 100644 index 0000000..0a3d887 --- /dev/null +++ b/engine/signal.cpp @@ -0,0 +1,169 @@ +#include "signal.hpp" +#include "task.hpp" + +using namespace std; +using namespace flat::core; + +bool channel::sig_prior_cmp::operator()(const signal& s, const signal& g) const +{ + return s.prior <= g.prior; +} + +map<string, channel*> channel::channels; + +channel::channel(const string& id, task::priority prior) +{ + channel * other = find_channel(id); + + if (!other) + //TODO throw exception + ; + + /* Initialize task, post-process, fifth priority */ + checker = new task<channel>( this, + &channel::post_processing, + 0, + prior); + + string ID = (id.empty()) ? object::random_id() : id; + + set_id(ID); + + channels.insert(pair<string, channel*>(ID, this)); +} + +channel::~channel() +{ + channels.erase(get_id()); + + /* Finalize task */ + delete checker; +} + +void channel::emit(const signal& sig) +{ + if (!sig.priority) { + + /* Execute immediately */ + for (auto listener_s : listener_ss) + listener_s->execute(sig); + + } else + /* Insert in order of priority */ + stack.insert(sig); +} + +void channel::connect(listener_s* l) +{ + /* Control not to double */ + for (auto listener_s : listener_ss) + { + if (listener_s == l) + return; + } + + listener_ss.push_back(l); +} + +void channel::disconnect(listener_s* l) +{ + listener_ss.remove(l); +} + + +channel * channel::findChannel(const string& id) +{ + if (id.empty()) + return 0; + + auto it = channels.find(id); + + return (it == channels.end()) ? 0 : (*it).second; +} + +void channel::post_processing(void*) +{ + if (!stack.empty()) { + + /* for each listener_s, catch signal */ + for (const auto& signal : stack) + { + for (auto listener_s : listener_ss) + listener_s->execute(signal); + } + + stack.clear(); + } +} + + + +/* signal class */ + +signal::signal(FlatObject *sender, const string& id, void *data, Uint8 priority) + : sender(sender), data(data), priority(priority) +{ + set_id(id); +} + +bool signal::emit(const string& channel) const +{ + channel * chan = channel::find_channel(channel); + + if (!chan) + return false; + + /* Finally emit in channel */ + chan->emit(*this); + + return true; +} + + + +/* listener_s class */ + +listener_s::listener_s(const initializer_list<string>& filters) + : filters(filters) {} + +bool listener_s::check_in_filters(const std::string& filter) const +{ + for (const auto& f : filters) + { + if (filter == f) + return true; + } + + return false; +} + +void listener_s::add_filter(const std::string& f) +{ + filters.push_back(f); +} + +void listener_s::remove_filter(const std::string& f) +{ + filters.remove(f); +} + +bool listener_s::connect(const std::string& chan) +{ + channel * c = channel::find_channel(chan); + + if (!c) + c->connect(this); + + return c != 0; +} + +bool listener_s::disconnect(const std::string& chan) +{ + channel * c = channel::find_channel(chan); + + if (!c) + c->connect(this); + + return c != 0; +} + |