# 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

File | common/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 * 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");
    }