18#ifndef TRINITYCORE_TASK_SCHEDULER_H
19#define TRINITYCORE_TASK_SCHEDULER_H
52 typedef std::chrono::steady_clock
clock_t;
82 : _end(end), _duration(duration), _group(group), _repeated(repeated), _task(
std::move(task)) { }
86 : _end(end), _duration(duration), _group(
std::nullopt), _repeated(0), _task(
std::move(task)) { }
102 return std::compare_weak_order_fallback(_end, other.
_end);
108 return _end == other.
_end;
114 return _group == group;
125 return (*left.get()) < (*right.get());
144 void RemoveIf(std::function<
bool(
TaskContainer const&)>
const& filter);
146 void ModifyIf(std::function<
bool(
TaskContainer const&)>
const& filter);
148 bool IsEmpty()
const;
179 : self_reference(this, [](
TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { }
192 _predicate = std::forward<P>(predicate);
209 template<
class Rep,
class Period>
224 template<
class Rep,
class Period>
228 return this->ScheduleAt(_now, time, std::move(task));
233 template<
class Rep,
class Period>
237 return this->ScheduleAt(_now, time, group, std::move(task));
242 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
244 std::chrono::duration<RepRight, PeriodRight> max,
task_handler_t task)
246 return this->Schedule(
::randtime(min, max), std::move(task));
251 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
253 std::chrono::duration<RepRight, PeriodRight> max,
group_t const group,
256 return this->Schedule(
::randtime(min, max), group, std::move(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> 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> min,
312 std::chrono::duration<RepRight, PeriodRight> max)
314 return this->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> max)
335 return this->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> min,
360 std::chrono::duration<RepRight, PeriodRight> max)
362 return this->RescheduleGroup(group,
::randtime(min, max));
369 template<
class Rep,
class Period>
378 template<
class Rep,
class Period>
380 std::chrono::duration<Rep, Period> time,
383 static constexpr repeated_t DEFAULT_REPEATED = 0;
384 return InsertTask(
TaskContainer(
new Task(end + time, time, group, DEFAULT_REPEATED, std::move(task))));
388 void Dispatch(success_t
const& callback);
410 : _task(), _owner(), _consumed(
std::make_shared<bool>(true)) { }
414 : _task(
std::move(task)), _owner(
std::move(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)) { }
441 _task = std::move(right._task);
442 _owner = std::move(right._owner);
443 _consumed = std::move(right._consumed);
451 bool IsExpired()
const;
469 template<
class Rep,
class Period>
475 _task->_duration = duration;
476 _task->_end += duration;
477 _task->_repeated += 1;
490 return Repeat(_task->_duration);
497 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
499 std::chrono::duration<RepRight, PeriodRight> max)
512 template<
class Rep,
class Period>
516 auto const end = _task->_end;
527 template<
class Rep,
class Period>
531 auto const end = _task->_end;
534 return scheduler.
ScheduleAt<Rep,
Period>(end, time, group, std::move(task));
542 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
553 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
572 template<
class Rep,
class Period>
577 return scheduler.
DelayAll(duration);
582 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
584 std::chrono::duration<RepRight, PeriodRight> max)
590 template<
class Rep,
class Period>
600 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
602 std::chrono::duration<RepLeft, PeriodLeft> min,
603 std::chrono::duration<RepRight, PeriodRight> max)
609 template<
class Rep,
class Period>
619 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
621 std::chrono::duration<RepRight, PeriodRight> max)
627 template<
class Rep,
class Period>
637 template<
class RepLeft,
class PeriodLeft,
class RepRight,
class PeriodRight>
639 std::chrono::duration<RepLeft, PeriodLeft> min,
640 std::chrono::duration<RepRight, PeriodRight> max)
647 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 & Schedule(std::chrono::duration< Rep, Period > time, TaskScheduler::task_handler_t task)
TaskContext & Schedule(std::chrono::duration< Rep, Period > time, TaskScheduler::group_t const group, TaskScheduler::task_handler_t task)
TaskContext & operator=(TaskContext &&right) noexcept
TaskContext & RescheduleAll(std::chrono::duration< Rep, Period > duration)
Reschedule all tasks with the given duration.
TaskContext & DelayGroup(TaskScheduler::group_t const group, std::chrono::duration< Rep, Period > duration)
Delays all tasks of a group with the given duration from within the context.
TaskContext & DelayGroup(TaskScheduler::group_t const group, std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Delays all tasks of a group with a random duration between min and max from within the context.
TaskContext & Repeat(std::chrono::duration< Rep, Period > duration)
TaskContext & RescheduleAll(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Reschedule all tasks with a random duration between min and max.
TaskContext & RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Reschedule all tasks of a group with a random duration between min and max.
TaskContext(TaskContext &&right) noexcept
TaskScheduler::TaskContainer _task
Associated task.
TaskContext & Schedule(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max, TaskScheduler::task_handler_t task)
std::weak_ptr< TaskScheduler > _owner
Owner.
std::shared_ptr< bool > _consumed
Marks the task as consumed.
TaskContext & operator=(TaskContext const &right)
TaskContext & RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration< Rep, Period > duration)
Reschedule all tasks of a group with the given duration.
TaskContext & DelayAll(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Delays all tasks with a random duration between min and max from within the context.
TaskContext(TaskContext const &right)
TaskContext & Repeat(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
TaskContext & DelayAll(std::chrono::duration< Rep, Period > duration)
Delays all tasks with the given duration from within the context.
TaskContext(TaskScheduler::TaskContainer &&task, std::weak_ptr< TaskScheduler > &&owner)
TaskContext & Schedule(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max, TaskScheduler::group_t const group, TaskScheduler::task_handler_t task)
void ModifyIf(std::function< bool(TaskContainer const &)> const &filter)
std::multiset< TaskContainer, Compare > container
bool IsInGroup(group_t const group) const
Task(timepoint_t end, duration_t duration, task_handler_t task)
Optional< group_t > _group
Task(Task const &)=delete
Task(timepoint_t end, duration_t duration, Optional< group_t > group, repeated_t const repeated, task_handler_t task)
TaskScheduler & CancelGroup(group_t group)
TaskScheduler & CancelAll()
std::shared_ptr< Task > TaskContainer
TaskScheduler & operator=(TaskScheduler const &)=delete
TaskScheduler & RescheduleAll(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Reschedule all tasks with a random duration between min and max.
clock_t::time_point timepoint_t
TaskScheduler & ScheduleAt(timepoint_t end, std::chrono::duration< Rep, Period > time, group_t const group, task_handler_t task)
TaskScheduler & CancelGroupsOf(std::vector< group_t > const &groups)
void Dispatch(success_t const &callback)
Dispatch remaining tasks.
TaskScheduler & RescheduleAll(std::chrono::duration< Rep, Period > duration)
Reschedule all tasks with a given duration.
TaskScheduler & Schedule(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max, group_t const group, task_handler_t task)
TaskScheduler(TaskScheduler &&)=delete
std::function< void()> success_t
TaskScheduler & DelayAll(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Delays all tasks with a random duration between min and max.
TaskScheduler & DelayAll(std::chrono::duration< Rep, Period > duration)
Delays all tasks with the given duration.
TaskScheduler & Update(std::chrono::duration< Rep, Period > difftime, success_t const &callback=nullptr)
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 & Schedule(std::chrono::duration< Rep, Period > time, group_t const group, task_handler_t task)
TaskScheduler & Schedule(std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max, task_handler_t task)
TaskScheduler(P &&predicate)
TaskScheduler & ScheduleAt(timepoint_t end, std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & DelayGroup(group_t const group, std::chrono::duration< Rep, Period > duration)
Delays all tasks of a group with the given duration.
clock_t::duration duration_t
TaskScheduler & Schedule(std::chrono::duration< Rep, Period > time, task_handler_t task)
TaskScheduler & InsertTask(TaskContainer task)
Insert a new task to the enqueued tasks.
TaskScheduler(TaskScheduler const &)=delete
TaskScheduler & RescheduleGroup(group_t const group, std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Reschedule all tasks of a group with a random duration between min and max.
TaskScheduler & DelayGroup(group_t const group, std::chrono::duration< RepLeft, PeriodLeft > min, std::chrono::duration< RepRight, PeriodRight > max)
Delays all tasks of a group with a random duration between min and max.
timepoint_t _now
The current time point (now)
std::queue< std::function< void()> > AsyncHolder
TaskScheduler & Async(std::function< void()> callable)
std::chrono::steady_clock clock_t
TaskScheduler & RescheduleGroup(group_t const group, std::chrono::duration< Rep, Period > duration)
Reschedule all tasks of a group with the given duration.
static bool EmptyValidator()
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.
bool operator==(unique_trackable_ptr< T1 > const &left, unique_trackable_ptr< T2 > const &right)
void Update(VignetteData &vignette, WorldObject const *owner)
Container which provides Task order, insert and reschedule operations.