18#ifndef _TASK_SCHEDULER_H_
19#define _TASK_SCHEDULER_H_
52 typedef std::chrono::steady_clock
clock_t;
82 : _end(end), _duration(duration), _group(group), _repeated(repeated), _task(task) { }
86 : _end(end), _duration(duration), _group(
std::nullopt), _repeated(0), _task(task) { }
100 return std::compare_weak_order_fallback(_end, other.
_end);
104 bool operator== (
Task const& other)
const
106 return _end == other.
_end;
112 return _group == group;
123 return (*left.get()) < (*right.get());
142 void RemoveIf(std::function<
bool(
TaskContainer const&)>
const& filter);
144 void ModifyIf(std::function<
bool(
TaskContainer const&)>
const& filter);
146 bool IsEmpty()
const;
181 : self_reference(this, [](
TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { }
192 _predicate = std::forward<P>(predicate);
201 TaskScheduler& Update(success_t
const& callback = EmptyCallback);
205 TaskScheduler& Update(
size_t const milliseconds, success_t
const& callback = EmptyCallback);
209 template<
class _Rep,
class _Period>
211 success_t const& callback = EmptyCallback)
224 template<
class _Rep,
class _Period>
228 return ScheduleAt(_now, time, task);
233 template<
class _Rep,
class _Period>
237 return ScheduleAt(_now, time, group, task);
242 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
244 std::chrono::duration<_RepRight, _PeriodRight>
const& max,
task_handler_t const& task)
246 return Schedule(
randtime(min, max), task);
251 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
253 std::chrono::duration<_RepRight, _PeriodRight>
const& max,
group_t const group,
256 return Schedule(
randtime(min, max), group, task);
269 TaskScheduler& CancelGroupsOf(std::vector<group_t>
const& groups);
272 template<
class _Rep,
class _Period>
277 task->_end += duration;
284 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
286 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
288 return DelayAll(
randtime(min, max));
292 template<
class _Rep,
class _Period>
297 if (task->IsInGroup(group))
299 task->_end += duration;
309 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
311 std::chrono::duration<_RepLeft, _PeriodLeft>
const& min,
312 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
314 return DelayGroup(group,
randtime(min, max));
318 template<
class _Rep,
class _Period>
321 auto const end = _now + duration;
331 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
333 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
335 return RescheduleAll(
randtime(min, max));
339 template<
class _Rep,
class _Period>
342 auto const end = _now + duration;
345 if (task->IsInGroup(group))
357 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
359 std::chrono::duration<_RepLeft, _PeriodLeft>
const& min,
360 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
362 return RescheduleGroup(group,
randtime(min, max));
369 template<
class _Rep,
class _Period>
371 std::chrono::duration<_Rep, _Period>
const& time,
task_handler_t const& task)
378 template<
class _Rep,
class _Period>
380 std::chrono::duration<_Rep, _Period>
const& time,
384 return InsertTask(
TaskContainer(
new Task(end + time, time, group, DEFAULT_REPEATED, task)));
388 void Dispatch(success_t
const& callback);
410 : _task(), _owner(), _consumed(
std::make_shared<bool>(true)) { }
414 : _task(task), _owner(owner), _consumed(
std::make_shared<bool>(false)) { }
418 : _task(right._task), _owner(right._owner), _consumed(right._consumed) { }
422 : _task(
std::move(right._task)), _owner(
std::move(right._owner)), _consumed(
std::move(right._consumed)) { }
436 _task = std::move(right._task);
437 _owner = std::move(right._owner);
438 _consumed = std::move(right._consumed);
443 bool IsExpired()
const;
461 template<
class _Rep,
class _Period>
467 _task->_duration = duration;
468 _task->_end += duration;
469 _task->_repeated += 1;
479 return Repeat(_task->_duration);
486 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
488 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
495 TaskContext& Async(std::function<
void()>
const& callable);
501 template<
class _Rep,
class _Period>
505 auto const end = _task->_end;
508 return scheduler.
ScheduleAt<_Rep, _Period>(end, time, task);
516 template<
class _Rep,
class _Period>
520 auto const end = _task->_end;
523 return scheduler.
ScheduleAt<_Rep, _Period>(end, time, group, task);
531 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
535 return Schedule(
randtime(min, max), task);
542 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
547 return Schedule(
randtime(min, max), group, task);
558 TaskContext& CancelGroupsOf(std::vector<TaskScheduler::group_t>
const& groups);
561 template<
class _Rep,
class _Period>
564 return Dispatch(std::bind(&TaskScheduler::DelayAll<_Rep, _Period>, std::placeholders::_1, duration));
568 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
570 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
572 return DelayAll(
randtime(min, max));
576 template<
class _Rep,
class _Period>
579 return Dispatch(std::bind(&TaskScheduler::DelayGroup<_Rep, _Period>, std::placeholders::_1, group, duration));
583 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
585 std::chrono::duration<_RepLeft, _PeriodLeft>
const& min,
586 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
588 return DelayGroup(group,
randtime(min, max));
592 template<
class _Rep,
class _Period>
599 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
601 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
603 return RescheduleAll(
randtime(min, max));
607 template<
class _Rep,
class _Period>
610 return Dispatch(std::bind(&TaskScheduler::RescheduleGroup<_Rep, _Period>, std::placeholders::_1, group, duration));
614 template<
class _RepLeft,
class _PeriodLeft,
class _RepRight,
class _PeriodRight>
616 std::chrono::duration<_RepLeft, _PeriodLeft>
const& min,
617 std::chrono::duration<_RepRight, _PeriodRight>
const& max)
619 return RescheduleGroup(group,
randtime(min, max));
624 void AssertOnConsumed()
const;
static bool EmptyValidator()
std::optional< T > Optional
Optional helper class to wrap optional values within.
Milliseconds randtime(Milliseconds min, Milliseconds max)
std::strong_ordering operator<=>(WowTime const &left, WowTime const &right)
TaskContext & RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Reschedule all tasks of a group with a random duration between min and max.
TaskContext & Repeat(std::chrono::duration< _Rep, _Period > const &duration)
TaskContext & Schedule(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max, TaskScheduler::group_t const group, TaskScheduler::task_handler_t const &task)
TaskContext(TaskContext &&right)
TaskContext & Repeat(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
TaskContext & DelayGroup(TaskScheduler::group_t const group, std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Delays all tasks of a group with a random duration between min and max from within the context.
TaskScheduler::TaskContainer _task
Associated task.
std::weak_ptr< TaskScheduler > _owner
Owner.
std::shared_ptr< bool > _consumed
Marks the task as consumed.
TaskContext & Schedule(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max, TaskScheduler::task_handler_t const &task)
TaskContext & Schedule(std::chrono::duration< _Rep, _Period > const &time, TaskScheduler::group_t const group, TaskScheduler::task_handler_t const &task)
TaskContext & DelayAll(std::chrono::duration< _Rep, _Period > const &duration)
Delays all tasks with the given duration from within the context.
TaskContext & DelayGroup(TaskScheduler::group_t const group, std::chrono::duration< _Rep, _Period > const &duration)
Delays all tasks of a group with the given duration from within the context.
TaskContext & DelayAll(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Delays all tasks with a random duration between min and max from within the context.
TaskContext & RescheduleAll(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Reschedule all tasks with a random duration between min and max.
TaskContext(TaskContext const &right)
TaskContext & Schedule(std::chrono::duration< _Rep, _Period > const &time, TaskScheduler::task_handler_t const &task)
TaskContext(TaskScheduler::TaskContainer &&task, std::weak_ptr< TaskScheduler > &&owner)
TaskContext & RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration< _Rep, _Period > const &duration)
Reschedule all tasks of a group with the given duration.
TaskContext & RescheduleAll(std::chrono::duration< _Rep, _Period > const &duration)
Reschedule all tasks with the given duration.
void ModifyIf(std::function< bool(TaskContainer const &)> const &filter)
std::multiset< TaskContainer, Compare > container
bool IsInGroup(group_t const group) const
Optional< group_t > _group
Task(timepoint_t const &end, duration_t const &duration, Optional< group_t > const &group, repeated_t const repeated, task_handler_t const &task)
Task(Task const &)=delete
Task(timepoint_t const &end, duration_t const &duration, task_handler_t const &task)
TaskScheduler & DelayAll(std::chrono::duration< _Rep, _Period > const &duration)
Delays all tasks with the given duration.
TaskScheduler & RescheduleAll(std::chrono::duration< _Rep, _Period > const &duration)
Reschedule all tasks with a given duration.
std::shared_ptr< Task > TaskContainer
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
clock_t::time_point timepoint_t
TaskScheduler & ScheduleAt(timepoint_t const &end, std::chrono::duration< _Rep, _Period > const &time, task_handler_t const &task)
TaskScheduler(TaskScheduler &&)=delete
TaskScheduler & Update(std::chrono::duration< _Rep, _Period > const &difftime, success_t const &callback=EmptyCallback)
std::function< void()> success_t
std::shared_ptr< TaskScheduler > self_reference
Contains a self reference to track if this object was deleted or not.
std::function< void(TaskContext)> task_handler_t
std::function< bool()> predicate_t
TaskScheduler & DelayAll(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Delays all tasks with a random duration between min and max.
TaskScheduler & RescheduleGroup(group_t const group, std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Reschedule all tasks of a group with a random duration between min and max.
TaskScheduler(P &&predicate)
TaskScheduler & DelayGroup(group_t const group, std::chrono::duration< _Rep, _Period > const &duration)
Delays all tasks of a group with the given duration.
clock_t::duration duration_t
TaskScheduler & Schedule(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max, task_handler_t const &task)
TaskScheduler & Schedule(std::chrono::duration< _Rep, _Period > const &time, group_t const group, task_handler_t const &task)
TaskScheduler & InsertTask(TaskContainer task)
Insert a new task to the enqueued tasks.
TaskScheduler & Schedule(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max, group_t const group, task_handler_t const &task)
TaskScheduler(TaskScheduler const &)=delete
timepoint_t _now
The current time point (now)
std::queue< std::function< void()> > AsyncHolder
std::chrono::steady_clock clock_t
TaskScheduler & DelayGroup(group_t const group, std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Delays all tasks of a group with a random duration between min and max.
static bool EmptyValidator()
TaskScheduler & ScheduleAt(timepoint_t const &end, std::chrono::duration< _Rep, _Period > const &time, group_t const group, task_handler_t const &task)
TaskQueue _task_holder
The Task Queue which contains all task objects.
TaskScheduler & SetValidator(P &&predicate)
Sets a validator which is asked if tasks are allowed to be executed.
static void EmptyCallback()
TaskScheduler & RescheduleGroup(group_t const group, std::chrono::duration< _Rep, _Period > const &duration)
Reschedule all tasks of a group with the given duration.
TaskScheduler & RescheduleAll(std::chrono::duration< _RepLeft, _PeriodLeft > const &min, std::chrono::duration< _RepRight, _PeriodRight > const &max)
Reschedule all tasks with a random duration between min and max.
Container which provides Task order, insert and reschedule operations.