Files
StandardSence/StandardScene.Fass2Simulator/Fass2SimActionResolver.cs
T

143 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
namespace StandardScene.Fass2Simulator
{
/// <summary>
/// 对齐 <c>Fass2ActionResolver</c> 的到站动作判定(独立副本,避免引用 Magnetic)。
/// </summary>
public static class Fass2SimActionResolver
{
public const byte StartStopPass = 1;
public const byte StartStopStop = 2;
public const byte StartStopPrecision = 22;
private static readonly (string Name, Func<Fass2SimNodeMessage, byte> Get)[] ActionFields =
{
("Direction", n => n.Direction),
("Orientation", n => n.Orientation),
("Byroad", n => n.Byroad),
("Obstacle", n => n.Obstacle),
("Audio", n => n.Audio),
("Light", n => n.Light),
("Charge", n => n.Charge),
("Rest", n => n.Rest),
("Lift", n => n.Lift),
("Clamp", n => n.Clamp),
("Tray", n => n.Tray),
("Roll", n => n.Roll),
("Shutdown", n => n.Shutdown)
};
public static bool RequiresActionWait(Fass2SimNodeMessage expected)
{
if (expected == null)
{
return false;
}
if (expected.StartStop is StartStopStop or StartStopPrecision)
{
return true;
}
foreach (var field in ActionFields)
{
if (field.Get(expected) != 0)
{
return true;
}
}
return expected.Speed != 0;
}
public static bool IsStationActionComplete(Fass2SimNodeMessage expected, Fass2SimVehicleSnapshot actual, byte vehicleState)
{
if (expected == null || actual == null)
{
return false;
}
if (actual.Node != expected.Node)
{
return false;
}
if (vehicleState == 1)
{
return false;
}
if (!RequiresActionWait(expected))
{
return true;
}
if (expected.StartStop == StartStopPass)
{
return true;
}
return ListPendingFields(expected, actual).Count == 0;
}
public static List<string> ListPendingFields(Fass2SimNodeMessage expected, Fass2SimVehicleSnapshot actual)
{
var pending = new List<string>();
if (expected == null || actual == null)
{
return pending;
}
if (expected.StartStop != 0 && actual.StartStop != expected.StartStop)
{
pending.Add("StartStop");
}
if (expected.Speed != 0 && actual.Speed != expected.Speed)
{
pending.Add("Speed");
}
foreach (var field in ActionFields)
{
var expectedValue = field.Get(expected);
if (expectedValue != 0 && GetActualField(actual, field.Name) != expectedValue)
{
pending.Add(field.Name);
}
}
return pending;
}
public static string DescribePending(Fass2SimNodeMessage expected, Fass2SimVehicleSnapshot actual)
{
var pending = ListPendingFields(expected, actual);
return pending.Count == 0 ? string.Empty : string.Join(",", pending);
}
private static byte GetActualField(Fass2SimVehicleSnapshot actual, string name)
{
switch (name)
{
case "Direction": return actual.Direction;
case "Orientation": return actual.Orientation;
case "Byroad": return actual.Byroad;
case "Obstacle": return actual.Obstacle;
case "Audio": return actual.Audio;
case "Light": return actual.Light;
case "Charge": return actual.Charge;
case "Rest": return actual.Rest;
case "Lift": return actual.Lift;
case "Clamp": return actual.Clamp;
case "Tray": return actual.Tray;
case "Roll": return actual.Roll;
case "Shutdown": return actual.Shutdown;
default: return 0;
}
}
}
}