aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaios <naios-dev@live.de>2015-06-21 18:04:47 +0200
committerNaios <naios-dev@live.de>2015-06-21 18:19:17 +0200
commit3d95aba2b3d58057f3eeed6d4dd6e51ea49b77f6 (patch)
tree029607567faa34caf217f7b60bf9a4877c3ddfeb
parentbd661b58fd2c37850a719cfffe135e89043c112d (diff)
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
-rw-r--r--src/server/shared/Utilities/TaskScheduler.cpp34
-rw-r--r--src/server/shared/Utilities/TaskScheduler.h48
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