diff options
-rw-r--r-- | src/server/shared/Utilities/TaskScheduler.cpp | 34 | ||||
-rw-r--r-- | src/server/shared/Utilities/TaskScheduler.h | 48 |
2 files changed, 70 insertions, 12 deletions
diff --git a/src/server/shared/Utilities/TaskScheduler.cpp b/src/server/shared/Utilities/TaskScheduler.cpp index 4b261413fd9..04a4071d1f5 100644 --- a/src/server/shared/Utilities/TaskScheduler.cpp +++ b/src/server/shared/Utilities/TaskScheduler.cpp @@ -17,16 +17,22 @@ #include "TaskScheduler.h" -TaskScheduler& TaskScheduler::Update() +TaskScheduler& TaskScheduler::ClearValidator() +{ + _predicate = EmptyValidator; + return *this; +} + +TaskScheduler& TaskScheduler::Update(success_t const& callback) { _now = clock_t::now(); - Dispatch(); + Dispatch(callback); return *this; } -TaskScheduler& TaskScheduler::Update(size_t const milliseconds) +TaskScheduler& TaskScheduler::Update(size_t const milliseconds, success_t const& callback) { - return Update(std::chrono::milliseconds(milliseconds)); + return Update(std::chrono::milliseconds(milliseconds), callback); } TaskScheduler& TaskScheduler::Async(std::function<void()> const& callable) @@ -66,15 +72,26 @@ TaskScheduler& TaskScheduler::InsertTask(TaskContainer task) return *this; } -void TaskScheduler::Dispatch() +void TaskScheduler::Dispatch(success_t const& callback) { + // If the validation failed abort the dispatching here. + if (!_predicate()) + return; + // Process all asyncs while (!_asyncHolder.empty()) { _asyncHolder.front()(); _asyncHolder.pop(); + + // If the validation failed abort the dispatching here. + if (!_predicate()) + return; } + if (_task_holder.IsEmpty()) + return; + while (!_task_holder.IsEmpty()) { if (_task_holder.First()->_end > _now) @@ -86,7 +103,14 @@ void TaskScheduler::Dispatch() // Invoke the context context.Invoke(); + + // If the validation failed abort the dispatching here. + if (!_predicate()) + return; } + + // On finish call the final callback + callback(); } void TaskScheduler::TaskQueue::Push(TaskContainer&& task) diff --git a/src/server/shared/Utilities/TaskScheduler.h b/src/server/shared/Utilities/TaskScheduler.h index 98e210e55b1..d45835b5f17 100644 --- a/src/server/shared/Utilities/TaskScheduler.h +++ b/src/server/shared/Utilities/TaskScheduler.h @@ -60,6 +60,10 @@ class TaskScheduler typedef uint32 repeated_t; // Task handle type typedef std::function<void(TaskContext)> task_handler_t; + // Predicate type + typedef std::function<bool()> predicate_t; + // Success handle type + typedef std::function<void()> success_t; class Task { @@ -163,27 +167,57 @@ class TaskScheduler /// the next update tick. AsyncHolder _asyncHolder; + predicate_t _predicate; + + static bool EmptyValidator() + { + return true; + } + + static void EmptyCallback() + { + } + public: - TaskScheduler() : self_reference(this, [](TaskScheduler const*) { }), - _now(clock_t::now()) { } + TaskScheduler() + : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(EmptyValidator) { } + + template<typename P> + TaskScheduler(P&& predicate) + : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward<P>(predicate)) { } TaskScheduler(TaskScheduler const&) = delete; TaskScheduler(TaskScheduler&&) = delete; TaskScheduler& operator= (TaskScheduler const&) = delete; TaskScheduler& operator= (TaskScheduler&&) = delete; + /// Sets a validator which is asked if tasks are allowed to be executed. + template<typename P> + TaskScheduler& SetValidator(P&& predicate) + { + _predicate = std::forward<P>(predicate); + return *this; + } + + /// Clears the validator which is asked if tasks are allowed to be executed. + TaskScheduler& ClearValidator(); + /// Update the scheduler to the current time. - TaskScheduler& Update(); + /// Calls the optional callback on successfully finish. + TaskScheduler& Update(success_t const& callback = EmptyCallback); /// Update the scheduler with a difftime in ms. - TaskScheduler& Update(size_t const milliseconds); + /// Calls the optional callback on successfully finish. + TaskScheduler& Update(size_t const milliseconds, success_t const& callback = EmptyCallback); /// 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> const& difftime) + TaskScheduler& Update(std::chrono::duration<_Rep, _Period> const& difftime, + success_t const& callback = EmptyCallback) { _now += difftime; - Dispatch(); + Dispatch(callback); return *this; } @@ -370,7 +404,7 @@ private: } /// Dispatch remaining tasks - void Dispatch(); + void Dispatch(success_t const& callback); }; class TaskContext |