143 lines
4.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|