// MyBWRSimulator.Core/Simulation/Simulator.cs
namespace MyBWRSimulator.Core.Simulation
{
using MyBWRSimulator.Core.Components.Abstract;
using MyBWRSimulator.Core.Data;
using System;
using System.Collections.Generic;
using System.Linq;
///
/// The orchestrator of the simulation. Manages components, runs the simulation loop, and provides data.
///
public class Simulator
{
private List _components;
private double _simulationTime;
private bool _isPaused;
public Simulator()
{
_components = new List();
_simulationTime = 0.0;
_isPaused = false;
}
///
/// Adds a component to the simulation.
///
/// The component to add.
public void AddComponent(Component component)
{
if (component != null && !_components.Contains(component))
{
_components.Add(component);
_components = _components.OrderBy(c => c.UpdatePriority).ToList(); // Re-sort after adding
component.Initialize();
Console.WriteLine($"Component '{component.Name}' ({component.ID}) added.");
}
}
///
/// Removes a component from the simulation.
///
/// The component to remove.
public void RemoveComponent(Component component)
{
if (component != null && _components.Remove(component))
{
_components = _components.OrderBy(c => c.UpdatePriority).ToList(); // Re-sort after removing
component.Shutdown();
Console.WriteLine($"Component '{component.Name}' ({component.ID}) removed.");
}
}
///
/// Loads components and connections from a configuration file.
///
/// The path to the configuration JSON file.
public void LoadPlantConfiguration(string filePath)
{
ConfigurationLoader.LoadConfiguration(filePath, out _components);
_components = _components.OrderBy(c => c.UpdatePriority).ToList(); // Ensure sorted after load
Console.WriteLine($"Loaded { _components.Count} components from configuration.");
}
///
/// Runs the simulation for a specified duration with a given time step.
///
/// Total simulation duration (e.g., in seconds).
/// Time step for each update iteration (e.g., in seconds).
public void RunSimulation(double duration, double timeStep)
{
Console.WriteLine($"Starting simulation for {duration} seconds with a time step of {timeStep} seconds...");
_isPaused = false;
while (_simulationTime < duration && !_isPaused)
{
Console.WriteLine($"\n--- Simulation Time: {_simulationTime:F2} s ---");
foreach (var component in _components)
{
component.Update(timeStep);
}
_simulationTime += timeStep;
// For console output, add a small delay to see updates
System.Threading.Thread.Sleep(100);
}
if (_simulationTime >= duration)
{
Console.WriteLine("\nSimulation finished.");
}
else if (_isPaused)
{
Console.WriteLine("\nSimulation paused.");
}
// Call shutdown for all components at the end of the simulation
foreach (var component in _components)
{
component.Shutdown();
}
}
///
/// Pauses the simulation.
///
public void PauseSimulation()
{
_isPaused = true;
}
///
/// Resumes the simulation.
///
public void ResumeSimulation()
{
_isPaused = false;
}
///
/// Gets current simulation data from all components.
/// (Placeholder - you'll define the structure of this data more concretely later)
///
/// A dictionary containing simulation data.
public Dictionary GetSimulationData()
{
var data = new Dictionary();
data["SimulationTime"] = _simulationTime;
data["ComponentStates"] = _components.Select(c => new
{
c.ID,
c.Name
// Add specific properties for each component type here
// Example for Pump: (c as Pump)?.PumpSpeed
// Example for FluidTank: (c as FluidTank)?.CurrentVolume
}).ToList();
return data;
}
}
}