From 3d95aba2b3d58057f3eeed6d4dd6e51ea49b77f6 Mon Sep 17 00:00:00 2001 From: Naios Date: Sun, 21 Jun 2015 18:04:47 +0200 Subject: Core/Utilities: TaskScheduler: add a task validator and on update success callback. * makes it possible to block tasks if there is an active spellcast. * requested by @joschiwald --- src/server/shared/Utilities/TaskScheduler.cpp | 34 ++++++++++++++++--- src/server/shared/Utilities/TaskScheduler.h | 48 +++++++++++++++++++++++---- 2 files changed, 70 insertions(+), 12 deletions(-) (limited to 'src') 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 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 task_handler_t; + // Predicate type + typedef std::function predicate_t; + // Success handle type + typedef std::function 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 + TaskScheduler(P&& predicate) + : self_reference(this, [](TaskScheduler const*) { }), _now(clock_t::now()), _predicate(std::forward

(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 + TaskScheduler& SetValidator(P&& predicate) + { + _predicate = std::forward

(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 - 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 -- cgit v1.2.3