summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorancarola <raffaele.ancarola@epfl.ch>2019-01-23 15:07:33 +0100
committerancarola <raffaele.ancarola@epfl.ch>2019-01-23 15:07:33 +0100
commit8443d3d03573066ab884dae0f7bc8dbbabf106b5 (patch)
treea81f054b62ec9a5c18ca9a8275a94416512c9fa1
parentsignal opt (diff)
parentMake job hold RAII pointers that can expire, update test (diff)
downloadflatland-8443d3d03573066ab884dae0f7bc8dbbabf106b5.tar.gz
flatland-8443d3d03573066ab884dae0f7bc8dbbabf106b5.zip
Merge remote-tracking branch 'nao/raii-task'
Ci siamo
-rw-r--r--engine/include/core/priority.hpp17
-rw-r--r--engine/include/core/task.hpp19
-rw-r--r--engine/task.cpp24
-rw-r--r--test/task_test.cpp59
4 files changed, 92 insertions, 27 deletions
diff --git a/engine/include/core/priority.hpp b/engine/include/core/priority.hpp
index 773b2f7..1219d26 100644
--- a/engine/include/core/priority.hpp
+++ b/engine/include/core/priority.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <memory>
#include <set>
namespace flat {
@@ -32,8 +33,20 @@ namespace flat {
return lhs.priority() < rhs.priority();
}
- bool operator()(const prioritized * const& lhs, const prioritized * const& rhs) {
- return lhs->priority() < rhs->priority();
+ bool operator()(const std::weak_ptr<prioritized> lhs, const std::weak_ptr<prioritized>& rhs) {
+ if (auto l = lhs.lock()) {
+ if (auto r = rhs.lock()) {
+ // if both valid, check their priority
+ // in case they are the same, left is prioritized
+ return l->priority() < r->priority();
+ } else {
+ // if right is expired, left is prioritized
+ return true;
+ }
+ } else {
+ // if left is expired, the right is prioritized
+ return false;
+ }
}
};
diff --git a/engine/include/core/task.hpp b/engine/include/core/task.hpp
index 90e3d97..d886fcd 100644
--- a/engine/include/core/task.hpp
+++ b/engine/include/core/task.hpp
@@ -3,26 +3,29 @@
#include "priority.hpp"
#include <functional>
-#include <set>
+#include <memory>
namespace flat {
namespace core {
+ // forward decl
+ class job;
+ class task;
+
class task : public prioritized {
public:
+ using callback = std::function<void(void)>;
+
task() = delete;
- task(std::function<void()> callback, priority_t p = priority_t::none);
+ task(callback f, priority_t p = priority_t::none);
inline void operator()() const { m_callback(); }
private:
- std::function<void()> m_callback;
+ callback m_callback;
};
- struct job : public queue<task> {
- inline auto add_task(task t) {
- this->insert(t);
- }
-
+ struct job : private queue<std::weak_ptr<task>> {
+ std::shared_ptr<task> make_task(task::callback f, priority_t p = priority_t::none);
void invoke_tasks();
};
}
diff --git a/engine/task.cpp b/engine/task.cpp
index 760b1b9..f2b6058 100644
--- a/engine/task.cpp
+++ b/engine/task.cpp
@@ -1,17 +1,31 @@
#include "core/task.hpp"
#include <functional>
+#include <memory>
namespace flat {
namespace core {
- task::task(std::function<void()> callback, priority_t p)
- : m_callback(callback) {}
+ task::task(task::callback f, priority_t p)
+ : m_callback(f) {}
+
+ std::shared_ptr<task> job::make_task(task::callback f, priority_t p) {
+ auto shared = std::make_shared<task>(f, p);
+ insert(shared);
+ return shared;
+ }
void job::invoke_tasks() {
- for (const task& t : *this) {
- t();
- }
+ std::for_each(begin(), end(), [&](auto tp) {
+ // check that the task has not expired
+ if (auto t = tp.lock()) {
+ // run task
+ std::invoke(*t);
+ } else {
+ // delete task
+ erase(tp);
+ }
+ });
}
}
}
diff --git a/test/task_test.cpp b/test/task_test.cpp
index 074eb94..199d510 100644
--- a/test/task_test.cpp
+++ b/test/task_test.cpp
@@ -1,39 +1,74 @@
-#include "task.hpp"
+#include "core/task.hpp"
#include <functional>
#include <iostream>
-struct hello_class {
- const std::string motd = "hello world!";
+// test class
+struct message {
+ std::string motd = "today we have no motd!";
+ std::string date = "1 Jan 1970";
+
+ void print_date() {
+ std::cout << date << std::endl;
+ }
void print_motd() {
std::cout << motd << std::endl;
}
};
-
+// test functions
void hello() {
std::cout << "hello!" << std::endl;
}
+void ciao() {
+ std::cout << "ciao!" << std::endl;
+}
+
+
int main(int argc, char *argv[]) {
using namespace flat::core;
- job job;
+
+ std::cout << "Testing functions" << std::endl;
+ std::cout << "should print once: hello!" << std::endl;
+
+ job f_job;
// test a function
- task t_func(hello);
- job.add_task(t_func);
+ auto ciao_fn_task = f_job.make_task(hello);
+
+ // test a function ad make the pointer go out of scope
+ {
+ auto hello_fn_task = f_job.make_task(ciao);
+ }
+
+ f_job.invoke_tasks();
- // test a member function
- hello_class h;
- task t_mem([&](){ h.print_motd(); });
- job.add_task(t_mem);
+ std::cout << std::endl;
+ std::cout << "Testing methods" << std::endl;
+ std::cout << " should print once: today we have no motd!" << std::endl;
+ job m_job;
+
+ // test a method
+ message m;
+ m_job.make_task(std::bind(&message::print_motd, m));
+
+ // test a method of an object that goes out of scope
+ {
+ message out;
+ m_job.make_task(std::bind(&message::print_date, out));
+ }
// invoke tasks
- job.invoke_tasks();
+ // should print:
+ //
+ // hello!
+ // hello world!
+ m_job.invoke_tasks();
return 0;
}