using System; using System.Collections.Generic; using System.IO; using Microsoft.Extensions.Configuration; using Newtonsoft.Json; namespace StandardScene.Fass2Simulator { public static class Fass2SimBootstrap { public static string SettingsFile { get; private set; } = "appsettings.json"; public static void ApplyCommandLine(string[] args) { if (args == null) { return; } for (var i = 0; i < args.Length - 1; i++) { if (string.Equals(args[i], "--config", StringComparison.OrdinalIgnoreCase)) { SettingsFile = args[i + 1]; } } } public static Fass2SimConfig LoadConfig(string settingsFile = null) { var basePath = AppContext.BaseDirectory; var builder = new ConfigurationBuilder() .SetBasePath(basePath) .AddJsonFile(settingsFile ?? SettingsFile, optional: true, reloadOnChange: false); var configuration = builder.Build(); var config = new Fass2SimConfig(); configuration.GetSection("Fass2Simulator").Bind(config); return config; } public static Fass2SimNodeProfileStore LoadNodeProfiles(Fass2SimConfig config) { var store = new Fass2SimNodeProfileStore(); var path = ResolveNodeProfilesPath(config.NodeProfilesPath); if (!File.Exists(path)) { return store; } try { var json = File.ReadAllText(path); var profiles = JsonConvert.DeserializeObject>(json) ?? new Dictionary(); store.Load(profiles); Fass2SimLog.WriteLine($"[{DateTime.Now:HH:mm:ss}] 已加载节点配置: {path} ({profiles.Count} 项)"); } catch (Exception ex) { Fass2SimLog.WriteLine($"[{DateTime.Now:HH:mm:ss}] 加载节点配置失败: {ex.Message}"); } return store; } public static Fass2SimRuntime CreateRuntime(Fass2SimConfig config) { var profiles = LoadNodeProfiles(config); return new Fass2SimRuntime(config, profiles); } public static (Fass2SimVehicle vehicle, Fass2SimMotionEngine motion, Fass2SimActionEngine actions) CreateTestStack( Fass2SimConfig config) { var vehicle = new Fass2SimVehicle(config); var actions = new Fass2SimActionEngine(vehicle, config, new Fass2SimNodeProfileStore()); var motion = new Fass2SimMotionEngine(vehicle, config, actions); actions.StationActionsCompleted += motion.OnStationActionsCompleted; return (vehicle, motion, actions); } private static string ResolveNodeProfilesPath(string configuredPath) { if (string.IsNullOrWhiteSpace(configuredPath)) { return Path.Combine(AppContext.BaseDirectory, "sim-nodes.json"); } return Path.IsPathRooted(configuredPath) ? configuredPath : Path.Combine(AppContext.BaseDirectory, configuredPath); } } }