diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-12-08 20:27:41 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2023-12-08 20:27:41 +0100 |
commit | 78bcc3f52a1daa406851e7121c2b1af392fb4b3c (patch) | |
tree | 747d2e3496a08c5594bc05e08c6da7c515e7aa59 /src/common/Utilities/TaskScheduler.h | |
parent | f038c8526a2993ea9c71e47869cc4ae658159089 (diff) |
Core/Misc: Minor code modernization - kill std::bind
Diffstat (limited to 'src/common/Utilities/TaskScheduler.h')
-rw-r--r-- | src/common/Utilities/TaskScheduler.h | 247 |
1 files changed, 137 insertions, 110 deletions
diff --git a/src/common/Utilities/TaskScheduler.h b/src/common/Utilities/TaskScheduler.h index e76e6f1c45e..2ebd3e57b37 100644 --- a/src/common/Utilities/TaskScheduler.h +++ b/src/common/Utilities/TaskScheduler.h @@ -15,8 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _TASK_SCHEDULER_H_ -#define _TASK_SCHEDULER_H_ +#ifndef TRINITYCORE_TASK_SCHEDULER_H +#define TRINITYCORE_TASK_SCHEDULER_H #include "Duration.h" #include "Optional.h" @@ -94,6 +94,8 @@ class TC_COMMON_API TaskScheduler // Move Assign Task& operator= (Task&& right) = delete; + ~Task() = default; + // Order tasks by its end std::weak_ordering operator<=> (Task const& other) const { @@ -181,6 +183,8 @@ public: TaskScheduler& operator= (TaskScheduler const&) = delete; TaskScheduler& operator= (TaskScheduler&&) = delete; + ~TaskScheduler() = default; + /// Sets a validator which is asked if tasks are allowed to be executed. template<typename P> TaskScheduler& SetValidator(P&& predicate) @@ -198,12 +202,12 @@ public: /// Update the scheduler with a difftime in ms. /// Calls the optional callback on successfully finish. - TaskScheduler& Update(size_t const milliseconds, success_t const& callback = nullptr); + TaskScheduler& Update(size_t milliseconds, success_t const& callback = nullptr); /// 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, + template<class Rep, class Period> + TaskScheduler& Update(std::chrono::duration<Rep, Period> difftime, success_t const& callback = nullptr) { _now += difftime; @@ -217,39 +221,39 @@ 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, + template<class Rep, class Period> + TaskScheduler& Schedule(std::chrono::duration<Rep, Period> time, task_handler_t task) { - return ScheduleAt(_now, time, std::move(task)); + return this->ScheduleAt(_now, time, std::move(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& Schedule(std::chrono::duration<_Rep, _Period> time, + template<class Rep, class Period> + TaskScheduler& Schedule(std::chrono::duration<Rep, Period> time, group_t const group, task_handler_t task) { - return ScheduleAt(_now, time, group, std::move(task)); + return this->ScheduleAt(_now, time, group, std::move(task)); } /// 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) + 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) { - return Schedule(randtime(min, max), std::move(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, + 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, task_handler_t task) { - return Schedule(randtime(min, max), group, std::move(task)); + return this->Schedule(::randtime(min, max), group, std::move(task)); } /// Cancels all tasks. @@ -258,15 +262,15 @@ public: /// Cancel all tasks of a single group. /// Never call this from within a task context! Use TaskContext::CancelGroup instead! - TaskScheduler& CancelGroup(group_t const group); + TaskScheduler& CancelGroup(group_t group); /// Cancels all groups in the given std::vector. /// Hint: Use std::initializer_list for this: "{1, 2, 3, 4}" 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) + template<class Rep, class Period> + TaskScheduler& DelayAll(std::chrono::duration<Rep, Period> duration) { _task_holder.ModifyIf([&duration](TaskContainer const& task) -> bool { @@ -277,16 +281,16 @@ public: } /// 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) + template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> + TaskScheduler& DelayAll(std::chrono::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return DelayAll(randtime(min, 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) + 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 { @@ -302,17 +306,17 @@ public: } /// Delays all tasks of a group with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> + 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::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return DelayGroup(group, randtime(min, 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) + 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 @@ -324,16 +328,16 @@ public: } /// 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) + template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> + TaskScheduler& RescheduleAll(std::chrono::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return RescheduleAll(randtime(min, 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) + 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 @@ -350,33 +354,33 @@ public: } /// Reschedule all tasks of a group with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> + 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::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return RescheduleGroup(group, randtime(min, max)); + return this->RescheduleGroup(group, ::randtime(min, max)); } private: /// Insert a new task to the enqueued tasks. TaskScheduler& InsertTask(TaskContainer task); - template<class _Rep, class _Period> + template<class Rep, class Period> TaskScheduler& ScheduleAt(timepoint_t end, - std::chrono::duration<_Rep, _Period> time, task_handler_t task) + std::chrono::duration<Rep, Period> time, task_handler_t task) { return InsertTask(TaskContainer(new Task(end + time, time, std::move(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> + template<class Rep, class Period> TaskScheduler& ScheduleAt(timepoint_t end, - std::chrono::duration<_Rep, _Period> time, + std::chrono::duration<Rep, Period> time, group_t const group, task_handler_t task) { - static repeated_t const DEFAULT_REPEATED = 0; + static constexpr repeated_t DEFAULT_REPEATED = 0; return InsertTask(TaskContainer(new Task(end + time, time, group, DEFAULT_REPEATED, std::move(task)))); } @@ -407,7 +411,7 @@ public: // Construct from task and owner explicit TaskContext(TaskScheduler::TaskContainer&& task, std::weak_ptr<TaskScheduler>&& owner) - : _task(std::move(task)), _owner(owner), _consumed(std::make_shared<bool>(false)) { } + : _task(std::move(task)), _owner(std::move(owner)), _consumed(std::make_shared<bool>(false)) { } // Copy construct TaskContext(TaskContext const& right) @@ -418,23 +422,31 @@ public: : _task(std::move(right._task)), _owner(std::move(right._owner)), _consumed(std::move(right._consumed)) { } // Copy assign - TaskContext& operator= (TaskContext const& right) + TaskContext& operator=(TaskContext const& right) { - _task = right._task; - _owner = right._owner; - _consumed = right._consumed; + if (this != &right) + { + _task = right._task; + _owner = right._owner; + _consumed = right._consumed; + } return *this; } // Move assign - TaskContext& operator= (TaskContext&& right) noexcept + TaskContext& operator=(TaskContext&& right) noexcept { - _task = std::move(right._task); - _owner = std::move(right._owner); - _consumed = std::move(right._consumed); + if (this != &right) + { + _task = std::move(right._task); + _owner = std::move(right._owner); + _consumed = std::move(right._consumed); + } return *this; } + ~TaskContext() = default; + /// Returns true if the owner was deallocated and this context has expired. bool IsExpired() const; @@ -454,8 +466,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 _Rep, class _Period> - TaskContext& Repeat(std::chrono::duration<_Rep, _Period> duration) + template<class Rep, class Period> + TaskContext& Repeat(std::chrono::duration<Rep, Period> duration) { AssertOnConsumed(); @@ -464,7 +476,10 @@ public: _task->_end += duration; _task->_repeated += 1; (*_consumed) = true; - return Dispatch(std::bind(&TaskScheduler::InsertTask, std::placeholders::_1, _task)); + return this->Dispatch([this](TaskScheduler& scheduler) -> TaskScheduler& + { + return scheduler.InsertTask(_task); + }); } /// Repeats the event with the same duration. @@ -479,11 +494,11 @@ 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) + template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> + TaskContext& Repeat(std::chrono::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return Repeat(randtime(min, max)); + return this->Repeat(::randtime(min, max)); } /// Schedule a callable function that is executed at the next update tick from within the context. @@ -494,14 +509,14 @@ 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, + template<class Rep, class Period> + TaskContext& Schedule(std::chrono::duration<Rep, Period> time, TaskScheduler::task_handler_t task) { auto const end = _task->_end; - return Dispatch([end, time, task = std::move(task)](TaskScheduler& scheduler) -> TaskScheduler& + return this->Dispatch([end, time, task = std::move(task)](TaskScheduler& scheduler) -> TaskScheduler& { - return scheduler.ScheduleAt<_Rep, _Period>(end, time, std::move(task)); + return scheduler.ScheduleAt<Rep, Period>(end, time, std::move(task)); }); } @@ -509,14 +524,14 @@ 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, + 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 Dispatch([end, time, group, task = std::move(task)](TaskScheduler& scheduler) -> TaskScheduler& + return this->Dispatch([end, time, group, task = std::move(task)](TaskScheduler& scheduler) -> TaskScheduler& { - return scheduler.ScheduleAt<_Rep, _Period>(end, time, group, std::move(task)); + return scheduler.ScheduleAt<Rep, Period>(end, time, group, std::move(task)); }); } @@ -524,23 +539,23 @@ 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::task_handler_t task) + 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) { - return Schedule(randtime(min, max), std::move(task)); + return this->Schedule(::randtime(min, max), std::move(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::group_t const group, + 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, TaskScheduler::task_handler_t task) { - return Schedule(randtime(min, max), group, std::move(task)); + return this->Schedule(::randtime(min, max), group, std::move(task)); } /// Cancels all tasks from within the context. @@ -554,65 +569,77 @@ 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) + template<class Rep, class Period> + TaskContext& DelayAll(std::chrono::duration<Rep, Period> duration) { - return Dispatch(std::bind(&TaskScheduler::DelayAll<_Rep, _Period>, std::placeholders::_1, duration)); + return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& + { + return scheduler.DelayAll(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) + template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> + TaskContext& DelayAll(std::chrono::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return DelayAll(randtime(min, 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) + template<class Rep, class Period> + TaskContext& DelayGroup(TaskScheduler::group_t const group, std::chrono::duration<Rep, Period> duration) { - return Dispatch(std::bind(&TaskScheduler::DelayGroup<_Rep, _Period>, std::placeholders::_1, group, duration)); + return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& + { + return scheduler.DelayGroup(group, 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> + 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::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return DelayGroup(group, randtime(min, 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) + template<class Rep, class Period> + TaskContext& RescheduleAll(std::chrono::duration<Rep, Period> duration) { - return Dispatch(std::bind(&TaskScheduler::RescheduleAll, std::placeholders::_1, duration)); + return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& + { + return scheduler.RescheduleAll(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) + template<class RepLeft, class PeriodLeft, class RepRight, class PeriodRight> + TaskContext& RescheduleAll(std::chrono::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return RescheduleAll(randtime(min, 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) + template<class Rep, class Period> + TaskContext& RescheduleGroup(TaskScheduler::group_t const group, std::chrono::duration<Rep, Period> duration) { - return Dispatch(std::bind(&TaskScheduler::RescheduleGroup<_Rep, _Period>, std::placeholders::_1, group, duration)); + return this->Dispatch([=](TaskScheduler& scheduler) -> TaskScheduler& + { + return scheduler.RescheduleGroup(group, duration); + }); } /// Reschedule all tasks of a group with a random duration between min and max. - template<class _RepLeft, class _PeriodLeft, class _RepRight, class _PeriodRight> + 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::duration<RepLeft, PeriodLeft> min, + std::chrono::duration<RepRight, PeriodRight> max) { - return RescheduleGroup(group, randtime(min, max)); + return this->RescheduleGroup(group, ::randtime(min, max)); } private: @@ -623,4 +650,4 @@ private: void Invoke(); }; -#endif /// _TASK_SCHEDULER_H_ +#endif /// TRINITYCORE_TASK_SCHEDULER_H |