using System; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reactive; using System.Threading; using LoraGamepad.Models; using LoraGamepad.Util; using ReactiveUI; namespace LoraGamepad.ViewModels; public class TProViewModel : ViewModelBase { private bool _isOpenPortButtonVisible = true; private bool _isClosePortButtonVisible; private ObservableCollection _portList = new(); public CBPortItem PortSelectItem { get; set; } public SliderConfig SliderValue { get; } public BtnConfig BtnIsPressed { get; } private readonly SerialPipeIn _serialPipeIn; private readonly CrsfParserPipeIn _crsfParserPipeIn; public ReactiveCommand OpenPort { get; } public ReactiveCommand ClosePort { get; } public Thread ReadThread; public TProViewModel() { SliderValue = new SliderConfig(); BtnIsPressed = new BtnConfig(); PortList = CBPortItem.GetPortList(); _serialPipeIn = new SerialPipeIn(); _crsfParserPipeIn = new CrsfParserPipeIn(); _serialPipeIn.OnOut += _crsfParserPipeIn.Push; _crsfParserPipeIn.OnOut += data => { SliderValue.RightHorizonValue = data.channel[0]; SliderValue.RightVerticalValue = data.channel[1]; SliderValue.LeftHorizonValue = data.channel[2]; SliderValue.LeftVerticalValue = data.channel[3]; // Console.WriteLine($"{data.channel[4]},{data.channel[5]},{data.channel[6]},{data.channel[7]},{data.channel[8]},{data.channel[9]}"); // Console.WriteLine($"{data.channel[10]},{data.channel[11]},{data.channel[12]},{data.channel[13]},{data.channel[14]},{data.channel[15]}"); SliderValue.LeftUpValue = data.channel[4]; BtnIsPressed.BtnLeftUp = data.channel[5] > 0; BtnIsPressed.BtnRightUp = data.channel[6] > 0; BtnIsPressed.BtnRightDown = data.channel[7] > 0; SliderValue.MidLeftValue = data.channel[8]; SliderValue.MidRightValue = data.channel[9]; BtnIsPressed.BtnModel1 = data.channel[10] > 0; BtnIsPressed.BtnModel2 = data.channel[11] > 0; BtnIsPressed.BtnModel3 = data.channel[12] > 0; BtnIsPressed.BtnModel4 = data.channel[13] > 0; BtnIsPressed.BtnModel5 = data.channel[14] > 0; BtnIsPressed.BtnModel6 = data.channel[15] > 0; }; ReadThread = new Thread(ReadThreadEntry); OpenPort = ReactiveCommand.Create(PortOpenButtonClick); ClosePort = ReactiveCommand.Create(PortCloseButtonClick); } public void ReadThreadEntry() { while (true) { if (SerialPort.Me.TryRead(out var data)) { // Console.WriteLine(BitConverter.ToString(data)); _serialPipeIn.Push(data); } SpinWait.SpinUntil(() => false, 1); } } /// /// ComboBox串口列表绑定对象 /// public ObservableCollection PortList { get => _portList; set => this.RaiseAndSetIfChanged(ref _portList, value); } /// /// 刷新串口列表事件处理函数 /// public void OnPortListComboBoxPressed() { var newList = CBPortItem.GetPortList(); PortList.Except(newList,new CBPortItemCompare()).ToList().ForEach(a => { PortList.Remove(a); }); newList.Except(PortList, new CBPortItemCompare()).ToList().ForEach(a => { PortList.Add(a); }); newList.Except(PortList, new CBPortItemCompare()).ToList().ForEach(a => { PortList.Add(a); }); } /// /// 关闭串口按键可见性属性 /// public bool IsClosePortButtonVisible { get => _isClosePortButtonVisible; set => this.RaiseAndSetIfChanged(ref _isClosePortButtonVisible, value); } /// /// 打开串口按键可见性属性 /// public bool IsOpenPortButtonVisible { get => _isOpenPortButtonVisible; set => this.RaiseAndSetIfChanged(ref _isOpenPortButtonVisible, value); } /// /// 打开串口按键响应 /// private void PortOpenButtonClick() { if (PortSelectItem.PortName == "") return; SerialPort.Me.Open(PortSelectItem.PortName,250000,1000); IsOpenPortButtonVisible = false; IsClosePortButtonVisible = true; ReadThread.Start(); } /// /// 关闭串口按键响应 /// private void PortCloseButtonClick() { SerialPort.Me.Close(); IsOpenPortButtonVisible = true; IsClosePortButtonVisible = false; } }