aboutsummaryrefslogtreecommitdiff
path: root/src/common/Utilities/TaskScheduler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/Utilities/TaskScheduler.h')
-rw-r--r--src/common/Utilities/TaskScheduler.h261
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));
}