using System; using System.Collections.Generic; namespace CncSimulator.Device { /// /// 剧本播放器。按预设顺序循环场景,每台设备独立运行。 /// public class ScenarioPlayer { private readonly DeviceSimulator _simulator; private readonly Random _rng; private int _stepIndex; private bool _autoMode; /// 剧本步骤定义:{ 场景名, 最小tick, 最大tick } private static readonly string[,] ScriptSteps = new string[,] { { "machining", "20", "40" }, { "same_part", "5", "10" }, { "machining", "10", "20" }, { "program_change", "1", "1" }, { "machining", "15", "30" }, { "pause", "5", "10" }, { "machining", "10", "15" }, { "same_part", "3", "5" }, { "manual_reset", "1", "1" }, { "machining", "20", "30" }, { "idle", "10", "20" }, { "machining", "15", "25" }, { "power_off", "5", "15" }, { "power_on", "1", "1" } }; public ScenarioPlayer(DeviceSimulator simulator, bool autoMode, int seed) { _simulator = simulator; _rng = new Random(seed); _autoMode = autoMode; // 随机偏移起始步骤,避免所有设备同步 _stepIndex = _rng.Next(ScriptSteps.GetLength(0)); // 初始化第一步 StartCurrentStep(); } /// 切换模式 public void SetMode(string mode) { _autoMode = (mode == "auto"); } /// 每个数据变化间隔调用一次 public void Tick() { if (!_autoMode) return; var state = _simulator.State; // 断电状态下不推进剧本 if (!state.IsOnline) return; state.ScenarioTick++; // 检查是否达到当前场景的持续时间 if (state.ScenarioTick >= state.ScenarioDuration) { AdvanceToNextStep(); } } /// 手动触发特定事件 public void TriggerEvent(string eventType) { _simulator.TriggerEvent(eventType); } /// 推进到下一个剧本步骤 private void AdvanceToNextStep() { _stepIndex = (_stepIndex + 1) % ScriptSteps.GetLength(0); StartCurrentStep(); } /// 启动当前步骤 private void StartCurrentStep() { string scenario = ScriptSteps[_stepIndex, 0]; int minTicks = int.Parse(ScriptSteps[_stepIndex, 1]); int maxTicks = int.Parse(ScriptSteps[_stepIndex, 2]); int duration = (minTicks == maxTicks) ? minTicks : _rng.Next(minTicks, maxTicks + 1); _simulator.SetScenario(scenario, duration); } } }