18#ifndef TRINITYCORE_TASK_SCHEDULER_H
19#define TRINITYCORE_TASK_SCHEDULER_H
55 typedef std::chrono::steady_clock
clock_t;
74 template <
typename InnerHandler>
requires (!std::same_as<InnerHandler, TaskHandler>)
75 TaskHandler(InnerHandler&& handler) : _handler(TaskHandler::Wrap(std::forward<InnerHandler>(handler))) { }
80 template <
typename InnerHandler>
81 static decltype(
auto)
Wrap(InnerHandler&& handler)
83 if constexpr (std::invocable<InnerHandler, TaskContext&>)
85 return std::forward<InnerHandler>(handler);
87 else if constexpr (std::invocable<InnerHandler, TaskContext&&>)
90 return [inner = std::forward<InnerHandler>(handler)](
TaskContext& context)
97 static_assert(Trinity::dependant_false_v<InnerHandler>,
"Unsupported task argument type, must be TaskContext& or TaskContext const&");
119 : _end(end), _duration(duration), _group(group), _repeated(repeated), _task(
std::move(task)) { }
123 : _end(end), _duration(duration), _group(
std::nullopt), _repeated(0), _task(
std::move(task)) { }
139 return std::compare_weak_order_fallback(_end, other.
_end);
143 bool operator== (
Task const& other)
const
145 return _end == other.
_end;
151 return _group == group;
162 return (*left.get()) < (*right.get());
169 typedef std::multiset<TaskContainer, Compare>
Container;
179 void Push(Container::node_type&& node);
182 Container::node_type Pop();
188 void RemoveIf(std::function<
bool(
TaskContainer const&)>
const& filter);
190 void ModifyIf(std::function<
bool(
TaskContainer const&)>
const& filter);
192 bool IsEmpty()
const;
216 : self_reference(this, [](
TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { }
229 _predicate = std::forward<P>(predicate);
268 return this->ScheduleAt(_now, time, std::move(task));
276 return this->ScheduleAt(_now, time, group, std::move(task));
284 return this->Schedule(
::randtime(min, max), std::move(task));
290 std::chrono::milliseconds max,
group_t group,
293 return this->Schedule(
::randtime(min, max), group, std::move(task));
313 std::chrono::milliseconds max)
319 TaskScheduler& DelayGroup(group_t group, duration_t duration);
323 std::chrono::milliseconds min,
324 std::chrono::milliseconds max)
326 return this->DelayGroup(group,
::randtime(min, max));
335 return this->RescheduleAll(
::randtime(min, max));
339 TaskScheduler& RescheduleGroup(group_t group, duration_t duration);
343 std::chrono::milliseconds min,
344 std::chrono::milliseconds max)
346 return this->RescheduleGroup(group,
::randtime(min, max));
354 TaskScheduler& InsertTask(TaskQueue::Container::node_type&& node);
357 duration_t time, task_handler_t task);
363 group_t group, task_handler_t task);
366 void Dispatch(success_t
const& callback);
374 std::variant<TaskScheduler::TaskQueue::Container::node_type ,
383 : _task(), _owner() { }
386 explicit TaskContext(TaskScheduler::TaskQueue::Container::node_type&& task, std::weak_ptr<TaskScheduler>&& owner)
noexcept;
403 bool IsExpired()
const;
433 std::chrono::milliseconds max)
440 TaskContext& Async(std::function<
void()> callable);
463 return this->Schedule(
::randtime(min, max), std::move(task));
474 return this->Schedule(
::randtime(min, max), group, std::move(task));
485 TaskContext& CancelGroupsOf(std::span<TaskScheduler::group_t> groups);
492 std::chrono::milliseconds max)
502 std::chrono::milliseconds min,
503 std::chrono::milliseconds max)
505 return this->DelayGroup(group,
::randtime(min, max));
513 std::chrono::milliseconds max)
515 return this->RescheduleAll(
::randtime(min, max));
523 std::chrono::milliseconds min,
524 std::chrono::milliseconds max)
526 return this->RescheduleGroup(group,
::randtime(min, max));
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 group, std::chrono::milliseconds min, std::chrono::milliseconds max)
Reschedule all tasks of a group with a random duration between min and max.
TaskContext & Schedule(std::chrono::milliseconds min, std::chrono::milliseconds max, TaskScheduler::task_handler_t task)
TaskContext & Repeat(std::chrono::milliseconds min, std::chrono::milliseconds max)
TaskContext & RescheduleAll(std::chrono::milliseconds min, std::chrono::milliseconds max)
Reschedule all tasks with a random duration between min and max.
std::variant< TaskScheduler::TaskQueue::Container::node_type, TaskScheduler::TaskContainer > _task
Associated task.
std::weak_ptr< TaskScheduler > _owner
Owner.
TaskContext(TaskContext const &right)=delete
TaskContext & DelayGroup(TaskScheduler::group_t group, std::chrono::milliseconds min, std::chrono::milliseconds max)
Delays all tasks of a group with a random duration between min and max from within the context.
TaskContext & operator=(TaskContext const &right)=delete
TaskContext & Schedule(std::chrono::milliseconds min, std::chrono::milliseconds max, TaskScheduler::group_t group, TaskScheduler::task_handler_t task)
TaskContext & DelayAll(std::chrono::milliseconds min, std::chrono::milliseconds max)
Delays all tasks with a random duration between min and max from within the context.
std::function< void(TaskContext &)> _handler
static decltype(auto) Wrap(InnerHandler &&handler)
void operator()(TaskContext &context) const
TaskHandler(InnerHandler &&handler)
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)
std::shared_ptr< Task > TaskContainer
clock_t::time_point timepoint_t
TaskScheduler(TaskScheduler &&)=delete
std::function< void()> success_t
TaskScheduler & DelayGroup(group_t group, std::chrono::milliseconds min, std::chrono::milliseconds max)
Delays all tasks of a group with a random duration between min and max.
std::shared_ptr< TaskScheduler > self_reference
Contains a self reference to track if this object was deleted or not.
std::function< bool()> predicate_t
TaskScheduler & Schedule(std::chrono::milliseconds min, std::chrono::milliseconds max, task_handler_t task)
TaskHandler task_handler_t
TaskScheduler(P &&predicate)
TaskScheduler & Schedule(duration_t time, group_t group, task_handler_t task)
clock_t::duration duration_t
TaskScheduler & Schedule(duration_t time, task_handler_t task)
static success_t const EmptySuccessCallback
TaskScheduler & Schedule(std::chrono::milliseconds min, std::chrono::milliseconds max, group_t group, task_handler_t task)
TaskScheduler(TaskScheduler const &)=delete
TaskScheduler & RescheduleAll(std::chrono::milliseconds min, std::chrono::milliseconds max)
Reschedule all tasks with a random duration between min and max.
timepoint_t _now
The current time point (now)
TaskScheduler & RescheduleGroup(group_t group, std::chrono::milliseconds min, std::chrono::milliseconds max)
Reschedule all tasks of a group with a random duration between min and max.
std::chrono::steady_clock clock_t
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.
TaskScheduler & DelayAll(std::chrono::milliseconds min, std::chrono::milliseconds max)
Delays all tasks with a random duration between min and max.
Container which provides Task order, insert and reschedule operations.