diff options
author | Nao Pross <naopross@thearcway.org> | 2019-01-23 20:33:33 +0100 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2019-01-23 20:33:33 +0100 |
commit | d0f35bf97063d1d786713f373e4753bed56d4f0b (patch) | |
tree | 19dc0f18ca966424b286b1cf1e4dd686f60eaa64 | |
parent | Merge branch 'raii-task' (diff) | |
download | flatland-d0f35bf97063d1d786713f373e4753bed56d4f0b.tar.gz flatland-d0f35bf97063d1d786713f373e4753bed56d4f0b.zip |
Update job interface to allow safe ownership delegation
-rw-r--r-- | engine/include/core/priority.hpp | 15 | ||||
-rw-r--r-- | engine/include/core/task.hpp | 24 | ||||
-rw-r--r-- | engine/task.cpp | 7 | ||||
-rw-r--r-- | test/task_test.cpp | 29 |
4 files changed, 43 insertions, 32 deletions
diff --git a/engine/include/core/priority.hpp b/engine/include/core/priority.hpp index d6c9b35..ae4a6db 100644 --- a/engine/include/core/priority.hpp +++ b/engine/include/core/priority.hpp @@ -16,21 +16,16 @@ namespace flat { }; class prioritized { - private: - const priority_t m_priority; - public: - prioritized(priority_t priority = priority_t::none) - : m_priority(priority) {} + const priority_t priority; - const priority_t priority() const { - return m_priority; - } + prioritized(priority_t p = priority_t::none) + : priority(p) {} }; struct prioritize { bool operator()(const prioritized& lhs, const prioritized& rhs) { - return lhs.priority() < rhs.priority(); + return lhs.priority < rhs.priority; } bool operator()(const std::weak_ptr<prioritized> lhs, const std::weak_ptr<prioritized> rhs) { @@ -38,7 +33,7 @@ namespace flat { 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(); + return l->priority < r->priority; } else { // if right is expired, left is prioritized return true; diff --git a/engine/include/core/task.hpp b/engine/include/core/task.hpp index 570e547..77e1da6 100644 --- a/engine/include/core/task.hpp +++ b/engine/include/core/task.hpp @@ -2,7 +2,9 @@ #include "priority.hpp" +#include <unordered_set> #include <functional> +#include <variant> #include <memory> namespace flat { @@ -13,6 +15,7 @@ namespace flat { class task : public prioritized { public: + using ptr = std::shared_ptr<task>; using callback = std::function<void(void)>; task() = delete; @@ -24,13 +27,24 @@ namespace flat { callback m_callback; }; - struct job : public queue<std::weak_ptr<task>> { - std::shared_ptr<task> make_task(task::callback f, priority_t p = priority_t::none); - void invoke_tasks(); + class job : protected queue<std::weak_ptr<task>> { + public: + /// add a task function owned by the job object + void add_task(task::callback f, priority_t p); + + /// add a task function not owned by the job object (weak_ptr) + std::shared_ptr<task> delegate_task(task::callback f, priority_t p = priority_t::none); - inline void operator()() { - invoke_tasks(); + /// add a task methods not owned by the job object (weak_ptr), + /// this allows to make the task die when the owner object goes out of scope + template<typename R, typename T> + inline std::shared_ptr<task> delegate_task(R T::*mf, T& obj, priority_t p = priority_t::none) { + return delegate_task(std::bind(mf, obj), p); } + + /// run tasks + void invoke_tasks(); + inline void operator()() { invoke_tasks(); } }; } } diff --git a/engine/task.cpp b/engine/task.cpp index 8950633..9cfbec4 100644 --- a/engine/task.cpp +++ b/engine/task.cpp @@ -16,14 +16,17 @@ namespace flat { task::task(task::callback f, priority_t p) : m_callback(f) {} - std::shared_ptr<task> job::make_task(task::callback f, priority_t p) { - + std::shared_ptr<task> job::delegate_task(task::callback f, priority_t p) { auto shared = std::make_shared<task>(f, p); insert(shared); return shared; } + void job::add_task(task::callback f, priority_t p) { + insert(std::make_shared<task>(f, p)); + } + void job::invoke_tasks() { // expired tasks to remove std::vector<job::value_type> to_erase; diff --git a/test/task_test.cpp b/test/task_test.cpp index 76fb3b7..04bb23d 100644 --- a/test/task_test.cpp +++ b/test/task_test.cpp @@ -6,21 +6,19 @@ using namespace flat::core; // test class -struct message { - - message(job& m_job, bool date) - { - if (date) - mytask = m_job.make_task(std::bind(&message::print_date, *this)); - else - mytask = m_job.make_task(std::bind(&message::print_motd, *this)); - } - - std::shared_ptr<task> mytask; +class message { +private: + task::ptr mytask; std::string motd = "today we have no motd!"; std::string date = "1 Jan 1970"; +public: + message(job& job) { + // add an example job + mytask = job.delegate_task(&message::print_motd, *this); + } + void print_date() { std::cout << date << std::endl; } @@ -49,11 +47,11 @@ int main(int argc, char *argv[]) { job f_job; // test a function - auto hello_fn_task = f_job.make_task(hello); + auto hello_fn_task = f_job.delegate_task(hello); // test a function ad make the pointer go out of scope { - auto ciao_fn_task = f_job.make_task(ciao); + auto ciao_fn_task = f_job.delegate_task(ciao); } f_job(); @@ -61,14 +59,15 @@ int main(int argc, char *argv[]) { 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, false); + message m(m_job); // test a method of an object that goes out of scope { - message out(m_job, true); + message out(m_job); } // invoke tasks |