using System.Collections.Generic; using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using HC_APTBS.Models; namespace HC_APTBS.ViewModels { /// /// Dashboard-side alarm aggregator. /// /// Keeps an collection in sync with the /// bench Alarms CAN bitmask, resolving each set bit against the /// alarm definitions loaded from alarms.xml. The consumer (MainViewModel's /// refresh tick) calls every refresh interval. /// public sealed partial class DashboardAlarmsViewModel : ObservableObject { private readonly IReadOnlyList _definitions; private int _lastMask = -1; /// List of currently asserted alarms. public ObservableCollection ActiveAlarms { get; } = new(); /// True when no alarms are active — used to show the "System OK" banner. [ObservableProperty] private bool _isClear = true; /// True when at least one active alarm is flagged critical. [ObservableProperty] private bool _hasCritical; public DashboardAlarmsViewModel(IReadOnlyList definitions) { _definitions = definitions; } /// /// Rebuilds from the current bench alarm bitmask. /// Cheap no-op when the mask has not changed since the last call. /// Must be invoked on the UI thread. /// public void Update(int mask) { if (mask == _lastMask) return; _lastMask = mask; ActiveAlarms.Clear(); bool anyCritical = false; foreach (var def in _definitions) { bool bitSet = (mask & (1 << def.Bit)) != 0; def.IsActive = bitSet; if (!bitSet) continue; ActiveAlarms.Add(def); if (def.IsCritical) anyCritical = true; } IsClear = ActiveAlarms.Count == 0; HasCritical = anyCritical; } } }