Last active
July 5, 2020 16:55
-
-
Save NotAPenguin0/3d15f96f2697fea9591a2c0a47d3b0a7 to your computer and use it in GitHub Desktop.
task scheduler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef ANDROMEDA_TASK_MANAGER_HPP_ | |
| #define ANDROMEDA_TASK_MANAGER_HPP_ | |
| #include <ftl/task_scheduler.h> | |
| #include <memory> | |
| #include <functional> | |
| namespace andromeda { | |
| class TaskManager; | |
| template<typename T> | |
| struct TaskFunctionType { | |
| using type = std::function<void(ftl::TaskScheduler*, T)>; | |
| }; | |
| template<> | |
| struct TaskFunctionType<void> { | |
| using type = std::function<void(ftl::TaskScheduler*)>; | |
| }; | |
| template<typename T> | |
| using TaskFunction = typename TaskFunctionType<T>::type; | |
| namespace detail { | |
| template<typename T> | |
| struct TaskLaunchStub { | |
| TaskFunction<T> func; | |
| T arg; | |
| TaskManager& manager; | |
| }; | |
| template<> | |
| struct TaskLaunchStub<void> { | |
| TaskFunction<void> func; | |
| TaskManager& manager; | |
| }; | |
| template<typename T> | |
| void task_func(ftl::TaskScheduler* scheduler, void* arg) { | |
| auto original_launch_stub = (TaskLaunchStub<T>*)(arg); | |
| original_launch_stub->func(scheduler, original_launch_stub->arg); | |
| // Cleanup the launch data | |
| delete original_launch_stub; | |
| } | |
| template<> | |
| void task_func<void>(ftl::TaskScheduler* scheduler, void* arg) { | |
| auto original_launch_stub = (TaskLaunchStub<void>*)(arg); | |
| original_launch_stub->func(scheduler); | |
| // Cleanup the launch data | |
| delete original_launch_stub; | |
| } | |
| template<typename T> | |
| void do_launch(TaskLaunchStub<T>* launch_stub) { | |
| ftl::Task task{ task_func<T>, (void*)launch_stub }; | |
| launch_stub->manager.get_scheduler().AddTask(task); | |
| } | |
| } | |
| class TaskManager { | |
| public: | |
| TaskManager(); | |
| template<typename T> | |
| void launch(TaskFunction<T> func, T arg) { | |
| detail::TaskLaunchStub<T>* launch_stub = new detail::TaskLaunchStub<T>{ std::move(func), std::move(arg), *this }; | |
| detail::do_launch(launch_stub); | |
| } | |
| void launch(TaskFunction<void> func) { | |
| detail::TaskLaunchStub<void>* launch_stub = new detail::TaskLaunchStub<void>{ std::move(func), *this }; | |
| detail::do_launch(launch_stub); | |
| } | |
| ftl::TaskScheduler& get_scheduler() { return *scheduler; } | |
| private: | |
| void init(); | |
| void deinit(); | |
| std::unique_ptr<ftl::TaskScheduler> scheduler; | |
| std::atomic<size_t> running_tasks = 0; | |
| }; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment