Back to Index

Task

Inherits from: SignalSlot

Contents

The Task class serves as the foundation for all task components in the framework. It inherits from SignalSlot to provide signal/slot communication capabilities and establishes common signals for task lifecycle events. This class provides a consistent foundation that all specialized task types build upon.

Class Interface

class Task : public SignalSlot {
public:
    Task();
    virtual ~Task() = default;
};

While the interface is minimal, the Task class establishes the crucial foundation of common signals that create a consistent communication pattern across the framework.

Standard Signals

The Task class automatically creates these standard signals during construction:

Signal Type Description
started simple Simple Emitted when the task begins execution
finished simple Simple Emitted when the task completes execution
log data Data Emitted with informational log messages
warn data Data Emitted with warning messages
error data Data Emitted with error messages

Implementation

Here's how the Task class is implemented:

Task::Task() {
    // Create simple notification signals (no arguments)
    createSimpleSignal("started");
    createSimpleSignal("finished");

    // Create data signals (with ArgumentPack)
    createDataSignal("log");
    createDataSignal("warn");
    createDataSignal("error");
}
Note: While the implementation is simple, it establishes a consistent communication pattern that all task-based components follow. This consistency is key to the framework's design.

Usage

The Task class is primarily used as a base class. Here's a simple example of a class deriving from Task:

Basic Task Subclass
class CustomTask : public Task {
public:
    CustomTask(const std::string& name) : m_name(name) {
        // Create additional signals if needed
        createDataSignal("result");
    }
    
    void start() {
        // Signal that we're starting
        emit("started");
        
        try {
            // Perform task work
            emitString("log", m_name + " is executing");
            
            // Create a result
            ArgumentPack resultArgs;
            resultArgs.add("Operation completed");
            resultArgs.add(42);
            emit("result", resultArgs);
            
            // Signal completion
            emit("finished");
        } catch (const std::exception& e) {
            // Report error
            emitString("error", m_name + " failed: " + e.what());
        }
    }
    
private:
    std::string m_name;
};
Using a Task
// Create the task
auto task = std::make_shared("MyTask");

// Connect to standard Task signals
task->connectSimple("started", []() {
    std::cout << "Task started" << std::endl;
});

task->connectSimple("finished", []() {
    std::cout << "Task finished" << std::endl;
});

task->connectData("log", [](const ArgumentPack& args) {
    std::string message = args.get(0);
    std::cout << "LOG: " << message << std::endl;
});

task->connectData("error", [](const ArgumentPack& args) {
    std::string message = args.get(0);
    std::cerr << "ERROR: " << message << std::endl;
});

// Connect to custom signals
task->connectData("result", [](const ArgumentPack& args) {
    std::string status = args.get(0);
    int value = args.get(1);
    std::cout << "Result: " << status << ", value=" << value << std::endl;
});

// Execute the task
task->start();

Extensions

The Task class is extended by several specialized classes in the framework:

Best Practice: When creating a new component that needs to communicate with other parts of the system, consider deriving from Task rather than directly from SignalSlot to ensure consistent signal patterns.