#include <iostream>
#include <memory>
#include <vector>

// ------------------ Receiver ------------------
// The class that actually executes the business logic
class Light {
public:
    void on() {
        std::cout << "💡 Light turned on (ON)" << std::endl;
    }
    void off() {
        std::cout << "💡 Light turned off (OFF)" << std::endl;
    }
};

// ------------------ Abstract Command ------------------
// Defines the unified interface for commands
class Command {
public:
    virtual ~Command() = default;
    virtual void execute() = 0;
    virtual void undo() = 0;
};

// ------------------ Concrete Command ------------------
// Light on command: binds receiver, implements execute/undo
class LightOnCommand : public Command {
private:
    Light* light_;  // Using raw pointer, lifetime managed externally
public:
    explicit LightOnCommand(Light* light) : light_(light) {}

    void execute() override {
        light_->on();
    }

    void undo() override {
        light_->off();
    }
};

// Light off command
class LightOffCommand : public Command {
private:
    Light* light_;
public:
    explicit LightOffCommand(Light* light) : light_(light) {}

    void execute() override {
        light_->off();
    }

    void undo() override {
        light_->on();
    }
};

// ------------------ Invoker ------------------
// Responsible for executing commands and maintaining history for undo support
class RemoteControl {
private:
    // Using shared_ptr to share command objects, avoid ownership transfer
    std::vector<std::shared_ptr<Command>> history_;
public:
    // Execute a command and store in history
    void executeCommand(std::shared_ptr<Command> cmd) {
        cmd->execute();
        history_.push_back(cmd);
    }

    // Undo the most recently executed command
    void undoLastCommand() {
        if (history_.empty()) {
            std::cout << "⚠️ No command to undo." << std::endl;
            return;
        }
        auto lastCmd = history_.back();
        history_.pop_back();
        lastCmd->undo();
    }
};

// ------------------ Client ------------------
int main() {
    // Create receiver
    Light livingRoomLight;

    // Create concrete commands and bind to receiver
    auto lightOn  = std::make_shared<LightOnCommand>(&livingRoomLight);
    auto lightOff = std::make_shared<LightOffCommand>(&livingRoomLight);

    // Create invoker
    RemoteControl remote;

    std::cout << "=== Remote Control Operation Demo ===" << std::endl;

    // Turn on light
    remote.executeCommand(lightOn);     // Output: Light turned on

    // Turn off light
    remote.executeCommand(lightOff);    // Output: Light turned off

    // Undo turn off -> Light turns back on
    remote.undoLastCommand();           // Output: Light turned on

    // Undo again -> Light turns back off
    remote.undoLastCommand();           // Output: Light turned off

    // Try undo once more (no command)
    remote.undoLastCommand();           // Output: No command to undo.

    return 0;
}

results matching ""

    No results matching ""