Files
BWRSimlator/BWR.core/Data/ConfigurationLoader.cs

167 lines
7.3 KiB
C#

// MyBWRSimulator.Core/Data/ConfigurationLoader.cs
namespace MyBWRSimulator.Core.Data
{
using MyBWRSimulator.Core.Components.Abstract;
using MyBWRSimulator.Core.Components.Concrete;
using MyBWRSimulator.Core.Ports;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
/// <summary>
/// Helper class for deserializing component and connection configurations.
/// </summary>
public class ComponentConfig
{
public string Type { get; set; }
public string ID { get; set; }
public string Name { get; set; }
public int UpdatePriority { get; set; }
public JsonElement InitialState { get; set; } // Use JsonElement to handle dynamic properties
}
/// <summary>
/// Helper class for deserializing connection configurations.
/// </summary>
public class PortReference
{
public string ComponentID { get; set; }
public string PortID { get; set; }
}
/// <summary>
/// Overall configuration structure.
/// </summary>
public class PlantConfiguration
{
public List<ComponentConfig> Components { get; set; }
public List<ConnectionConfig> Connections { get; set; }
}
/// <summary>
/// Helper class for deserializing connection configurations.
/// </summary>
public class ConnectionConfig
{
public PortReference PortA { get; set; }
public PortReference PortB { get; set; }
}
/// <summary>
/// Handles loading simulation configuration from a JSON file.
/// </summary>
public class ConfigurationLoader
{
/// <summary>
/// Loads components and establishes connections from a JSON configuration file.
/// </summary>
/// <param name="filePath">The path to the JSON configuration file.</param>
/// <param name="components">An output list to populate with instantiated components.</param>
public static void LoadConfiguration(string filePath, out List<Component> components)
{
components = new List<Component>();
if (!File.Exists(filePath))
{
Console.WriteLine($"Error: Configuration file not found at {filePath}");
return;
}
try
{
string jsonString = File.ReadAllText(filePath);
var config = JsonSerializer.Deserialize<PlantConfiguration>(jsonString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
if (config?.Components == null)
{
Console.WriteLine("Error: No components found in configuration.");
return;
}
// 1. Instantiate Components
foreach (var compConfig in config.Components)
{
Component newComponent = null;
switch (compConfig.Type)
{
case "Pump":
// Example: Deserialize specific properties for Pump
var pumpProps = compConfig.InitialState.Deserialize<Dictionary<string, double>>();
newComponent = new Pump(compConfig.ID, compConfig.Name, pumpProps["MaxFlowRate"], pumpProps["MaxHeadPressure"]);
if (pumpProps.TryGetValue("PumpSpeed", out double pumpSpeed))
{
((Pump)newComponent).SetPumpSpeed(pumpSpeed);
}
break;
case "FluidTank":
// Example: Deserialize specific properties for FluidTank
var tankProps = compConfig.InitialState.Deserialize<Dictionary<string, double>>();
newComponent = new FluidTank(compConfig.ID, compConfig.Name, tankProps["MaxVolume"], (int)tankProps["NumInlets"], (int)tankProps["NumOutlets"], tankProps["InitialVolume"]);
break;
case "Pipe":
var pipeProps = compConfig.InitialState.Deserialize<Dictionary<string, double>>();
newComponent = new Pipe(compConfig.ID, compConfig.Name, pipeProps["Length"], pipeProps["Diameter"]);
break;
case "ReactorCore":
newComponent = new ReactorCore(compConfig.ID, compConfig.Name, compConfig.UpdatePriority);
// ReactorCore might have no specific initial state beyond base properties
break;
// Add more component types here
default:
Console.WriteLine($"Warning: Unknown component type '{compConfig.Type}' for ID '{compConfig.ID}'. Skipping.");
break;
}
if (newComponent != null)
{
components.Add(newComponent);
newComponent.Initialize(); // Initialize after creation
}
}
// 2. Establish Connections
if (config.Connections != null)
{
foreach (var connConfig in config.Connections)
{
var compA = components.FirstOrDefault(c => c.ID == connConfig.PortA.ComponentID);
var compB = components.FirstOrDefault(c => c.ID == connConfig.PortB.ComponentID);
if (compA == null || compB == null)
{
Console.WriteLine($"Warning: Could not find one or both components for connection: {connConfig.PortA.ComponentID}.{connConfig.PortA.PortID} <-> {connConfig.PortB.ComponentID}.{connConfig.PortB.PortID}");
continue;
}
// Use the new GetPortById methods for more robust lookup
Port portA = compA.GetFluidPortById(connConfig.PortA.PortID) as Port ??
compA.GetThermalPortById(connConfig.PortA.PortID) as Port;
Port portB = compB.GetFluidPortById(connConfig.PortB.PortID) as Port ??
compB.GetThermalPortById(connConfig.PortB.PortID) as Port;
if (portA != null && portB != null)
{
portA.Connect(portB);
}
else
{
Console.WriteLine($"Warning: Could not find one or both ports for connection: {connConfig.PortA.ComponentID}.{connConfig.PortA.PortID} <-> {connConfig.PortB.ComponentID}.{connConfig.PortB.PortID}");
}
}
}
}
catch (JsonException ex)
{
Console.WriteLine($"Error parsing JSON configuration: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An unexpected error occurred during configuration loading: {ex.Message}");
}
}
}
}