Loading Samples/DeviceLab/CommandSequence.cs 0 → 100644 +134 −0 Original line number Diff line number Diff line using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace DeviceLab { public class CommandSequence : ICommand { private List<ICommand> registeredCommands; private Queue<ICommand> commandQueue; private object sharedParameter; //------------------------------------------------------------------- // Constructor //------------------------------------------------------------------- #region Constructor public CommandSequence(Queue<ICommand> commandQueue = null) { this.registeredCommands = new List<ICommand>(); this.commandQueue = commandQueue == null ? new Queue<ICommand>() : commandQueue; } #endregion // Constructor //------------------------------------------------------------------- // Command Registration //------------------------------------------------------------------- public void RegisterCommand(ICommand cmd) { if (cmd == null) { throw new ArgumentException(nameof(cmd)); } if (cmd == this) { throw new ArgumentException("Cannot register a CommandSequence with itself"); } lock (this.registeredCommands) { CommandSequence seq = cmd as CommandSequence; if (seq == null) { this.registeredCommands.Add(cmd); } else { foreach (ICommand subcmd in seq.registeredCommands) { this.registeredCommands.Add(subcmd); } } } OnCanExecuteChanged(); } //------------------------------------------------------------------- // ICommand Implementation //------------------------------------------------------------------- public event EventHandler CanExecuteChanged; private void OnCanExecuteChanged() { this.CanExecuteChanged?.Invoke(this, new EventArgs()); } public bool CanExecute(object parameter) { if (this.registeredCommands.Count == 0) { return false; } if (this.commandQueue.Count > 0) { return false; } return this.registeredCommands[0].CanExecute(parameter); } public void Execute(object parameter) { lock (this.commandQueue) { if (this.registeredCommands.Count > 0 && this.commandQueue.Count == 0) { foreach (ICommand cmd in this.registeredCommands) { this.commandQueue.Enqueue(cmd); this.sharedParameter = parameter; } } else { return; } } OnCanExecuteChanged(); ExecuteNext(); } private void CurrentCommand_CanExecuteChanged(object sender, EventArgs e) { ICommand cmd = sender as ICommand; cmd.CanExecuteChanged -= CurrentCommand_CanExecuteChanged; ExecuteNext(); } private void ExecuteNext() { lock (this.commandQueue) { while (this.commandQueue.Count > 0 && this.commandQueue.Peek().CanExecute(this.sharedParameter)) { ICommand cmd = this.commandQueue.Dequeue(); cmd.Execute(this.sharedParameter); } if (this.commandQueue.Count > 0) { this.commandQueue.Peek().CanExecuteChanged += CurrentCommand_CanExecuteChanged; } else { OnCanExecuteChanged(); } } } } } Samples/DeviceLab/DeviceLab.csproj +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ <SubType>Designer</SubType> </ApplicationDefinition> <Compile Include="AutoScrollTextBox.cs" /> <Compile Include="CommandSequence.cs" /> <Compile Include="DeviceCollectionView.xaml.cs"> <DependentUpon>DeviceCollectionView.xaml</DependentUpon> </Compile> Loading Samples/DeviceLab/DevicePortalViewModel.cs +2 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ using static Microsoft.Tools.WindowsDevicePortal.DevicePortal; namespace DeviceLab { public class DevicePortalViewModel : BindableBase { //------------------------------------------------------------------- Loading Samples/DeviceLab/DeviceSignInViewModel.cs +1 −58 Original line number Diff line number Diff line Loading @@ -80,7 +80,6 @@ namespace DeviceLab /// <remarks>Diagnostic output will be lost</remarks> public DeviceSignInViewModel() { this.ready = true; this.diagnostics = new NullDiagnosticSink(); } Loading @@ -91,7 +90,6 @@ namespace DeviceLab /// <param name="diags">Diagnostic sink that will receive all the diagnostic output</param> public DeviceSignInViewModel(IDiagnosticSink diags) { this.ready = true; this.diagnostics = diags; } #endregion // Constructors Loading Loading @@ -127,15 +125,6 @@ namespace DeviceLab } #endregion // Password #region Ready private bool ready; public bool Ready { get { return this.ready; } private set { SetProperty(ref this.ready, value); } } #endregion // Ready #region Connection Types private ObservableCollection<IDevicePortalConnectionFactory> connectionTypes; public ObservableCollection<IDevicePortalConnectionFactory> ConnectionTypes Loading Loading @@ -174,13 +163,10 @@ namespace DeviceLab { if (connectCommand == null) { // TODO //connectCommand = DelegateCommand.FromAsyncHandler(ExecuteConnect, CanExecuteConnect); connectCommand = new DelegateCommand(ExecuteConnect, CanExecuteConnect); connectCommand.ObservesProperty(() => this.DeviceIP); connectCommand.ObservesProperty(() => this.UserName); connectCommand.ObservesProperty(() => this.Password); connectCommand.ObservesProperty(() => this.Ready); connectCommand.ObservesProperty(() => this.ConnectionTypeSelection); } return connectCommand; Loading @@ -194,52 +180,9 @@ namespace DeviceLab this.SignInAttempts?.Invoke(this, new DeviceSignInEventArgs(portal, conn)); } // TODO //private async Task OldExecuteConnectAsync() //{ // this.diagnostics.OutputDiagnosticString("[{0}] Attempting to connect.\n", this.deviceIP); // IDevicePortalConnection conn = this.ConnectionTypeSelection.CreateConnection(this.DeviceIP, this.UserName, this.Password); // DevicePortal portal = new DevicePortal(conn); // DeviceConnectionStatusEventHandler handler = (DevicePortal sender, DeviceConnectionStatusEventArgs args) => // { // this.diagnostics.OutputDiagnosticString("[{0}] Connection status update: Status: {1}, Phase: {2}\n", portal.Address, args.Status, args.Phase); // if (args.Status == DeviceConnectionStatus.Connected) // { // this.diagnostics.OutputDiagnosticString("[{0}] Language: {1}\n", portal.Address, conn.OsInfo.Language); // this.diagnostics.OutputDiagnosticString("[{0}] Name: {1}\n", portal.Address, conn.OsInfo.Name); // this.diagnostics.OutputDiagnosticString("[{0}] OsEdition: {1}\n", portal.Address, conn.OsInfo.OsEdition); // this.diagnostics.OutputDiagnosticString("[{0}] OsEditionId: {1}\n", portal.Address, conn.OsInfo.OsEditionId); // this.diagnostics.OutputDiagnosticString("[{0}] OsVersionString: {1}\n", portal.Address, conn.OsInfo.OsVersionString); // this.diagnostics.OutputDiagnosticString("[{0}] Platform: {1}\n", portal.Address, conn.OsInfo.Platform); // this.diagnostics.OutputDiagnosticString("[{0}] PlatformName: {1}\n", portal.Address, conn.OsInfo.PlatformName); // } // else if (args.Status == DeviceConnectionStatus.Failed) // { // this.diagnostics.OutputDiagnosticString("[{0}] Bummer.\n", portal.Address); // } // }; // portal.ConnectionStatus += handler; // try // { // this.Ready = false; // await portal.Connect(); // } // catch (Exception exn) // { // this.diagnostics.OutputDiagnosticString("[{0}] Exception when trying to connect:\n[{0}] {1}\nStackTrace: \n[{0}] {2}\n", portal.Address, exn.Message, exn.StackTrace); // } // this.SignInAttempts?.Invoke(this, new DeviceSignInEventArgs(portal.ConnectionHttpStatusCode, portal)); // portal.ConnectionStatus -= handler; // this.Ready = true; //} private bool CanExecuteConnect() { return Ready && !string.IsNullOrWhiteSpace(this.DeviceIP) && !string.IsNullOrWhiteSpace(this.UserName) && this.Password != null && Loading Samples/DeviceLab/MainViewModel.cs +8 −108 Original line number Diff line number Diff line Loading @@ -11,102 +11,6 @@ using Microsoft.Tools.WindowsDevicePortal; namespace DeviceLab { public class NewDeviceHelper : ICommand { // TODO: Don't close over a DevicePortalViewModel // Instead, should just hook up the CanExecuteChanged events on // the commands private DevicePortalViewModel dpvm; private Queue<ICommand> commandQueue; private bool executionStarted; // TODO: public event EventHandler CanExecuteChanged; public NewDeviceHelper(DevicePortalViewModel dpvm) { this.dpvm = dpvm; this.commandQueue = new Queue<ICommand>(); this.executionStarted = false; } public void Enqueue(ICommand command) { if (this.executionStarted) { throw new InvalidOperationException("Execution already started"); } this.commandQueue.Enqueue(command); } private void Dpvm_PropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == "Ready") { if(this.dpvm.Ready) { DoNextCommand(); } } } private void DoNextCommand() { if(this.commandQueue == null) { throw new InvalidOperationException("Attempting to execute commands without a command queue"); } if(this.commandQueue.Count == 0) { throw new InvalidOperationException("Attempting to execute command on an empty command queue"); } if(this.commandQueue.Peek().CanExecute(null)) { ICommand nextCommand = this.commandQueue.Dequeue(); if (this.commandQueue.Count == 0) { // Executing the next command will probably trigger property changed // events and since this is the last command we want to disconnect from // those events this.dpvm.PropertyChanged -= Dpvm_PropertyChanged; this.executionStarted = false; } nextCommand.Execute(null); } } public bool CanExecute(object parameter) { if(this.executionStarted) { return false; } if(this.commandQueue.Count > 0) { return this.commandQueue.Peek().CanExecute(null); } return false; } public void Execute(object parameter) { if(this.executionStarted) { throw new InvalidOperationException("Execution already started"); } dpvm.PropertyChanged += Dpvm_PropertyChanged; DoNextCommand(); } } public class MainViewModel : BindableBase { //------------------------------------------------------------------- Loading @@ -128,6 +32,8 @@ namespace DeviceLab this.ConnectedDevices.CollectionChanged += OnConnectedDevicesChanged; } #endregion // Constructors private void OnSignInAttemptCompleted(DeviceSignInViewModel sender, DeviceSignInEventArgs args) { Loading @@ -144,7 +50,6 @@ namespace DeviceLab this.ConnectedDevices.Add(new DevicePortalViewModel(args.Portal, Diagnostics)); } #endregion // Constructors //------------------------------------------------------------------- // Properties Loading Loading @@ -404,17 +309,12 @@ namespace DeviceLab private void OnDeviceAdded(DevicePortalViewModel dpvm) { dpvm.PropertyChanged += DevicePropertyChanged; // TODO: //CompositeCommand command = new CompositeCommand(); //command.RegisterCommand(dpvm.RefreshDeviceNameCommand); //command.RegisterCommand(dpvm.StartListeningForSystemPerfCommand); //command.Execute(null); NewDeviceHelper ndh = new NewDeviceHelper(dpvm); ndh.Enqueue(dpvm.ReestablishConnectionCommand); ndh.Enqueue(dpvm.RefreshDeviceNameCommand); ndh.Enqueue(dpvm.StartListeningForSystemPerfCommand); ndh.Execute(null); CommandSequence cmdSeq = new CommandSequence(); cmdSeq.RegisterCommand(dpvm.ReestablishConnectionCommand); cmdSeq.RegisterCommand(dpvm.RefreshDeviceNameCommand); cmdSeq.RegisterCommand(dpvm.StartListeningForSystemPerfCommand); cmdSeq.Execute(null); } private void OnDeviceRemoved(DevicePortalViewModel dpvm) Loading Loading
Samples/DeviceLab/CommandSequence.cs 0 → 100644 +134 −0 Original line number Diff line number Diff line using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace DeviceLab { public class CommandSequence : ICommand { private List<ICommand> registeredCommands; private Queue<ICommand> commandQueue; private object sharedParameter; //------------------------------------------------------------------- // Constructor //------------------------------------------------------------------- #region Constructor public CommandSequence(Queue<ICommand> commandQueue = null) { this.registeredCommands = new List<ICommand>(); this.commandQueue = commandQueue == null ? new Queue<ICommand>() : commandQueue; } #endregion // Constructor //------------------------------------------------------------------- // Command Registration //------------------------------------------------------------------- public void RegisterCommand(ICommand cmd) { if (cmd == null) { throw new ArgumentException(nameof(cmd)); } if (cmd == this) { throw new ArgumentException("Cannot register a CommandSequence with itself"); } lock (this.registeredCommands) { CommandSequence seq = cmd as CommandSequence; if (seq == null) { this.registeredCommands.Add(cmd); } else { foreach (ICommand subcmd in seq.registeredCommands) { this.registeredCommands.Add(subcmd); } } } OnCanExecuteChanged(); } //------------------------------------------------------------------- // ICommand Implementation //------------------------------------------------------------------- public event EventHandler CanExecuteChanged; private void OnCanExecuteChanged() { this.CanExecuteChanged?.Invoke(this, new EventArgs()); } public bool CanExecute(object parameter) { if (this.registeredCommands.Count == 0) { return false; } if (this.commandQueue.Count > 0) { return false; } return this.registeredCommands[0].CanExecute(parameter); } public void Execute(object parameter) { lock (this.commandQueue) { if (this.registeredCommands.Count > 0 && this.commandQueue.Count == 0) { foreach (ICommand cmd in this.registeredCommands) { this.commandQueue.Enqueue(cmd); this.sharedParameter = parameter; } } else { return; } } OnCanExecuteChanged(); ExecuteNext(); } private void CurrentCommand_CanExecuteChanged(object sender, EventArgs e) { ICommand cmd = sender as ICommand; cmd.CanExecuteChanged -= CurrentCommand_CanExecuteChanged; ExecuteNext(); } private void ExecuteNext() { lock (this.commandQueue) { while (this.commandQueue.Count > 0 && this.commandQueue.Peek().CanExecute(this.sharedParameter)) { ICommand cmd = this.commandQueue.Dequeue(); cmd.Execute(this.sharedParameter); } if (this.commandQueue.Count > 0) { this.commandQueue.Peek().CanExecuteChanged += CurrentCommand_CanExecuteChanged; } else { OnCanExecuteChanged(); } } } } }
Samples/DeviceLab/DeviceLab.csproj +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ <SubType>Designer</SubType> </ApplicationDefinition> <Compile Include="AutoScrollTextBox.cs" /> <Compile Include="CommandSequence.cs" /> <Compile Include="DeviceCollectionView.xaml.cs"> <DependentUpon>DeviceCollectionView.xaml</DependentUpon> </Compile> Loading
Samples/DeviceLab/DevicePortalViewModel.cs +2 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ using static Microsoft.Tools.WindowsDevicePortal.DevicePortal; namespace DeviceLab { public class DevicePortalViewModel : BindableBase { //------------------------------------------------------------------- Loading
Samples/DeviceLab/DeviceSignInViewModel.cs +1 −58 Original line number Diff line number Diff line Loading @@ -80,7 +80,6 @@ namespace DeviceLab /// <remarks>Diagnostic output will be lost</remarks> public DeviceSignInViewModel() { this.ready = true; this.diagnostics = new NullDiagnosticSink(); } Loading @@ -91,7 +90,6 @@ namespace DeviceLab /// <param name="diags">Diagnostic sink that will receive all the diagnostic output</param> public DeviceSignInViewModel(IDiagnosticSink diags) { this.ready = true; this.diagnostics = diags; } #endregion // Constructors Loading Loading @@ -127,15 +125,6 @@ namespace DeviceLab } #endregion // Password #region Ready private bool ready; public bool Ready { get { return this.ready; } private set { SetProperty(ref this.ready, value); } } #endregion // Ready #region Connection Types private ObservableCollection<IDevicePortalConnectionFactory> connectionTypes; public ObservableCollection<IDevicePortalConnectionFactory> ConnectionTypes Loading Loading @@ -174,13 +163,10 @@ namespace DeviceLab { if (connectCommand == null) { // TODO //connectCommand = DelegateCommand.FromAsyncHandler(ExecuteConnect, CanExecuteConnect); connectCommand = new DelegateCommand(ExecuteConnect, CanExecuteConnect); connectCommand.ObservesProperty(() => this.DeviceIP); connectCommand.ObservesProperty(() => this.UserName); connectCommand.ObservesProperty(() => this.Password); connectCommand.ObservesProperty(() => this.Ready); connectCommand.ObservesProperty(() => this.ConnectionTypeSelection); } return connectCommand; Loading @@ -194,52 +180,9 @@ namespace DeviceLab this.SignInAttempts?.Invoke(this, new DeviceSignInEventArgs(portal, conn)); } // TODO //private async Task OldExecuteConnectAsync() //{ // this.diagnostics.OutputDiagnosticString("[{0}] Attempting to connect.\n", this.deviceIP); // IDevicePortalConnection conn = this.ConnectionTypeSelection.CreateConnection(this.DeviceIP, this.UserName, this.Password); // DevicePortal portal = new DevicePortal(conn); // DeviceConnectionStatusEventHandler handler = (DevicePortal sender, DeviceConnectionStatusEventArgs args) => // { // this.diagnostics.OutputDiagnosticString("[{0}] Connection status update: Status: {1}, Phase: {2}\n", portal.Address, args.Status, args.Phase); // if (args.Status == DeviceConnectionStatus.Connected) // { // this.diagnostics.OutputDiagnosticString("[{0}] Language: {1}\n", portal.Address, conn.OsInfo.Language); // this.diagnostics.OutputDiagnosticString("[{0}] Name: {1}\n", portal.Address, conn.OsInfo.Name); // this.diagnostics.OutputDiagnosticString("[{0}] OsEdition: {1}\n", portal.Address, conn.OsInfo.OsEdition); // this.diagnostics.OutputDiagnosticString("[{0}] OsEditionId: {1}\n", portal.Address, conn.OsInfo.OsEditionId); // this.diagnostics.OutputDiagnosticString("[{0}] OsVersionString: {1}\n", portal.Address, conn.OsInfo.OsVersionString); // this.diagnostics.OutputDiagnosticString("[{0}] Platform: {1}\n", portal.Address, conn.OsInfo.Platform); // this.diagnostics.OutputDiagnosticString("[{0}] PlatformName: {1}\n", portal.Address, conn.OsInfo.PlatformName); // } // else if (args.Status == DeviceConnectionStatus.Failed) // { // this.diagnostics.OutputDiagnosticString("[{0}] Bummer.\n", portal.Address); // } // }; // portal.ConnectionStatus += handler; // try // { // this.Ready = false; // await portal.Connect(); // } // catch (Exception exn) // { // this.diagnostics.OutputDiagnosticString("[{0}] Exception when trying to connect:\n[{0}] {1}\nStackTrace: \n[{0}] {2}\n", portal.Address, exn.Message, exn.StackTrace); // } // this.SignInAttempts?.Invoke(this, new DeviceSignInEventArgs(portal.ConnectionHttpStatusCode, portal)); // portal.ConnectionStatus -= handler; // this.Ready = true; //} private bool CanExecuteConnect() { return Ready && !string.IsNullOrWhiteSpace(this.DeviceIP) && !string.IsNullOrWhiteSpace(this.UserName) && this.Password != null && Loading
Samples/DeviceLab/MainViewModel.cs +8 −108 Original line number Diff line number Diff line Loading @@ -11,102 +11,6 @@ using Microsoft.Tools.WindowsDevicePortal; namespace DeviceLab { public class NewDeviceHelper : ICommand { // TODO: Don't close over a DevicePortalViewModel // Instead, should just hook up the CanExecuteChanged events on // the commands private DevicePortalViewModel dpvm; private Queue<ICommand> commandQueue; private bool executionStarted; // TODO: public event EventHandler CanExecuteChanged; public NewDeviceHelper(DevicePortalViewModel dpvm) { this.dpvm = dpvm; this.commandQueue = new Queue<ICommand>(); this.executionStarted = false; } public void Enqueue(ICommand command) { if (this.executionStarted) { throw new InvalidOperationException("Execution already started"); } this.commandQueue.Enqueue(command); } private void Dpvm_PropertyChanged(object sender, PropertyChangedEventArgs e) { if(e.PropertyName == "Ready") { if(this.dpvm.Ready) { DoNextCommand(); } } } private void DoNextCommand() { if(this.commandQueue == null) { throw new InvalidOperationException("Attempting to execute commands without a command queue"); } if(this.commandQueue.Count == 0) { throw new InvalidOperationException("Attempting to execute command on an empty command queue"); } if(this.commandQueue.Peek().CanExecute(null)) { ICommand nextCommand = this.commandQueue.Dequeue(); if (this.commandQueue.Count == 0) { // Executing the next command will probably trigger property changed // events and since this is the last command we want to disconnect from // those events this.dpvm.PropertyChanged -= Dpvm_PropertyChanged; this.executionStarted = false; } nextCommand.Execute(null); } } public bool CanExecute(object parameter) { if(this.executionStarted) { return false; } if(this.commandQueue.Count > 0) { return this.commandQueue.Peek().CanExecute(null); } return false; } public void Execute(object parameter) { if(this.executionStarted) { throw new InvalidOperationException("Execution already started"); } dpvm.PropertyChanged += Dpvm_PropertyChanged; DoNextCommand(); } } public class MainViewModel : BindableBase { //------------------------------------------------------------------- Loading @@ -128,6 +32,8 @@ namespace DeviceLab this.ConnectedDevices.CollectionChanged += OnConnectedDevicesChanged; } #endregion // Constructors private void OnSignInAttemptCompleted(DeviceSignInViewModel sender, DeviceSignInEventArgs args) { Loading @@ -144,7 +50,6 @@ namespace DeviceLab this.ConnectedDevices.Add(new DevicePortalViewModel(args.Portal, Diagnostics)); } #endregion // Constructors //------------------------------------------------------------------- // Properties Loading Loading @@ -404,17 +309,12 @@ namespace DeviceLab private void OnDeviceAdded(DevicePortalViewModel dpvm) { dpvm.PropertyChanged += DevicePropertyChanged; // TODO: //CompositeCommand command = new CompositeCommand(); //command.RegisterCommand(dpvm.RefreshDeviceNameCommand); //command.RegisterCommand(dpvm.StartListeningForSystemPerfCommand); //command.Execute(null); NewDeviceHelper ndh = new NewDeviceHelper(dpvm); ndh.Enqueue(dpvm.ReestablishConnectionCommand); ndh.Enqueue(dpvm.RefreshDeviceNameCommand); ndh.Enqueue(dpvm.StartListeningForSystemPerfCommand); ndh.Execute(null); CommandSequence cmdSeq = new CommandSequence(); cmdSeq.RegisterCommand(dpvm.ReestablishConnectionCommand); cmdSeq.RegisterCommand(dpvm.RefreshDeviceNameCommand); cmdSeq.RegisterCommand(dpvm.StartListeningForSystemPerfCommand); cmdSeq.Execute(null); } private void OnDeviceRemoved(DevicePortalViewModel dpvm) Loading