Code cleanup.

This commit is contained in:
José Pedro 2018-08-27 22:42:05 +01:00
parent 2ba220782d
commit 22989bb677
No known key found for this signature in database
GPG key ID: B8247B9301707B83
2 changed files with 97 additions and 80 deletions

View file

@ -1,8 +1,10 @@
using System; using System;
using System.ComponentModel.Design; using System.ComponentModel.Design;
using Microsoft.VisualStudio; using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Threading;
using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
using Cosmos.VS.Windows.ToolWindows; using Cosmos.VS.Windows.ToolWindows;
@ -16,86 +18,79 @@ namespace Cosmos.VS.Windows
public const int CosmosInternalCmdID = 0x0103; public const int CosmosInternalCmdID = 0x0103;
public const int CosmosShowAllCmdID = 0x0104; public const int CosmosShowAllCmdID = 0x0104;
private readonly CosmosWindowsPackage package; private readonly CosmosWindowsPackage _package;
private CosmosMenuCmdSet(CosmosWindowsPackage package) private CosmosMenuCmdSet(CosmosWindowsPackage package)
{ {
this.package = package ?? throw new ArgumentNullException(nameof(package)); _package = package ?? throw new ArgumentNullException(nameof(package));
AddCommand(CosmosAssemblyCmdID, ShowWindowAssembly); AddCommand(CosmosAssemblyCmdID, ShowWindowAssemblyAsync);
AddCommand(CosmosRegistersCmdID, ShowWindowRegisters); AddCommand(CosmosRegistersCmdID, ShowWindowRegistersAsync);
AddCommand(CosmosStackCmdID, ShowWindowStack); AddCommand(CosmosStackCmdID, ShowWindowStackAsync);
AddCommand(CosmosInternalCmdID, ShowWindowInternal); AddCommand(CosmosInternalCmdID, ShowWindowInternalAsync);
AddCommand(CosmosShowAllCmdID, ShowWindowAll); AddCommand(CosmosShowAllCmdID, ShowWindowAllAsync);
} }
private void AddCommand(int cmdId, EventHandler handler) private void AddCommand(int cmdId, EventHandler handler)
{ {
OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; if (ServiceProvider.GetService(typeof(IMenuCommandService)) is OleMenuCommandService commandService)
if (commandService != null)
{ {
var menuCommandID = new CommandID(Guids.CosmosMenuCmdSetGuid, cmdId); var menuCommandID = new CommandID(Guids.CosmosMenuCmdSetGuid, cmdId);
var menuItem = new MenuCommand(handler, menuCommandID); var menuItem = new MenuCommand(handler, menuCommandID);
commandService.AddCommand(menuItem); commandService.AddCommand(menuItem);
} }
} }
private void AddCommand(int cmdId, AsyncEventHandler handler) =>
AddCommand(cmdId, (EventHandler)((sender, e) => handler?.InvokeAsync(sender, e)));
public static CosmosMenuCmdSet Instance { get; private set; } public static CosmosMenuCmdSet Instance { get; private set; }
private IServiceProvider ServiceProvider => package; private IServiceProvider ServiceProvider => _package;
public static void Initialize(CosmosWindowsPackage package) public static void Initialize(CosmosWindowsPackage package)
{ {
Instance = new CosmosMenuCmdSet(package); Instance = new CosmosMenuCmdSet(package);
} }
private void ShowWindow(Type aWindowType) private async Task ShowWindowAsync(Type aWindowType)
{ {
var xWindow = package.FindWindow(aWindowType); await _package.JoinableTaskFactory.SwitchToMainThreadAsync();
var xWindow = await _package.FindWindowAsync(aWindowType);
var xFrame = (IVsWindowFrame)xWindow.Frame; var xFrame = (IVsWindowFrame)xWindow.Frame;
ErrorHandler.ThrowOnFailure(xFrame.Show()); ErrorHandler.ThrowOnFailure(xFrame.Show());
} }
private void ShowChannelWindow(Type aWindowType) private async Task ShowChannelWindowAsync(Type aWindowType)
{ {
var xWindow = package.FindChannelWindow(aWindowType); await _package.JoinableTaskFactory.SwitchToMainThreadAsync();
var xWindow = await _package.FindChannelWindowAsync(aWindowType);
var xFrame = (IVsWindowFrame)xWindow.Frame; var xFrame = (IVsWindowFrame)xWindow.Frame;
ErrorHandler.ThrowOnFailure(xFrame.Show()); ErrorHandler.ThrowOnFailure(xFrame.Show());
} }
private void ShowWindowAssembly(object aCommand, EventArgs e) private Task ShowWindowAssemblyAsync(object sender, EventArgs e) => ShowWindowAsync(typeof(AssemblyToolWindow));
{
ShowWindow(typeof(AssemblyToolWindow));
}
private void ShowWindowInternal(object aCommand, EventArgs e) private Task ShowWindowInternalAsync(object sender, EventArgs e) => ShowWindowAsync(typeof(InternalTW));
{
ShowWindow(typeof(InternalTW));
}
private void ShowWindowRegisters(object aCommand, EventArgs e) private Task ShowWindowRegistersAsync(object sender, EventArgs e) => ShowWindowAsync(typeof(RegistersToolWindow));
{
ShowWindow(typeof(RegistersToolWindow));
}
private void ShowWindowStack(object aCommand, EventArgs e) private Task ShowWindowStackAsync(object sender, EventArgs e) => ShowWindowAsync(typeof(StackTW));
{
ShowWindow(typeof(StackTW));
}
private void ShowWindowConsole(object aCommand, EventArgs e) private Task ShowWindowConsoleAsync(object sender, EventArgs e) => ShowChannelWindowAsync(typeof(ConsoleTW));
{
ShowChannelWindow(typeof(ConsoleTW));
}
private void ShowWindowAll(object aCommand, EventArgs e) private Task ShowWindowAllAsync(object sender, EventArgs e) =>
{ Task.WhenAll(
ShowWindowAssembly(aCommand, e); ShowWindowAssemblyAsync(sender, e),
ShowWindowRegisters(aCommand, e); ShowWindowRegistersAsync(sender, e),
ShowWindowStack(aCommand, e); ShowWindowStackAsync(sender, e)
//ShowWindowConsole(aCommand, e); //ShowWindowConsole(sender, e)
// Dont show Internal Window, most Cosmos users wont use it. // Dont show Internal Window, most Cosmos users wont use it.
} );
} }
} }

View file

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Windows.Threading; using System.Threading.Tasks;
using Microsoft.VisualStudio; using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell.Interop;
@ -48,7 +48,7 @@ namespace Cosmos.VS.Windows
// So instead we use a stack and a timer to poll it for data. // So instead we use a stack and a timer to poll it for data.
mTimer = new Timer(100); mTimer = new Timer(100);
mTimer.AutoReset = true; mTimer.AutoReset = true;
mTimer.Elapsed += ProcessMessage; mTimer.Elapsed += (sender, e) => JoinableTaskFactory.RunAsync(() => ProcessMessageAsync(sender, e));
mTimer.Start(); mTimer.Start();
mPipeDown = new PipeServer(Pipes.DownName); mPipeDown = new PipeServer(Pipes.DownName);
@ -87,7 +87,7 @@ namespace Cosmos.VS.Windows
base.Dispose(disposing); base.Dispose(disposing);
} }
void ProcessMessage(object sender, EventArgs e) private async Task ProcessMessageAsync(object sender, EventArgs e)
{ {
ushort xCmd; ushort xCmd;
byte[] xMsg; byte[] xMsg;
@ -111,47 +111,47 @@ namespace Cosmos.VS.Windows
break; break;
case Debugger2Windows.Stack: case Debugger2Windows.Stack:
UpdateWindow(typeof(StackTW), "STACK", xMsg); await UpdateWindowAsync(typeof(StackTW), "STACK", xMsg);
break; break;
case Debugger2Windows.Frame: case Debugger2Windows.Frame:
UpdateWindow(typeof(StackTW), "FRAME", xMsg); await UpdateWindowAsync(typeof(StackTW), "FRAME", xMsg);
break; break;
case Debugger2Windows.Registers: case Debugger2Windows.Registers:
UpdateWindow(typeof(RegistersToolWindow), null, xMsg); await UpdateWindowAsync(typeof(RegistersToolWindow), null, xMsg);
break; break;
case Debugger2Windows.Quit: case Debugger2Windows.Quit:
break; break;
case Debugger2Windows.AssemblySource: case Debugger2Windows.AssemblySource:
UpdateWindow(typeof(AssemblyToolWindow), null, xMsg); await UpdateWindowAsync(typeof(AssemblyToolWindow), null, xMsg);
break; break;
case Debugger2Windows.PongVSIP: case Debugger2Windows.PongVSIP:
UpdateWindow(typeof(InternalTW), null, Encoding.UTF8.GetBytes("Pong from VSIP")); await UpdateWindowAsync(typeof(InternalTW), null, Encoding.UTF8.GetBytes("Pong from VSIP"));
break; break;
case Debugger2Windows.PongDebugStub: case Debugger2Windows.PongDebugStub:
UpdateWindow(typeof(InternalTW), null, Encoding.UTF8.GetBytes("Pong from DebugStub")); await UpdateWindowAsync(typeof(InternalTW), null, Encoding.UTF8.GetBytes("Pong from DebugStub"));
break; break;
case Debugger2Windows.OutputPane: case Debugger2Windows.OutputPane:
System.Windows.Application.Current.Dispatcher.Invoke( await JoinableTaskFactory.SwitchToMainThreadAsync();
() => Global.OutputPane.OutputString(Encoding.UTF8.GetString(xMsg)), Global.OutputPane.OutputString(Encoding.UTF8.GetString(xMsg));
DispatcherPriority.Normal);
break; break;
case Debugger2Windows.OutputClear: case Debugger2Windows.OutputClear:
System.Windows.Application.Current.Dispatcher.Invoke( await JoinableTaskFactory.SwitchToMainThreadAsync();
() => { Global.OutputPane.Clear(); StateStorer.ClearState(); }, DispatcherPriority.Normal); Global.OutputPane.Clear();
StateStorer.ClearState();
break; break;
} }
} }
else else
{ {
UpdateChannelWindows(xCmd, xMsg); await UpdateChannelWindowsAsync(xCmd, xMsg);
} }
} }
} }
@ -178,6 +178,19 @@ namespace Cosmos.VS.Windows
return xWindow as ToolWindowPane2; return xWindow as ToolWindowPane2;
} }
public async Task<ToolWindowPane2> FindWindowAsync(Type aWindowType)
{
// Get the instance number 0 of this tool window.
// Our windows are single instance so this instance will be the only one.
// The last flag is set to true so that if the tool window does not exists it will be created.
var xWindow = await FindToolWindowAsync(aWindowType, 0, true, default);
if (xWindow?.Frame == null)
{
throw new NotSupportedException("Failed to create the Cosmos tool window.");
}
return xWindow as ToolWindowPane2;
}
public ToolWindowPaneChannel FindChannelWindow(Type aWindowType) public ToolWindowPaneChannel FindChannelWindow(Type aWindowType)
{ {
// Get the instance number 0 of this tool window. // Get the instance number 0 of this tool window.
@ -191,32 +204,41 @@ namespace Cosmos.VS.Windows
return xWindow as ToolWindowPaneChannel; return xWindow as ToolWindowPaneChannel;
} }
public void UpdateChannelWindows(ushort aChannelAndCommand, byte[] aData) public async Task<ToolWindowPaneChannel> FindChannelWindowAsync(Type aWindowType)
{ {
System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, // Get the instance number 0 of this tool window.
(Action)delegate () // Our windows are single instance so this instance will be the only one.
// The last flag is set to true so that if the tool window does not exists it will be created.
var xWindow = await FindToolWindowAsync(aWindowType, 0, true, default);
if (xWindow?.Frame == null)
{ {
throw new NotSupportedException("Failed to create the Cosmos tool window.");
}
return xWindow as ToolWindowPaneChannel;
}
public async Task UpdateChannelWindowsAsync(ushort aChannelAndCommand, byte[] aData)
{
await JoinableTaskFactory.SwitchToMainThreadAsync();
foreach (var xType in mAllChannelWindowTypes) foreach (var xType in mAllChannelWindowTypes)
{ {
var xWindow = FindChannelWindow(xType); var xWindow = await FindChannelWindowAsync(xType);
xWindow.UserControl.Package = this; xWindow.UserControl.Package = this;
xWindow.UserControl.HandleChannelMessage(aChannelAndCommand, aData); xWindow.UserControl.HandleChannelMessage(aChannelAndCommand, aData);
} }
} }
);
}
public void UpdateWindow(Type aWindowType, string aTag, byte[] aData) private async Task UpdateWindowAsync(Type aWindowType, string aTag, byte[] aData)
{ {
System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.DataBind, await JoinableTaskFactory.SwitchToMainThreadAsync();
(Action)delegate ()
{ var xWindow = await FindWindowAsync(aWindowType);
var xWindow = FindWindow(aWindowType);
xWindow.UserControl.Package = this; xWindow.UserControl.Package = this;
xWindow.UserControl.Update(aTag, aData); xWindow.UserControl.Update(aTag, aData);
} }
);
}
public void StoreAllStates() public void StoreAllStates()
{ {