diff options
author | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-23 15:07:33 +0100 |
---|---|---|
committer | ancarola <raffaele.ancarola@epfl.ch> | 2019-01-23 15:07:33 +0100 |
commit | 8443d3d03573066ab884dae0f7bc8dbbabf106b5 (patch) | |
tree | a81f054b62ec9a5c18ca9a8275a94416512c9fa1 | |
parent | signal opt (diff) | |
parent | Make job hold RAII pointers that can expire, update test (diff) | |
download | flatland-8443d3d03573066ab884dae0f7bc8dbbabf106b5.tar.gz flatland-8443d3d03573066ab884dae0f7bc8dbbabf106b5.zip |
Merge remote-tracking branch 'nao/raii-task'
Ci siamo
-rw-r--r-- | engine/include/core/priority.hpp | 17 | ||||
-rw-r--r-- | engine/include/core/task.hpp | 19 | ||||
-rw-r--r-- | engine/task.cpp | 24 | ||||
-rw-r--r-- | test/task_test.cpp | 59 |
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; } |