From 6e453cb08481bcdff3cf94d84b34505153dd7279 Mon Sep 17 00:00:00 2001 From: ancarola Date: Mon, 28 Jan 2019 17:41:06 +0100 Subject: Channel interface improved --- engine/flatland.cpp | 8 +++---- engine/include/core/signal.hpp | 50 +++++++++++++++++++++++++++++++++++++----- engine/signal.cpp | 34 ++++++++++++++++++---------- test/signal_test.cpp | 2 ++ 4 files changed, 74 insertions(+), 20 deletions(-) diff --git a/engine/flatland.cpp b/engine/flatland.cpp index da0f58d..d5a2a46 100644 --- a/engine/flatland.cpp +++ b/engine/flatland.cpp @@ -107,10 +107,10 @@ int flat::init_flatland(FlatWindow* w, const flat_status& s, float _fps) // init core channel cout << "Flatland: Initializing core channel" << endl; - - core_chan.start(core::priority_t::max); - - if (!core_chan.map()) { + + // start core channel + // assure that NO OTHER core channel was present before initialization + if (!core_chan.start(core::priority_t::max, &mainsync_job)) { cout << "Flatland: Could not map 'core' channel" << endl; cout << "Flatland: Do not call another channel 'core' before flatland initialization" << endl; diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp index e21b73e..8496f1e 100644 --- a/engine/include/core/signal.hpp +++ b/engine/include/core/signal.hpp @@ -101,16 +101,29 @@ namespace flat static std::map> channels; bool mapped; + + bool map(); public: using ptr = std::shared_ptr; - + + /* + * Constructs a new channel and try to bind it the specified job + * If no job is specified, then flat::main_job will be taken + * + * Note: Remember to check for channel legacy with legit() member function + * A channel is legit if and only if there's no other channel + * corresponding to the same label name + * In general, a channel must be UNIQUE with its label + */ channel(const std::string& id = ""); ~channel(); - void start(priority_t task_priority = priority_t::none); - bool map(); + // do not allow to copy a channel + // it does not have any sense to create a channel with the same name + channel(const channel&) = delete; + channel& operator=(const channel&) = delete; void emit(const signal&); @@ -120,6 +133,21 @@ namespace flat bool connect(listener* l); void disconnect(listener* l); + /* + * Check for legacy + * + * Note: Channels are mapped by their label. + * A channel is legit if and only if there's no other channel + * corresponding to the same label name. + */ + bool legit() const; + + /* + * It tries binding the channel task and make the channel legit + * In case of success, true is returned, otherwise false + */ + bool start(priority_t task_priority = priority_t::none, job * _job = NULL); + listener::ptr connect(listener::callback f, const std::initializer_list& filters = {}); @@ -130,10 +158,22 @@ namespace flat using namespace std::placeholders; return connect(std::bind(mf, obj, _1, _2), filters); } - + + /* + * Find channel by its name + */ static ptr find(const std::string&); - static ptr create(const std::string& id, priority_t prior = priority_t::none); + /* + * Safer than constructor + * It constructs a new channel checking whether it is legit or not. + * It returns a nullptr if the legacy is not verified. + * + * Note: Channels are mapped by their label. + * A channel is legit if and only if there's no other channel + * corresponding to the same label name. + */ + static ptr create(const std::string& id, priority_t prior = priority_t::none, job * _job = NULL); void check_and_call(); }; diff --git a/engine/signal.cpp b/engine/signal.cpp index 0a57caa..d6be29b 100644 --- a/engine/signal.cpp +++ b/engine/signal.cpp @@ -20,12 +20,25 @@ channel::~channel() channels.erase(label); } -void channel::start(priority_t prior) +bool channel::start(priority_t prior, job * _job) { + npdebug("Trying to map channel: ", label); + + if (map()) + checker.reset(); // force count to zero, it should remove task too + else + return false; + npdebug("Starting channel: ", label); + // take main job if no job is specified + if (!_job) + _job = &flat::main_job(); + // Initialize task - checker = flat::main_job().delegate_task(&channel::check_and_call, this, prior); + checker = _job->delegate_task(&channel::check_and_call, this, prior); + + return true; } bool channel::map() @@ -97,16 +110,17 @@ listener::ptr channel::connect(listener::callback f, const std::initializer_list return nullptr; } -channel::ptr channel::create(const std::string& id, priority_t prior) +bool channel::legit() const { - ptr out = std::make_shared(id); - - if (!out->map()) - return nullptr; + return mapped; +} - out->start(prior); +channel::ptr channel::create(const std::string& id, priority_t prior, job * _job) +{ + ptr out = std::make_shared(id); - return out; + // do not create a non-legit channel + return out->start(prior, _job) ? out : nullptr; } channel::ptr channel::find(const std::string& id) @@ -119,8 +133,6 @@ channel::ptr channel::find(const std::string& id) return (it == channels.end()) ? nullptr : (*it).second.lock(); } -int step = 0; - void channel::check_and_call() { if (!stack.empty()) { diff --git a/test/signal_test.cpp b/test/signal_test.cpp index 4dcb635..35aede5 100644 --- a/test/signal_test.cpp +++ b/test/signal_test.cpp @@ -87,6 +87,8 @@ int main() FlatWindow win(600, 900, "Test 3"); flat_status status; + npdebug("Initializing channel alpha") + alpha = channel::create("alpha"); if (alpha == nullptr) -- cgit v1.2.1