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

Filecommon/interface/task.h

Classes ITask
UTask
UTaskTemplate
Examples Task
UTaskTemplate

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 * userThe 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 progressA 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 errorA boolean which can be set to true to indicate an error.
bool stoppedA 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 taskThe 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 taskThe 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 taskThe ITask instance of the task itself.
dword progressThe 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 * baseThe 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");
}