using System; using System.Collections.Generic; using System.Linq; using System.Windows.Input; using System.Windows.Threading; using leak_test_project.Models; using leak_test_project.Services; using leak_test_project.ViewModels.Core; namespace leak_test_project.ViewModels { /// /// In/Out Monitor 화면의 데이터 페이징 및 실시간 갱신 로직을 담당하는 ViewModel. /// public class InOutViewModel : ObservableObject, IDisposable { private readonly IoBoardService _ioService; private readonly List _allInputs; private readonly List _allOutputs; private const int PageSize = 30; private int _inputCurrentPage = 0; private int _outputCurrentPage = 0; private readonly DispatcherTimer _refreshTimer; private List _currentInputs = new List(); public List CurrentInputs { get => _currentInputs; set => SetProperty(ref _currentInputs, value); } private List _currentOutputs = new List(); public List CurrentOutputs { get => _currentOutputs; set => SetProperty(ref _currentOutputs, value); } // Input 페이징 커맨드 public ICommand InputFirstCommand { get; } public ICommand InputPrevCommand { get; } public ICommand InputNextCommand { get; } public ICommand InputLastCommand { get; } // Output 페이징 커맨드 public ICommand OutputFirstCommand { get; } public ICommand OutputPrevCommand { get; } public ICommand OutputNextCommand { get; } public ICommand OutputLastCommand { get; } /// Close 버튼 시 홈으로 돌아가는 커맨드 public ICommand CloseCommand { get; } public InOutViewModel(Action navigateHome, IoBoardService ioService) { _ioService = ioService; _allInputs = ioService.Inputs; _allOutputs = ioService.Outputs; InputFirstCommand = new RelayCommand(o => { _inputCurrentPage = 0; UpdateInputs(); }); InputPrevCommand = new RelayCommand(o => { if (_inputCurrentPage > 0) { _inputCurrentPage--; UpdateInputs(); } }); InputNextCommand = new RelayCommand(o => { if ((_inputCurrentPage + 1) * PageSize < _allInputs.Count) { _inputCurrentPage++; UpdateInputs(); } }); InputLastCommand = new RelayCommand(o => { _inputCurrentPage = Math.Max(0, (_allInputs.Count - 1) / PageSize); UpdateInputs(); }); OutputFirstCommand = new RelayCommand(o => { _outputCurrentPage = 0; UpdateOutputs(); }); OutputPrevCommand = new RelayCommand(o => { if (_outputCurrentPage > 0) { _outputCurrentPage--; UpdateOutputs(); } }); OutputNextCommand = new RelayCommand(o => { if ((_outputCurrentPage + 1) * PageSize < _allOutputs.Count) { _outputCurrentPage++; UpdateOutputs(); } }); OutputLastCommand = new RelayCommand(o => { _outputCurrentPage = Math.Max(0, (_allOutputs.Count - 1) / PageSize); UpdateOutputs(); }); CloseCommand = new RelayCommand(o => { Dispose(); navigateHome?.Invoke(); }); UpdateInputs(); UpdateOutputs(); // 500ms 주기로 DIO 상태 자동 갱신 _refreshTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(500) }; _refreshTimer.Tick += (s, e) => { _ioService.RefreshState(); UpdateInputs(); UpdateOutputs(); }; _refreshTimer.Start(); } private void UpdateInputs() { CurrentInputs = _allInputs.Skip(_inputCurrentPage * PageSize).Take(PageSize).ToList(); } private void UpdateOutputs() { CurrentOutputs = _allOutputs.Skip(_outputCurrentPage * PageSize).Take(PageSize).ToList(); } public void Dispose() { _refreshTimer?.Stop(); } } }