Plane.FormationCreator/Plane.FormationCreator/ViewModels/ConnectViewModel.cs

177 lines
6.6 KiB
C#
Raw Normal View History

2017-02-27 02:06:48 +08:00
using Plane;
using Plane.Collections;
using Plane.FormationCreator.Formation;
using Plane.Logging;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Plane.Communication;
using Plane.Copters;
using Plane.Windows.Messages;
using Plane.FormationCreator.Properties;
using System.IO;
namespace Plane.FormationCreator.ViewModels
{
public class ConnectViewModel : ViewModelBase
{
public ConnectViewModel(CopterManager copterManager)
{
_copterManager = copterManager;
}
private CopterManager _copterManager;
private const int PORT = 5250;
// 不严谨,稍微验证一下。
private Regex _ipListRegex = new Regex(@"^(?:" + Environment.NewLine + @")*\d{1,3}(?:\.\d{1,3}){3}(?:" + Environment.NewLine + @"\d{1,3}(?:\.\d{1,3}){3})*(?:" + Environment.NewLine + @")*$", RegexOptions.Singleline | RegexOptions.Compiled);
// private string _IPs = @"192.168.1.11
//192.168.1.12
//192.168.1.13
//192.168.1.14
//192.168.1.15
//192.168.1.16
//192.168.1.17
//192.168.1.18
//192.168.1.19
//192.168.1.20
//";
private string _IPs = Settings.Default.IPs;
public string IPs
{
get { return _IPs; }
set { Set(nameof(IPs), ref _IPs, value); }
}
private bool _IsProcessing;
public bool IsProcessing
{
get { return _IsProcessing; }
set { Set(nameof(IsProcessing), ref _IsProcessing, value); }
}
private ICommand _ConnectCommand;
public ICommand ConnectCommand
{
get
{
return _ConnectCommand ?? (_ConnectCommand = new RelayCommand<string>(async connectionType =>
{
if (!_ipListRegex.IsMatch(IPs))
{
Alert.Show($"您输入的 IP 格式不对!形如{Environment.NewLine}192.168.1.10{Environment.NewLine}192.168.1.11");
return;
}
IsProcessing = true;
var connectionStatusDict =
IPs.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
.Where(ip => _copterManager.Copters.All(c => c.Id != ip))
.OrderBy(ip => ip)
.Distinct()
.ToDictionary(ip => ip, ip => (bool?)null);
var timeIsOut = false;
var uiThreadContext = SynchronizationContext.Current;
new Action(async () =>
{
foreach (var ip in connectionStatusDict.Keys.ToList())
{
var Connection =
connectionType == "SerialPort"
? new SerialPortConnection("COM10") as IConnection
: connectionType == "UDP"
? new UdpConnection(ip, PORT) as IConnection
: new TcpConnection(ip, PORT);
var c = new Copter(Connection, uiThreadContext)
//var c = new Copter(new SerialPortConnection("COM3"), uiThreadContext)
{
Id = ip,
Name = ip.Substring(ip.LastIndexOf('.') + 1)
};
try
{
await c.ConnectAsync().ConfigureAwait(false);
if (!timeIsOut)
{
connectionStatusDict[ip] = true;
App.Current.Dispatcher.Invoke(() =>
{
_copterManager.Copters.Add(c);
});
//await c.GetCopterDataAsync();
}
}
catch (SocketException)
{
connectionStatusDict[ip] = false;
}
catch (IOException)
{ // A device attached to the system is not functioning.
connectionStatusDict[ip] = false;
}
}
}).Invoke();
for (int waitedTime = 0, timeStep = 500; waitedTime < 2000; waitedTime += timeStep)
{
await Task.Delay(timeStep).ConfigureAwait(false);
if (connectionStatusDict.All(item => item.Value == true))
{
break;
}
}
timeIsOut = true;
IsProcessing = false;
var ipsCanNotConnect = string.Join(Environment.NewLine, connectionStatusDict.Where(item => !(item.Value ?? false)).Select(item => item.Key));
if (!string.IsNullOrEmpty(ipsCanNotConnect))
{
var message = $"无法连接以下 IP{Environment.NewLine}{ipsCanNotConnect}";
App.Current.Dispatcher.Invoke(() =>
{
Alert.Show(message);
});
}
else
{
CloseWindow();
}
}));
}
}
private Action _closeWindowCallback;
public void SetCloseWindowAction(Action closeWindowAction)
{
_closeWindowCallback = closeWindowAction;
}
private void CloseWindow()
{
if (_closeWindowCallback == null) return;
var dispatcher = App.Current.Dispatcher;
if (dispatcher.CheckAccess())
{
_closeWindowCallback();
}
else
{
dispatcher.InvokeAsync(() =>
{
_closeWindowCallback.Invoke();
});
}
}
}
}