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
This commit is contained in:
Naios
2015-06-21 18:04:47 +02:00
parent bd661b58fd
commit 3d95aba2b3
2 changed files with 71 additions and 13 deletions

View File

@@ -17,16 +17,22 @@
#include "TaskScheduler.h"
TaskScheduler& TaskScheduler::Update()
TaskScheduler& TaskScheduler::ClearValidator()
{
_now = clock_t::now();
Dispatch();
_predicate = EmptyValidator;
return *this;
}
TaskScheduler& TaskScheduler::Update(size_t const milliseconds)
TaskScheduler& TaskScheduler::Update(success_t const& callback)
{
return Update(std::chrono::milliseconds(milliseconds));
_now = clock_t::now();
Dispatch(callback);
return *this;
}
TaskScheduler& TaskScheduler::Update(size_t const milliseconds, success_t const& callback)
{
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)

View File

@@ -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