mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Update UIX and rename disassembly as log view
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 263 B |
Binary file not shown.
|
After Width: | Height: | Size: 347 B |
@@ -0,0 +1,28 @@
|
||||
using Gemini.Framework.Commands;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace ZuneUIXTools.Modules.Shell.Commands;
|
||||
|
||||
[CommandDefinition]
|
||||
public class ContinueDebuggerCommandDefinition : CommandDefinition
|
||||
{
|
||||
private const string Text_Stop = "Continue";
|
||||
private const string ToolTip_Stop = "Continues execution until the next breakpoint is hit.";
|
||||
private static readonly Uri IconSource_Stop = new("pack://application:,,,/ZuneUIXTools;component/Images/DebugContinue_16x.png");
|
||||
|
||||
public const string CommandName = "Debugger.Continue";
|
||||
|
||||
public override string Name => CommandName;
|
||||
|
||||
public override string Text => Text_Stop;
|
||||
|
||||
public override string ToolTip => ToolTip_Stop;
|
||||
|
||||
public override Uri IconSource => IconSource_Stop;
|
||||
|
||||
[Export]
|
||||
public static CommandKeyboardShortcut KeyGesture
|
||||
= new CommandKeyboardShortcut<ContinueDebuggerCommandDefinition>(new KeyGesture(Key.F11));
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Gemini.Framework.Commands;
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace ZuneUIXTools.Modules.Shell.Commands;
|
||||
|
||||
[CommandDefinition]
|
||||
public class StepOverDebuggerCommandDefinition : CommandDefinition
|
||||
{
|
||||
private const string Text_Stop = "Step Over";
|
||||
private const string ToolTip_Stop = "Executes the current instruction and breaks at the next.";
|
||||
private static readonly Uri IconSource_Stop = new("pack://application:,,,/ZuneUIXTools;component/Images/StepOver_16x.png");
|
||||
|
||||
public const string CommandName = "Debugger.StepOver";
|
||||
|
||||
public override string Name => CommandName;
|
||||
|
||||
public override string Text => Text_Stop;
|
||||
|
||||
public override string ToolTip => ToolTip_Stop;
|
||||
|
||||
public override Uri IconSource => IconSource_Stop;
|
||||
|
||||
[Export]
|
||||
public static CommandKeyboardShortcut KeyGesture
|
||||
= new CommandKeyboardShortcut<StepOverDebuggerCommandDefinition>(new KeyGesture(Key.F10));
|
||||
}
|
||||
@@ -30,5 +30,13 @@ namespace ZuneUIXTools.Modules.Shell
|
||||
[Export]
|
||||
public static ToolBarItemDefinition StartStopDebuggerToolBarItem = new CommandToolBarItemDefinition<StartStopDebuggerCommandDefinition>(
|
||||
UIXDebuggerToolBarGroup, 0, ToolBarItemDisplay.IconOnly);
|
||||
|
||||
[Export]
|
||||
public static ToolBarItemDefinition StepOverDebuggerToolBarItem = new CommandToolBarItemDefinition<StepOverDebuggerCommandDefinition>(
|
||||
UIXDebuggerToolBarGroup, 4, ToolBarItemDisplay.IconOnly);
|
||||
|
||||
[Export]
|
||||
public static ToolBarItemDefinition ContinueDebuggerToolBarItem = new CommandToolBarItemDefinition<ContinueDebuggerCommandDefinition>(
|
||||
UIXDebuggerToolBarGroup, 1, ToolBarItemDisplay.IconOnly);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@ namespace ZuneUIXTools.Modules.UIX;
|
||||
public class DebuggerService
|
||||
{
|
||||
private readonly IOutput _output;
|
||||
private readonly ConcurrentDictionary<string, ConcurrentBag<InterpreterEntry>> _entriesByFile = new();
|
||||
private IDebuggerClient _client;
|
||||
private readonly ConcurrentDictionary<string, ConcurrentBag<InterpreterInstruction>> _entriesByFile = new();
|
||||
|
||||
public event Action Stopped;
|
||||
|
||||
@@ -27,33 +26,37 @@ public class DebuggerService
|
||||
_output = output;
|
||||
}
|
||||
|
||||
public bool IsRunning => _client != null;
|
||||
public bool IsRunning => Client != null;
|
||||
|
||||
public IDebuggerClient Client => _client;
|
||||
public IDebuggerClient Client { get; private set; }
|
||||
|
||||
public IReadOnlyDictionary<string, ConcurrentBag<InterpreterEntry>> ConstructedFiles => _entriesByFile;
|
||||
public IReadOnlyDictionary<string, ConcurrentBag<InterpreterInstruction>> ConstructedFiles => _entriesByFile;
|
||||
|
||||
public bool IsInBreakMode { get; private set; }
|
||||
|
||||
public void Start(string connectionUri = null)
|
||||
{
|
||||
Stop();
|
||||
|
||||
_client = new NetDebuggerClient(connectionUri);
|
||||
_client.InterpreterStep += Client_InterpreterStep;
|
||||
Client = new NetDebuggerClient(connectionUri);
|
||||
Client.InterpreterDecode += ClientInterpreterDecode;
|
||||
Client.InterpreterExecute += ClientInterpreterExecute;
|
||||
|
||||
_output.AppendLine($"Debugger connected to {_client.ConnectionUri}");
|
||||
_output.AppendLine($"Debugger listening on {Client.ConnectionUri}");
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_entriesByFile.Clear();
|
||||
|
||||
if (_client is null)
|
||||
if (Client is null)
|
||||
return;
|
||||
else if (_client is IDisposable disposable)
|
||||
else if (Client is IDisposable disposable)
|
||||
disposable.Dispose();
|
||||
|
||||
_client.InterpreterStep -= Client_InterpreterStep;
|
||||
_client = null;
|
||||
Client.InterpreterDecode -= ClientInterpreterDecode;
|
||||
Client.InterpreterExecute -= ClientInterpreterExecute;
|
||||
Client = null;
|
||||
|
||||
Stopped?.Invoke();
|
||||
_output.AppendLine("Debugger disconnected");
|
||||
@@ -67,16 +70,23 @@ public class DebuggerService
|
||||
var sortedEntries = entries.ToImmutableSortedSet();
|
||||
|
||||
StringBuilder sb = new();
|
||||
sb.AppendJoin(Environment.NewLine, sortedEntries.Select(e => e.ToInstructionString()));
|
||||
sb.AppendJoin(Environment.NewLine, sortedEntries.Select(e => e.ToString()));
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private void Client_InterpreterStep(object sender, InterpreterEntry currentEntry)
|
||||
private void ClientInterpreterDecode(object sender, InterpreterInstruction currentInstruction)
|
||||
{
|
||||
var entries = _entriesByFile.GetOrAdd(currentEntry.LoadUri, _ => new ConcurrentBag<InterpreterEntry>());
|
||||
_output.AppendLine("[UIX Dec] " + currentInstruction.ToString());
|
||||
|
||||
if (entries.Any(e => e.Offset == currentEntry.Offset))
|
||||
var entries = _entriesByFile.GetOrAdd(currentInstruction.LoadUri, _ => new());
|
||||
|
||||
if (entries.Any(e => e.Offset == currentInstruction.Offset))
|
||||
return;
|
||||
entries.Add(currentEntry);
|
||||
entries.Add(currentInstruction);
|
||||
}
|
||||
|
||||
private void ClientInterpreterExecute(object sender, InterpreterEntry entry)
|
||||
{
|
||||
_output.AppendLine("[UIX Exe] " + entry.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ZuneUIXTools.Modules.UIXCompiled"
|
||||
xmlns:uixDebugData="clr-namespace:Microsoft.Iris.Debug.Data"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:UIBDisassemblyViewModel}">
|
||||
|
||||
@@ -36,14 +36,14 @@ public class UIBDisassemblyViewModel : Document
|
||||
public UIBDisassemblyViewModel(DebuggerService debuggerService, IShell shell)
|
||||
{
|
||||
_debuggerService = debuggerService;
|
||||
_debuggerService.Client.InterpreterStep += Client_InterpreterStep;
|
||||
_debuggerService.Client.InterpreterExecute += ClientInterpreterExecute;
|
||||
|
||||
_shell = shell;
|
||||
|
||||
DisplayName = $"UIB Disassembler ('{_debuggerService.Client.ConnectionUri}')";
|
||||
}
|
||||
|
||||
private void Client_InterpreterStep(object sender, InterpreterEntry entry)
|
||||
private void ClientInterpreterExecute(object sender, InterpreterEntry entry)
|
||||
{
|
||||
_view?.Dispatcher.Invoke(() =>
|
||||
{
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<UserControl x:Class="ZuneUIXTools.Modules.UIXCompiled.UIXLogView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:ZuneUIXTools.Modules.UIXCompiled"
|
||||
xmlns:uixDebugData="clr-namespace:Microsoft.Iris.Debug.Data"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DataContext="{d:DesignInstance local:UIBDisassemblyViewModel}">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<CheckBox Content="Auto-scroll" IsChecked="{Binding AutoScroll}" Padding="4"/>
|
||||
|
||||
<DataGrid x:Name="InstructionListView" IsReadOnly="True" AutoGenerateColumns="False"
|
||||
ItemsSource="{Binding Instructions}" SelectionChanged="InstructionListView_SelectionChanged"
|
||||
Grid.Row="1">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Source" Binding="{Binding LoadUri}"/>
|
||||
<DataGridTextColumn Header="Instruction" Binding="{Binding InstructionString}"/>
|
||||
</DataGrid.Columns>
|
||||
<DataGrid.RowDetailsTemplate>
|
||||
<DataTemplate DataType="uixDebugData:InterpreterEntry">
|
||||
<Border Padding="8">
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock Text="Parameters:"/>
|
||||
<ItemsControl ItemsSource="{Binding Parameters}"/>
|
||||
<Border Height="1" Background="Gray" Margin="0,8"/>
|
||||
<TextBlock Text="Return values:"/>
|
||||
<ItemsControl ItemsSource="{Binding ReturnValues}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</DataGrid.RowDetailsTemplate>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,38 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using MahApps.Metro.Controls;
|
||||
using Microsoft.Iris.Debug.Data;
|
||||
|
||||
namespace ZuneUIXTools.Modules.UIXCompiled;
|
||||
|
||||
public partial class UIXLogView : UserControl
|
||||
{
|
||||
public UIBDisassemblyViewModel ViewModel => (UIBDisassemblyViewModel)DataContext;
|
||||
|
||||
public UIXLogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
InstructionListView.Loaded += InstructionListView_Loaded;
|
||||
}
|
||||
|
||||
private void InstructionListView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InstructionListView.Loaded -= InstructionListView_Loaded;
|
||||
InstructionListView.FindChild<ScrollViewer>().ScrollChanged += InstructionListView_ScrollChanged;
|
||||
}
|
||||
|
||||
private void InstructionListView_ScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||
{
|
||||
if (ViewModel.AutoScroll && e.ExtentHeightChange != 0)
|
||||
((ScrollViewer)sender).ScrollToBottom();
|
||||
}
|
||||
|
||||
private void InstructionListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count <= 0)
|
||||
return;
|
||||
|
||||
ViewModel.SetInspector(e.AddedItems[0] as InterpreterEntry);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Caliburn.Micro;
|
||||
using Gemini.Framework.Commands;
|
||||
using Gemini.Framework.Threading;
|
||||
using Gemini.Modules.ErrorList;
|
||||
using Gemini.Modules.Output;
|
||||
using Microsoft.Iris;
|
||||
using Microsoft.Iris.Debug.SystemNet;
|
||||
@@ -12,6 +13,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using ZuneUIXTools.Modules.Shell.Commands;
|
||||
using ZuneUIXTools.Modules.UIX;
|
||||
using Application = Microsoft.Iris.Application;
|
||||
using Command = Gemini.Framework.Commands.Command;
|
||||
|
||||
@@ -19,10 +21,14 @@ namespace ZuneUIXTools.Modules.UIXSource
|
||||
{
|
||||
[Export(typeof(UIXSourceEditorViewModel))]
|
||||
#pragma warning disable 659
|
||||
public class UIXSourceEditorViewModel : UIX.UIXEditorViewModelBase, ICommandHandler<BuildAndRunCommandDefinition>, ICommandHandler<BuildAndDebugCommandDefinition>
|
||||
public class UIXSourceEditorViewModel : UIXEditorViewModelBase, ICommandHandler<BuildAndRunCommandDefinition>, ICommandHandler<BuildAndDebugCommandDefinition>,
|
||||
ICommandHandler<StepOverDebuggerCommandDefinition>, ICommandHandler<ContinueDebuggerCommandDefinition>
|
||||
#pragma warning restore 659
|
||||
{
|
||||
private readonly IOutput _output = IoC.Get<IOutput>();
|
||||
private readonly IErrorList _errorList = IoC.Get<IErrorList>();
|
||||
private readonly DebuggerService _debuggerService = IoC.Get<DebuggerService>();
|
||||
|
||||
private UIXSourceEditorView _view;
|
||||
private string _originalText;
|
||||
private string _debuggerConnectionUri = App.DEFAULT_DEBUG_URI;
|
||||
@@ -83,15 +89,34 @@ namespace ZuneUIXTools.Modules.UIXSource
|
||||
|
||||
private void BuildAndRun(object parameter)
|
||||
{
|
||||
string sourceFile = FilePath;
|
||||
string compiledFile = Path.ChangeExtension(sourceFile, "uib");
|
||||
|
||||
bool attachDebugger = (bool)parameter;
|
||||
if (attachDebugger)
|
||||
{
|
||||
// Set up debugger client
|
||||
var debuggerService = IoC.Get<DebuggerService>();
|
||||
debuggerService.Start(_debuggerConnectionUri);
|
||||
|
||||
debuggerService.Client.UpdateBreakpoint(new($"file://{compiledFile}", 1));
|
||||
debuggerService.Client.DebuggerCommand = Microsoft.Iris.Debug.Data.InterpreterCommand.Continue;
|
||||
debuggerService.Client.RequestLineNumberTable($"file://{sourceFile}", entries =>
|
||||
{
|
||||
foreach (var entry in entries)
|
||||
_output.AppendLine($"{entry.Offset} => {entry.Line}, {entry.Column}");
|
||||
});
|
||||
|
||||
// Set up debugger server
|
||||
Application.DebugSettings.DebugConnectionUri = _debuggerConnectionUri;
|
||||
Application.DebuggerServerReady += OnDebuggerServerReady;
|
||||
Application.Initialized += () =>
|
||||
{
|
||||
// Server is ready, run the application
|
||||
Run(sourceFile, compiledFile);
|
||||
};
|
||||
}
|
||||
_output.AppendLine($"Compiling '{sourceFile}'...");
|
||||
|
||||
string sourceFile = FilePath;
|
||||
string compiledFile = Path.ChangeExtension(sourceFile, "uib");
|
||||
bool isSuccess = false;
|
||||
try
|
||||
{
|
||||
@@ -109,20 +134,13 @@ namespace ZuneUIXTools.Modules.UIXSource
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Dispatcher.Invoke(() =>
|
||||
//{
|
||||
// ErrorPanel.Children.Add(new TextBlock
|
||||
// {
|
||||
// Text = $"Build failed: {ex.Message}",
|
||||
// Margin = new Thickness(0, 0, 0, 4)
|
||||
// });
|
||||
//});
|
||||
_errorList.AddItem(ErrorListItemType.Error, "Compiling failed: " + ex.Message, sourceFile, null, null);
|
||||
}
|
||||
|
||||
if (!isSuccess)
|
||||
{
|
||||
var dialogResult = MessageBox.Show(
|
||||
"There were build errors. Would you like to contine and run the last successful build?",
|
||||
"There were build errors. Would you like to continue and run the last successful build?",
|
||||
"Zune UIX Tools", MessageBoxButton.YesNo, MessageBoxImage.Information
|
||||
);
|
||||
if (dialogResult != MessageBoxResult.Yes)
|
||||
@@ -135,41 +153,39 @@ namespace ZuneUIXTools.Modules.UIXSource
|
||||
}
|
||||
catch { }
|
||||
|
||||
// No need to wait for the debugger to start
|
||||
if (!attachDebugger)
|
||||
Run(sourceFile, compiledFile);
|
||||
}
|
||||
|
||||
private void Run(string sourceFile, string compiledFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
string uiRoot = null;// (IrisProject.SelectedDocument as UIXDocumentViewModel)?.UIRoot;
|
||||
string uiRoot = string.IsNullOrEmpty(UIRoot) ? "Default" : UIRoot;
|
||||
_output.AppendLine($"Loading UI '{uiRoot}' from '{compiledFile}'...");
|
||||
|
||||
Application.Window.SetBackgroundColor(new WindowColor(0xE6, 0xE6, 0xE6));
|
||||
Application.Window.RequestLoad("file://" + compiledFile + (string.IsNullOrEmpty(uiRoot) ? string.Empty : "#" + uiRoot));
|
||||
Application.Window.RequestLoad($"file://{compiledFile}#{uiRoot}");
|
||||
Application.Window.CloseRequested += (object sender, WindowCloseRequestedEventArgs args) =>
|
||||
{
|
||||
args.BlockCloseRequest();
|
||||
Application.Window.Visible = false;
|
||||
|
||||
if (sender is Microsoft.Iris.Window window)
|
||||
_output.AppendLine($"Window '{window.Handle}' closed");
|
||||
};
|
||||
|
||||
_output.AppendLine($"Application is running...");
|
||||
Application.Run();
|
||||
_output.AppendLine("Application exited");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Dispatcher.Invoke(() =>
|
||||
//{
|
||||
// ErrorPanel.Children.Add(new TextBlock
|
||||
// {
|
||||
// Text = $"Load failed: {ex.Message}",
|
||||
// Margin = new Thickness(0, 0, 0, 4)
|
||||
// });
|
||||
//});
|
||||
_errorList.AddItem(ErrorListItemType.Error, "Load failed: " + ex.Message, sourceFile, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDebuggerServerReady(object sender, EventArgs e)
|
||||
{
|
||||
// Set up the debugger client
|
||||
NetDebuggerClient debuggerClient = new(_debuggerConnectionUri);
|
||||
debuggerClient.DispatcherStep += message =>
|
||||
{
|
||||
_output.AppendLine($"[{DisplayName}] [Dispatcher] {message}");
|
||||
};
|
||||
}
|
||||
|
||||
void ICommandHandler<BuildAndRunCommandDefinition>.Update(Command command) => command.Enabled = CanBuild;
|
||||
|
||||
Task ICommandHandler<BuildAndRunCommandDefinition>.Run(Command command)
|
||||
@@ -185,5 +201,31 @@ namespace ZuneUIXTools.Modules.UIXSource
|
||||
StartBuildAndRun(true);
|
||||
return TaskUtility.Completed;
|
||||
}
|
||||
|
||||
void ICommandHandler<StepOverDebuggerCommandDefinition>.Update(Command command)
|
||||
{
|
||||
command.Visible = _debuggerService.Client != null;
|
||||
command.Enabled = _debuggerService.Client != null
|
||||
&& _debuggerService.Client.DebuggerCommand == Microsoft.Iris.Debug.Data.InterpreterCommand.Break;
|
||||
}
|
||||
|
||||
Task ICommandHandler<StepOverDebuggerCommandDefinition>.Run(Command command)
|
||||
{
|
||||
_debuggerService.Client.DebuggerCommand = Microsoft.Iris.Debug.Data.InterpreterCommand.Step;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
void ICommandHandler<ContinueDebuggerCommandDefinition>.Update(Command command)
|
||||
{
|
||||
command.Visible = _debuggerService.Client != null;
|
||||
command.Enabled = _debuggerService.Client != null
|
||||
&& _debuggerService.Client.DebuggerCommand != Microsoft.Iris.Debug.Data.InterpreterCommand.Continue;
|
||||
}
|
||||
|
||||
Task ICommandHandler<ContinueDebuggerCommandDefinition>.Run(Command command)
|
||||
{
|
||||
_debuggerService.Client.DebuggerCommand = Microsoft.Iris.Debug.Data.InterpreterCommand.Continue;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
Submodule libs/MicrosoftIris updated: a4c47e611a...46833d467f
Reference in New Issue
Block a user