#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;
}