summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorancarola <raffaele.ancarola@epfl.ch>2019-01-28 17:41:06 +0100
committerancarola <raffaele.ancarola@epfl.ch>2019-01-28 17:41:06 +0100
commit6e453cb08481bcdff3cf94d84b34505153dd7279 (patch)
tree90252d46ebb148203554ecfceefb79c706eb53d9
parentMerge remote-tracking branch 'nao/master' (diff)
downloadflatland-6e453cb08481bcdff3cf94d84b34505153dd7279.tar.gz
flatland-6e453cb08481bcdff3cf94d84b34505153dd7279.zip
Channel interface improved
-rw-r--r--engine/flatland.cpp8
-rw-r--r--engine/include/core/signal.hpp50
-rw-r--r--engine/signal.cpp34
-rw-r--r--test/signal_test.cpp2
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<std::string, std::weak_ptr<channel>> channels;
bool mapped;
+
+ bool map();
public:
using ptr = std::shared_ptr<channel>;
-
+
+ /*
+ * 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<std::string>& 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<channel>(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<channel>(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)