You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
haoliang-net/src/CncSimulator/Device/ScenarioPlayer.cs

98 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
namespace CncSimulator.Device
{
/// <summary>
/// 剧本播放器。按预设顺序循环场景,每台设备独立运行。
/// </summary>
public class ScenarioPlayer
{
private readonly DeviceSimulator _simulator;
private readonly Random _rng;
private int _stepIndex;
private bool _autoMode;
/// <summary>剧本步骤定义:{ 场景名, 最小tick, 最大tick }</summary>
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();
}
/// <summary>切换模式</summary>
public void SetMode(string mode)
{
_autoMode = (mode == "auto");
}
/// <summary>每个数据变化间隔调用一次</summary>
public void Tick()
{
if (!_autoMode) return;
var state = _simulator.State;
// 断电状态下不推进剧本
if (!state.IsOnline) return;
state.ScenarioTick++;
// 检查是否达到当前场景的持续时间
if (state.ScenarioTick >= state.ScenarioDuration)
{
AdvanceToNextStep();
}
}
/// <summary>手动触发特定事件</summary>
public void TriggerEvent(string eventType)
{
_simulator.TriggerEvent(eventType);
}
/// <summary>推进到下一个剧本步骤</summary>
private void AdvanceToNextStep()
{
_stepIndex = (_stepIndex + 1) % ScriptSteps.GetLength(0);
StartCurrentStep();
}
/// <summary>启动当前步骤</summary>
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);
}
}
}