using System; namespace StandardScene.Fass2Simulator { public sealed class Fass2SimVehicle { private readonly object _syncRoot = new object(); public Fass2SimVehicle(Fass2SimConfig config) { Car = config.VehicleCode; Length = config.CarLength; Width = config.CarWidth; BatteryCharge = config.BatteryCharge; BatteryHealth = 100; BatteryVoltage = 480; State = config.InitialState; Node = config.InitialNode; Speed = 500; } public ushort Car { get; } public ushort Length { get; set; } public ushort Width { get; set; } public byte BatteryCharge { get; set; } public byte BatteryHealth { get; set; } public ushort BatteryCurrent { get; set; } public ushort BatteryVoltage { get; set; } public ushort HeadingAngle { get; set; } public byte State { get; set; } public ulong Alarm { get; set; } public ulong Task { get; set; } public byte LastCommand { get; set; } public ushort Node { get; set; } public ushort Distance { get; set; } public byte StartStop { get; set; } public byte Direction { get; set; } public byte Orientation { get; set; } public byte Byroad { get; set; } public ushort Speed { get; set; } public byte Obstacle { get; set; } public byte Audio { get; set; } public byte Light { get; set; } public byte Charge { get; set; } public byte Rest { get; set; } public byte Lift { get; set; } public byte Clamp { get; set; } public byte Tray { get; set; } public byte Roll { get; set; } public byte Shutdown { get; set; } public long StateReportsSent { get; private set; } public long CommandsReceived { get; private set; } public long AckReceived { get; private set; } public DateTime LastAckUtc { get; private set; } = DateTime.MinValue; public void RecordStateReportSent() { lock (_syncRoot) { StateReportsSent++; } } public void RecordCommandReceived() { lock (_syncRoot) { CommandsReceived++; } } public void RecordAckReceived() { lock (_syncRoot) { AckReceived++; LastAckUtc = DateTime.UtcNow; } } public Fass2SimVehicleSnapshot Snapshot() { lock (_syncRoot) { return CopySnapshotUnsafe(); } } /// /// 供已持有其它引擎锁的代码路径读取快照,避免与 UI 线程 Snapshot() 争用 _syncRoot 导致死锁。 /// internal Fass2SimVehicleSnapshot CopySnapshotUnsafe() { return new Fass2SimVehicleSnapshot { Car = Car, Length = Length, Width = Width, BatteryCharge = BatteryCharge, BatteryHealth = BatteryHealth, BatteryCurrent = BatteryCurrent, BatteryVoltage = BatteryVoltage, HeadingAngle = HeadingAngle, State = State, Alarm = Alarm, Task = Task, LastCommand = LastCommand, Node = Node, Distance = Distance, StartStop = StartStop, Direction = Direction, Orientation = Orientation, Byroad = Byroad, Speed = Speed, Obstacle = Obstacle, Audio = Audio, Light = Light, Charge = Charge, Rest = Rest, Lift = Lift, Clamp = Clamp, Tray = Tray, Roll = Roll, Shutdown = Shutdown, StateReportsSent = StateReportsSent, CommandsReceived = CommandsReceived, AckReceived = AckReceived, LastAckUtc = LastAckUtc }; } } public sealed class Fass2SimVehicleSnapshot { public ushort Car { get; set; } public ushort Length { get; set; } public ushort Width { get; set; } public byte BatteryCharge { get; set; } public byte BatteryHealth { get; set; } public ushort BatteryCurrent { get; set; } public ushort BatteryVoltage { get; set; } public ushort HeadingAngle { get; set; } public byte State { get; set; } public ulong Alarm { get; set; } public ulong Task { get; set; } public byte LastCommand { get; set; } public ushort Node { get; set; } public ushort Distance { get; set; } public byte StartStop { get; set; } public byte Direction { get; set; } public byte Orientation { get; set; } public byte Byroad { get; set; } public ushort Speed { get; set; } public byte Obstacle { get; set; } public byte Audio { get; set; } public byte Light { get; set; } public byte Charge { get; set; } public byte Rest { get; set; } public byte Lift { get; set; } public byte Clamp { get; set; } public byte Tray { get; set; } public byte Roll { get; set; } public byte Shutdown { get; set; } public long StateReportsSent { get; set; } public long CommandsReceived { get; set; } public long AckReceived { get; set; } public DateTime LastAckUtc { get; set; } } }