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