Tasks
An interface that encapsulates asynchronous tasks, that can be started,
then take some time and finally succeed or fail.
Applications can use this interface as a base class for their tasks.
File information
Classes
ITask
class ITask {
protected:
class UTask * user;
public:
ITask();
virtual ~ITask() {}
virtual void Start() {};
virtual void Start(class UTask * user) = 0;
virtual void Stop() { stopped = true; };
virtual void Complete() { if (user) user->TaskComplete(this); };
virtual void Failed() { if (user) user->TaskFailed(this); };
virtual void Progress(dword progress) { if (user) user->TaskProgress(this, progress); };
virtual void Finished() {};
bool error;
bool stopped;
};
The ITask class is a base class for tasks which shall do asynchronous operations and callback later a result on a UTask user.
Public functions
ITask()
The constructor of the class.
Parameters
virtual void Start()
Start function of a task, not to be used.
Parameters
virtual void Start(class UTask * user)
Start function of a task. Override this function in your parent class.
Parameters
class UTask * user | The UTask instance which will receive the callbacks. |
virtual void Stop()
Stop function of a task. The default implemenation just sets stopped to true.
You can override Stop and implement a logic to interrupt a task.
Parameters
virtual void Complete()
This function can be used as a shortcut instead of calling user->TaskComplete(this).
Parameters
virtual void Failed()
This function can be used as a shortcut instead of calling user->TaskFailed(this).
Parameters
virtual void Progress(dword progress)
This function can be used as a shortcut instead of calling user->TaskProgress(this, progress).
Parameters
dword progress | A dword to differentiate between different progress states. |
virtual void Finished()
This function can be overwritten to implement a Finished function which e.g. handles success and failed together.
Parameters
Public members
bool error | A boolean which can be set to true to indicate an error. |
bool stopped | A boolean which can be set to true to indicate that the task has been stopped. |
UTask
class UTask {
public:
virtual ~UTask() {};
virtual void TaskComplete(class ITask * const task) = 0;
virtual void TaskFailed(class ITask * const task) = 0;
virtual void TaskProgress(class ITask * const task, dword progress = 0) {};
};
The UTask class is a base class for classes which handle the callbacks from ITask tasks.
Public virtual functions
virtual void TaskComplete(class ITask * const task)
Callback that is called if the task is completed successfully.
If the implementation needs to return data as a result of the task,
this is outside the scope of the ITask interface.
Instead implementations should provid getter functions for result data.
Parameters
class ITask * const task | The ITask instance of the task itself. |
virtual void TaskFailed(class ITask * const task)
Callback that is called if the task failed.
Parameters
class ITask * const task | The ITask instance of the task itself. |
virtual void TaskProgress(class ITask * const task, dword progress)
Callback that is called if there was some progress to the task.
Parameters
class ITask * const task | The ITask instance of the task itself. |
dword progress | The nummeric value 'progress' can be used to indicate additional information the type of the progress. |
UTaskTemplate
template class UTaskTemplate : public UTask {
public:
UTaskTemplate(B * base,
void (B::* taskComplete)(T * task),
void (B::* taskFailed)(T * task) = 0,
void (B::* taskProgress)(T * task, dword progress) = 0);
};
Just using UTask is fine for classes which handle one task, but if you have a class which handles many different tasks, you would need to dynamic cast inside TaskComplete/TaskFailed/TaskProgress.
UTaskTemplate helps to avoid this by handing a member which can be added to the class which used to be derived from UTask. Instead of handing this to the ITask::Start function, you hand a reference to the member, which itself has specific callback functions.
Public functions
UTaskTemplate(B * base,
void (B::* taskComplete)(T * task),
void (B::* taskFailed)(T * task) = 0,
void (B::* taskProgress)(T * task, dword progress) = 0)
The constructor of the class.
Parameters
B * base | The class which has the member of UTaskTemplate. |
void (B::* taskComplete)(T * task) | The specific TaskComplete function of the calling class. |
void (B::* taskFailed)(T * task) | The specific TaskFailed function of the calling class. |
void (B::* taskProgress)(T * task) | The specific TaskProgress function of the calling class. |
Remarks
The error property of the ITask instance is automatically set to true if TaskFailed is called.
Examples
Task
// a class which has UTask as base class and calls an ITask instance
class TaskHandler : public UTask {
class TaskExecutor * task;
public:
TaskHandler();
void TaskComplete(class ITask * task) override;
void TaskFailed(class ITask * task) override;
void TaskProgress(class ITask * task, dword progress = 0) override;
}
// a class which has ITask as base class which can be used by class TaskHandler
class TaskExecutor : public ITask {
public:
void Start(class UTask * user) override; // do some async processing and call TaskFailed/TaskComplete later (async!)
void Stop() override;
}
// implementation
TaskHandler::TaskHandler() {
this->task = new class TaskExecutor();
this->task->Start(this);
}
void TaskHandler::TaskComplete(class ITask * task) {
debug->printf("done");
this->task = nullptr;
delete task;
}
void TaskHandler::TaskFailed(class ITask * task) {
debug->printf("failed");
this->task = nullptr;
delete task;
}
void TaskHandler::TaskProgress(class ITask * task, dword progress = 0) {
debug->printf("progress");
}
UTaskTemplate
// instead of having a base class UTask, we have a member from UTaskTemplate
class TaskHandler {
UTaskTemplate taskExecutor;
class ITask * task;
void TaskExecutorFinished(class TaskExecutor * task);
void TaskExecutorFailed(class TaskExecutor * task);
void TaskExecutorProgress(class TaskExecutor * task, dword progress = 0);
}
// implementation
TaskHandler::TaskHandler() :
// hand all the callback functions of our class to the taskExecutor member
taskExecutor(this, &TaskHandler::TaskExecutorFinished, &TaskHandler::TaskExecutorFailed, &TaskHandler::TaskExecutorProgress)
{
this->task = new class TaskExecutor();
this->task->Start(&taskExecutor); // hand a reference to taskExecutor instead of this
}
void TaskHandler::TaskExecutorFinished(class TaskExecutor * task) {
debug->printf("done");
this->task = nullptr;
delete task;
}
void TaskHandler::TaskExecutorFailed(class TaskExecutor * task) {
debug->printf("failed");
this->task = nullptr;
delete task;
}
void TaskHandler::TaskExecutorProgress(class TaskExecutor * task, dword progress = 0) {
debug->printf("progress");
}