example.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <list>
#include <string>
#include <functional>
#include <tuple>
#include <thread>
#include <chrono>

// Result structure representing simulation results
using SimulationResult = std::tuple<double, double, double>; // time step, energy, entropy

// Task structure representing a simulation task
struct Task {
    std::string name;
    int duration;  // Duration in seconds
    std::function<SimulationResult()> simulationFunc;
    
    Task(const std::string& n, int d, std::function<SimulationResult()> func) 
        : name(n), duration(d), simulationFunc(func) {}
};

// Observer class to be notified of simulation progress
class SimulationObserver {
public:
    virtual void update(const std::string& taskName, const SimulationResult& result) = 0;
};

// Concrete observer for visualization
class VisualizationTool : public SimulationObserver {
public:
    void update(const std::string& taskName, const SimulationResult& result) override {
        std::cout << "Visualization update for " << taskName << ": "
                  << "Time step: " << std::get<0>(result)
                  << ", Energy: " << std::get<1>(result)
                  << ", Entropy: " << std::get<2>(result) << std::endl;
    }
};

// Simulation class managing task queue
class Simulation {
public:
    void addTask(const Task& task) {
        tasks.push_back(task);
    }
    
    void addObserver(SimulationObserver* observer) {
        observers.push_back(observer);
    }
    
    // Run all tasks in the order they were added
    void runTasks() {
        for (const auto& task : tasks) {
            std::cout << "Running task: " << task.name << " for " << task.duration << " seconds\n";
            std::this_thread::sleep_for(std::chrono::seconds(task.duration));
            
            SimulationResult result = task.simulationFunc();
            notifyObservers(task.name, result);
        }
    }

private:
    std::list<Task> tasks;  // Use std::list to manage task queue
    std::list<SimulationObserver*> observers;

    void notifyObservers(const std::string& taskName, const SimulationResult& result) {
        for (auto observer : observers) {
            observer->update(taskName, result);
        }
    }
};

// Example simulation functions
SimulationResult simulateModel1() {
    return std::make_tuple(0.1, 100.0, 0.5);
}

SimulationResult simulateModel2() {
    return std::make_tuple(0.2, 200.0, 1.0);
}

int main() {
    Simulation sim;
    VisualizationTool vizTool;

    sim.addObserver(&vizTool);

    // Using std::bind to create tasks with different simulation functions
    sim.addTask(Task("Model 1", 2, std::bind(simulateModel1)));
    sim.addTask(Task("Model 2", 3, std::bind(simulateModel2)));
    
    std::cout << "Starting simulation...\n";
    sim.runTasks();
    std::cout << "Simulation finished.\n";
    return 0;
}
Back to wk07_STL_2