diff options
Diffstat (limited to 'src/common/Utilities/TaskScheduler.h')
-rw-r--r-- | src/common/Utilities/TaskScheduler.h | 261 |
1 files changed, 51 insertions, 210 deletions
diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h index 2ebd3e57b37..c9029a002db 100644 --- a/src/common/Utilities/TaskScheduler.h +++ b/src/common/Utilities/TaskScheduler.h @@ -171,11 +171,10 @@ class TC_COMMON_API TaskScheduler } public: - TaskScheduler() - : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(EmptyValidator) { } + TaskScheduler(); template<typename P> - TaskScheduler(P&& predicate) + explicit TaskScheduler(P&& predicate) : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { } TaskScheduler(TaskScheduler const&) = delete; @@ -183,7 +182,7 @@ public: TaskScheduler& operator= (TaskScheduler const&) = delete; TaskScheduler& operator= (TaskScheduler&&) = delete; - ~TaskScheduler() = default; + ~TaskScheduler(); /// Sets a validator which is asked if tasks are allowed to be executed. template<typename P> @@ -206,14 +205,7 @@ public: /// Update the scheduler with a difftime. /// Calls the optional callback on successfully finish. - template<class Rep, class Period> - TaskScheduler& Update(std::chrono::duration<Rep, Period> difftime, - success_t const& callback = nullptr) - { - _now += difftime; - Dispatch(callback); - return *this; - } + TaskScheduler& Update(duration_t difftime, success_t const& callback = nullptr); /// Schedule an callable function that is executed at the next update tick. /// Its safe to modify the TaskScheduler from within the callable. @@ -221,8 +213,7 @@ public: /// Schedule an event with a fixed rate. /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class Rep, class Period> - TaskScheduler& Schedule(std::chrono::duration<Rep, Period> time, + TaskScheduler& Schedule(duration_t time, task_handler_t task) { return this->ScheduleAt(_now, time, std::move(task)); @@ -230,8 +221,7 @@ public: /// Schedule an event with a fixed rate. /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class Rep, class Period> - TaskScheduler& Schedule(std::chrono::duration<Rep, Period> time, + TaskScheduler& Schedule(duration_t time, group_t const group, task_handler_t task) { return this->ScheduleAt(_now, time, group, std::move(task)); @@ -239,18 +229,16 @@ public: /// Schedule an event with a randomized rate between min and max rate. /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskScheduler& Schedule(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max, task_handler_t task) + TaskScheduler& Schedule(std::chrono::milliseconds min, + std::chrono::milliseconds max, task_handler_t task) { return this->Schedule(::randtime(min, max), std::move(task)); } /// Schedule an event with a fixed rate. /// Never call this from within a task context! Use TaskContext::Schedule instead! - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskScheduler& Schedule(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max, group_t const group, + TaskScheduler& Schedule(std::chrono::milliseconds min, + std::chrono::milliseconds max, group_t const group, task_handler_t task) { return this->Schedule(::randtime(min, max), group, std::move(task)); @@ -269,95 +257,42 @@ public: TaskScheduler& CancelGroupsOf(std::vector<group_t> const& groups); /// Delays all tasks with the given duration. - template<class Rep, class Period> - TaskScheduler& DelayAll(std::chrono::duration<Rep, Period> duration) - { - _task_holder.ModifyIf([&duration](TaskContainer const& task) -> bool - { - task->_end += duration; - return true; - }); - return *this; - } + TaskScheduler& DelayAll(duration_t duration); /// Delays all tasks with a random duration between min and max. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskScheduler& DelayAll(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + TaskScheduler& DelayAll(std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->DelayAll(::randtime(min, max)); } /// Delays all tasks of a group with the given duration. - template<class Rep, class Period> - TaskScheduler& DelayGroup(group_t const group, std::chrono::duration<Rep, Period> duration) - { - _task_holder.ModifyIf([&duration, group](TaskContainer const& task) -> bool - { - if (task->IsInGroup(group)) - { - task->_end += duration; - return true; - } - else - return false; - }); - return *this; - } + TaskScheduler& DelayGroup(group_t const group, duration_t duration); /// Delays all tasks of a group with a random duration between min and max. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> TaskScheduler& DelayGroup(group_t const group, - std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->DelayGroup(group, ::randtime(min, max)); } /// Reschedule all tasks with a given duration. - template<class Rep, class Period> - TaskScheduler& RescheduleAll(std::chrono::duration<Rep, Period> duration) - { - auto const end = _now + duration; - _task_holder.ModifyIf([end](TaskContainer const& task) -> bool - { - task->_end = end; - return true; - }); - return *this; - } + TaskScheduler& RescheduleAll(duration_t duration); /// Reschedule all tasks with a random duration between min and max. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskScheduler& RescheduleAll(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + TaskScheduler& RescheduleAll(std::chrono::milliseconds min, std::chrono::milliseconds max) { return this->RescheduleAll(::randtime(min, max)); } /// Reschedule all tasks of a group with the given duration. - template<class Rep, class Period> - TaskScheduler& RescheduleGroup(group_t const group, std::chrono::duration<Rep, Period> duration) - { - auto const end = _now + duration; - _task_holder.ModifyIf([end, group](TaskContainer const& task) -> bool - { - if (task->IsInGroup(group)) - { - task->_end = end; - return true; - } - else - return false; - }); - return *this; - } + TaskScheduler& RescheduleGroup(group_t const group, duration_t duration); /// Reschedule all tasks of a group with a random duration between min and max. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> TaskScheduler& RescheduleGroup(group_t const group, - std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->RescheduleGroup(group, ::randtime(min, max)); } @@ -366,23 +301,14 @@ private: /// Insert a new task to the enqueued tasks. TaskScheduler& InsertTask(TaskContainer task); - template<class Rep, class Period> TaskScheduler& ScheduleAt(timepoint_t end, - std::chrono::duration<Rep, Period> time, task_handler_t task) - { - return InsertTask(TaskContainer(new Task(end + time, time, std::move(task)))); - } + duration_t time, task_handler_t task); /// Schedule an event with a fixed rate. /// Never call this from within a task context! Use TaskContext::schedule instead! - template<class Rep, class Period> TaskScheduler& ScheduleAt(timepoint_t end, - std::chrono::duration<Rep, Period> time, - group_t const group, task_handler_t task) - { - static constexpr repeated_t DEFAULT_REPEATED = 0; - return InsertTask(TaskContainer(new Task(end + time, time, group, DEFAULT_REPEATED, std::move(task)))); - } + duration_t time, + group_t const group, task_handler_t task); /// Dispatch remaining tasks void Dispatch(success_t const& callback); @@ -414,36 +340,16 @@ public: : _task(std::move(task)), _owner(std::move(owner)), _consumed(std::make_shared<bool>(false)) { } // Copy construct - TaskContext(TaskContext const& right) - : _task(right._task), _owner(right._owner), _consumed(right._consumed) { } + TaskContext(TaskContext const& right) = default; // Move construct - TaskContext(TaskContext&& right) noexcept - : _task(std::move(right._task)), _owner(std::move(right._owner)), _consumed(std::move(right._consumed)) { } + TaskContext(TaskContext&& right) noexcept = default; // Copy assign - TaskContext& operator=(TaskContext const& right) - { - if (this != &right) - { - _task = right._task; - _owner = right._owner; - _consumed = right._consumed; - } - return *this; - } + TaskContext& operator=(TaskContext const& right) = default; // Move assign - TaskContext& operator=(TaskContext&& right) noexcept - { - if (this != &right) - { - _task = std::move(right._task); - _owner = std::move(right._owner); - _consumed = std::move(right._consumed); - } - return *this; - } + TaskContext& operator=(TaskContext&& right) noexcept = default; ~TaskContext() = default; @@ -466,21 +372,7 @@ public: /// std::chrono::seconds(5) for example. /// This will consume the task context, its not possible to repeat the task again /// from the same task context! - template<class Rep, class Period> - TaskContext& Repeat(std::chrono::duration<Rep, Period> duration) - { - AssertOnConsumed(); - - // Set new duration, in-context timing and increment repeat counter - _task->_duration = duration; - _task->_end += duration; - _task->_repeated += 1; - (*_consumed) = true; - return this->Dispatch([this](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.InsertTask(_task); - }); - } + TaskContext& Repeat(TaskScheduler::duration_t duration); /// Repeats the event with the same duration. /// This will consume the task context, its not possible to repeat the task again @@ -494,9 +386,8 @@ public: /// std::chrono::seconds(5) for example. /// This will consume the task context, its not possible to repeat the task again /// from the same task context! - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskContext& Repeat(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + TaskContext& Repeat(std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->Repeat(::randtime(min, max)); } @@ -509,39 +400,22 @@ public: /// Its possible that the new event is executed immediately! /// Use TaskScheduler::Async to create a task /// which will be called at the next update tick. - template<class Rep, class Period> - TaskContext& Schedule(std::chrono::duration<Rep, Period> time, - TaskScheduler::task_handler_t task) - { - auto const end = _task->_end; - return this->Dispatch([end, time, task = std::move(task)](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.ScheduleAt<Rep, Period>(end, time, std::move(task)); - }); - } + TaskContext& Schedule(TaskScheduler::duration_t time, + TaskScheduler::task_handler_t task); /// Schedule an event with a fixed rate from within the context. /// Its possible that the new event is executed immediately! /// Use TaskScheduler::Async to create a task /// which will be called at the next update tick. - template<class Rep, class Period> - TaskContext& Schedule(std::chrono::duration<Rep, Period> time, - TaskScheduler::group_t const group, TaskScheduler::task_handler_t task) - { - auto const end = _task->_end; - return this->Dispatch([end, time, group, task = std::move(task)](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.ScheduleAt<Rep, Period>(end, time, group, std::move(task)); - }); - } + TaskContext& Schedule(TaskScheduler::duration_t time, + TaskScheduler::group_t const group, TaskScheduler::task_handler_t task); /// Schedule an event with a randomized rate between min and max rate from within the context. /// Its possible that the new event is executed immediately! /// Use TaskScheduler::Async to create a task /// which will be called at the next update tick. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskContext& Schedule(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max, TaskScheduler::task_handler_t task) + TaskContext& Schedule(std::chrono::milliseconds min, + std::chrono::milliseconds max, TaskScheduler::task_handler_t task) { return this->Schedule(::randtime(min, max), std::move(task)); } @@ -550,9 +424,8 @@ public: /// Its possible that the new event is executed immediately! /// Use TaskScheduler::Async to create a task /// which will be called at the next update tick. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskContext& Schedule(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max, TaskScheduler::group_t const group, + TaskContext& Schedule(std::chrono::milliseconds min, + std::chrono::milliseconds max, TaskScheduler::group_t const group, TaskScheduler::task_handler_t task) { return this->Schedule(::randtime(min, max), group, std::move(task)); @@ -569,75 +442,43 @@ public: TaskContext& CancelGroupsOf(std::vector<TaskScheduler::group_t> const& groups); /// Delays all tasks with the given duration from within the context. - template<class Rep, class Period> - TaskContext& DelayAll(std::chrono::duration<Rep, Period> duration) - { - return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.DelayAll(duration); - }); - } + TaskContext& DelayAll(TaskScheduler::duration_t duration); /// Delays all tasks with a random duration between min and max from within the context. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskContext& DelayAll(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + TaskContext& DelayAll(std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->DelayAll(::randtime(min, max)); } /// Delays all tasks of a group with the given duration from within the context. - template<class Rep, class Period> - TaskContext& DelayGroup(TaskScheduler::group_t const group, std::chrono::duration<Rep, Period> duration) - { - return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.DelayGroup(group, duration); - }); - } + TaskContext& DelayGroup(TaskScheduler::group_t const group, TaskScheduler::duration_t duration); /// Delays all tasks of a group with a random duration between min and max from within the context. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> TaskContext& DelayGroup(TaskScheduler::group_t const group, - std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->DelayGroup(group, ::randtime(min, max)); } /// Reschedule all tasks with the given duration. - template<class Rep, class Period> - TaskContext& RescheduleAll(std::chrono::duration<Rep, Period> duration) - { - return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.RescheduleAll(duration); - }); - } + TaskContext& RescheduleAll(TaskScheduler::duration_t duration); /// Reschedule all tasks with a random duration between min and max. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> - TaskContext& RescheduleAll(std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + TaskContext& RescheduleAll(std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->RescheduleAll(::randtime(min, max)); } /// Reschedule all tasks of a group with the given duration. - template<class Rep, class Period> - TaskContext& RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration<Rep, Period> duration) - { - return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& - { - return scheduler.RescheduleGroup(group, duration); - }); - } + TaskContext& RescheduleGroup(TaskScheduler::group_t const group, TaskScheduler::duration_t duration); /// Reschedule all tasks of a group with a random duration between min and max. - template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> TaskContext& RescheduleGroup(TaskScheduler::group_t const group, - std::chrono::duration<RepLeft, PeriodLeft> min, - std::chrono::duration<RepRight, PeriodRight> max) + std::chrono::milliseconds min, + std::chrono::milliseconds max) { return this->RescheduleGroup(group, ::randtime(min, max)); } |