Debugger: Improved performance when a lot of labels are defined (e.g 1000+)
This commit is contained in:
parent
36617a6055
commit
17a02fb5c8
12 changed files with 207 additions and 150 deletions
|
@ -8,6 +8,13 @@ LabelManager::LabelManager(shared_ptr<BaseMapper> mapper)
|
|||
_mapper = mapper;
|
||||
}
|
||||
|
||||
void LabelManager::DeleteLabels()
|
||||
{
|
||||
_codeComments.clear();
|
||||
_codeLabels.clear();
|
||||
_codeLabelReverseLookup.clear();
|
||||
}
|
||||
|
||||
void LabelManager::SetLabel(uint32_t address, AddressType addressType, string label, string comment)
|
||||
{
|
||||
address = GetLabelAddress(address, addressType);
|
||||
|
|
|
@ -33,7 +33,8 @@ public:
|
|||
LabelManager(shared_ptr<BaseMapper> mapper);
|
||||
|
||||
void SetLabel(uint32_t address, AddressType addressType, string label, string comment);
|
||||
|
||||
void DeleteLabels();
|
||||
|
||||
int32_t GetLabelRelativeAddress(string label);
|
||||
|
||||
string GetLabel(uint16_t relativeAddr, bool checkRegisters);
|
||||
|
|
|
@ -22,15 +22,16 @@ namespace Mesen.GUI.Controls
|
|||
}
|
||||
}
|
||||
|
||||
private static bool? _isDesignMode = null;
|
||||
public bool IsDesignMode
|
||||
{
|
||||
get
|
||||
{
|
||||
try {
|
||||
return (
|
||||
LicenseManager.UsageMode == LicenseUsageMode.Designtime ||
|
||||
System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv"
|
||||
);
|
||||
if(!_isDesignMode.HasValue) {
|
||||
_isDesignMode = System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv";
|
||||
}
|
||||
return _isDesignMode.Value || LicenseManager.UsageMode == LicenseUsageMode.Designtime;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
this.lstFunctions.TabIndex = 2;
|
||||
this.lstFunctions.UseCompatibleStateImageBehavior = false;
|
||||
this.lstFunctions.View = System.Windows.Forms.View.Details;
|
||||
this.lstFunctions.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lstFunctions_RetrieveVirtualItem);
|
||||
this.lstFunctions.SearchForVirtualItem += new System.Windows.Forms.SearchForVirtualItemEventHandler(this.lstFunctions_SearchForVirtualItem);
|
||||
this.lstFunctions.SelectedIndexChanged += new System.EventHandler(this.lstFunctions_SelectedIndexChanged);
|
||||
this.lstFunctions.DoubleClick += new System.EventHandler(this.lstFunctions_DoubleClick);
|
||||
//
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
public event EventHandler OnFindOccurrence;
|
||||
public event EventHandler OnFunctionSelected;
|
||||
|
||||
private List<ListViewItem> _listItems = new List<ListViewItem>();
|
||||
private Dictionary<Int32, ListViewItem> _functions = new Dictionary<int, ListViewItem>();
|
||||
|
||||
public ctrlFunctionList()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -38,100 +41,99 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
mnuFindOccurrences.InitShortcut(this, nameof(DebuggerShortcutsConfig.FunctionList_FindOccurrences));
|
||||
}
|
||||
|
||||
private class FunctionComparer : IComparer
|
||||
private int CompareFunctions(ListViewItem a, ListViewItem b)
|
||||
{
|
||||
int IComparer.Compare(object x, object y)
|
||||
{
|
||||
ListViewItem a = x as ListViewItem;
|
||||
ListViewItem b = y as ListViewItem;
|
||||
string aText = string.IsNullOrWhiteSpace(a.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : a.Text;
|
||||
string bText = string.IsNullOrWhiteSpace(b.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : b.Text;
|
||||
Int32 aRelative = (Int32)a.SubItems[1].Tag == -1 ? Int32.MaxValue : (Int32)a.SubItems[1].Tag;
|
||||
Int32 bRelative = (Int32)b.SubItems[1].Tag == -1 ? Int32.MaxValue : (Int32)b.SubItems[1].Tag;
|
||||
Int32 aAbsolute = (Int32)a.SubItems[2].Tag;
|
||||
Int32 bAbsolute = (Int32)b.SubItems[2].Tag;
|
||||
|
||||
string aText = string.IsNullOrWhiteSpace(a.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : a.Text;
|
||||
string bText = string.IsNullOrWhiteSpace(b.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : b.Text;
|
||||
Int32 aRelative = (Int32)a.SubItems[1].Tag == -1 ? Int32.MaxValue : (Int32)a.SubItems[1].Tag;
|
||||
Int32 bRelative = (Int32)b.SubItems[1].Tag == -1 ? Int32.MaxValue : (Int32)b.SubItems[1].Tag;
|
||||
Int32 aAbsolute = (Int32)a.SubItems[2].Tag;
|
||||
Int32 bAbsolute = (Int32)b.SubItems[2].Tag;
|
||||
|
||||
if(a.Text == b.Text) {
|
||||
if(a.Tag == b.Tag) {
|
||||
return aAbsolute > bAbsolute ? 1 : -1;
|
||||
} else {
|
||||
return aRelative > bRelative ? 1 : -1;
|
||||
}
|
||||
if(a.Text == b.Text) {
|
||||
if(a.Tag == b.Tag) {
|
||||
return aAbsolute > bAbsolute ? 1 : -1;
|
||||
} else {
|
||||
return string.Compare(aText, bText);
|
||||
return aRelative > bRelative ? 1 : -1;
|
||||
}
|
||||
} else {
|
||||
return string.Compare(aText, bText);
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<Int32, ListViewItem> _functions = new Dictionary<int, ListViewItem>();
|
||||
public void UpdateFunctionList(bool reset)
|
||||
{
|
||||
if(reset) {
|
||||
lstFunctions.Items.Clear();
|
||||
_listItems.Clear();
|
||||
_functions.Clear();
|
||||
}
|
||||
|
||||
Font italicFont = null;
|
||||
Font regularFont = null;
|
||||
|
||||
Int32[] entryPoints = InteropEmu.DebugGetFunctionEntryPoints();
|
||||
bool updating = false;
|
||||
|
||||
for(int i = 0; i < entryPoints.Length && entryPoints[i] >= 0; i++) {
|
||||
Int32 entryPoint = entryPoints[i];
|
||||
ListViewItem item;
|
||||
if(!_functions.TryGetValue(entryPoint, out item)) {
|
||||
if(!updating) {
|
||||
updating = true;
|
||||
lstFunctions.BeginUpdate();
|
||||
lstFunctions.ListViewItemSorter = null;
|
||||
}
|
||||
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)entryPoint, AddressType.PrgRom);
|
||||
item = lstFunctions.Items.Add(label?.Label);
|
||||
item = new ListViewItem(label?.Label);
|
||||
item.Tag = label;
|
||||
|
||||
item.SubItems.Add("[n/a]");
|
||||
item.SubItems[1].Tag = -1;
|
||||
item.ForeColor = Color.Gray;
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
|
||||
if(italicFont == null) {
|
||||
italicFont = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
item.Font = italicFont;
|
||||
|
||||
item.SubItems.Add("$" + entryPoint.ToString("X4"));
|
||||
item.SubItems[2].Tag = entryPoint;
|
||||
|
||||
_listItems.Add(item);
|
||||
_functions[entryPoint] = item;
|
||||
}
|
||||
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress((UInt32)entryPoint, AddressType.PrgRom);
|
||||
if(relativeAddress != (Int32)item.SubItems[1].Tag) {
|
||||
if(!updating) {
|
||||
updating = true;
|
||||
lstFunctions.BeginUpdate();
|
||||
lstFunctions.ListViewItemSorter = null;
|
||||
}
|
||||
|
||||
if(relativeAddress >= 0) {
|
||||
item.SubItems[1].Text = "$" + relativeAddress.ToString("X4");
|
||||
item.ForeColor = Color.Black;
|
||||
item.Font = new Font(item.Font, FontStyle.Regular);
|
||||
if(regularFont == null) {
|
||||
regularFont = new Font(item.Font, FontStyle.Regular);
|
||||
}
|
||||
item.Font = regularFont;
|
||||
} else {
|
||||
item.SubItems[1].Text = "[n/a]";
|
||||
item.ForeColor = Color.Gray;
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
if(italicFont == null) {
|
||||
italicFont = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
item.Font = italicFont;
|
||||
}
|
||||
item.SubItems[1].Tag = relativeAddress;
|
||||
}
|
||||
}
|
||||
|
||||
if(updating) {
|
||||
lstFunctions.ListViewItemSorter = new FunctionComparer();
|
||||
lstFunctions.Sort();
|
||||
lstFunctions.EndUpdate();
|
||||
}
|
||||
lstFunctions.BeginUpdate();
|
||||
_listItems.Sort(CompareFunctions);
|
||||
lstFunctions.VirtualMode = true;
|
||||
lstFunctions.VirtualListSize = _listItems.Count;
|
||||
lstFunctions.EndUpdate();
|
||||
}
|
||||
|
||||
private ListViewItem GetSelectedItem()
|
||||
{
|
||||
return _listItems[lstFunctions.SelectedIndices[0]];
|
||||
}
|
||||
|
||||
private void lstFunctions_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(lstFunctions.SelectedItems.Count > 0) {
|
||||
Int32 relativeAddress = (Int32)lstFunctions.SelectedItems[0].SubItems[1].Tag;
|
||||
if(lstFunctions.SelectedIndices.Count > 0) {
|
||||
Int32 relativeAddress = (Int32)GetSelectedItem().SubItems[1].Tag;
|
||||
|
||||
if(relativeAddress >= 0) {
|
||||
OnFunctionSelected?.Invoke(relativeAddress, e);
|
||||
|
@ -141,26 +143,26 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void mnuEditLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstFunctions.SelectedItems.Count > 0) {
|
||||
CodeLabel label = lstFunctions.SelectedItems[0].Tag as CodeLabel;
|
||||
if(lstFunctions.SelectedIndices.Count > 0) {
|
||||
CodeLabel label = GetSelectedItem().Tag as CodeLabel;
|
||||
if(label != null) {
|
||||
ctrlLabelList.EditLabel(label.Address, label.AddressType);
|
||||
} else {
|
||||
ctrlLabelList.EditLabel((UInt32)(Int32)lstFunctions.SelectedItems[0].SubItems[2].Tag, AddressType.PrgRom);
|
||||
ctrlLabelList.EditLabel((UInt32)(Int32)GetSelectedItem().SubItems[2].Tag, AddressType.PrgRom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuFindOccurrences_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstFunctions.SelectedItems.Count > 0) {
|
||||
int relativeAddress = (int)lstFunctions.SelectedItems[0].SubItems[1].Tag;
|
||||
if(lstFunctions.SelectedIndices.Count > 0) {
|
||||
int relativeAddress = (int)GetSelectedItem().SubItems[1].Tag;
|
||||
if(relativeAddress >= 0) {
|
||||
CodeLabel label = lstFunctions.SelectedItems[0].Tag as CodeLabel;
|
||||
CodeLabel label = GetSelectedItem().Tag as CodeLabel;
|
||||
if(label != null) {
|
||||
OnFindOccurrence?.Invoke(label.Label, null);
|
||||
} else {
|
||||
OnFindOccurrence?.Invoke("$" + ((int)lstFunctions.SelectedItems[0].SubItems[1].Tag).ToString("X4"), null);
|
||||
OnFindOccurrence?.Invoke("$" + ((int)GetSelectedItem().SubItems[1].Tag).ToString("X4"), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,10 +170,10 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void lstFunctions_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
mnuEditLabel.Enabled = lstFunctions.SelectedItems.Count == 1;
|
||||
mnuFindOccurrences.Enabled = lstFunctions.SelectedItems.Count == 1;
|
||||
if(lstFunctions.SelectedItems.Count == 1) {
|
||||
int relativeAddress = (int)lstFunctions.SelectedItems[0].SubItems[1].Tag;
|
||||
mnuEditLabel.Enabled = lstFunctions.SelectedIndices.Count == 1;
|
||||
mnuFindOccurrences.Enabled = lstFunctions.SelectedIndices.Count == 1;
|
||||
if(lstFunctions.SelectedIndices.Count == 1) {
|
||||
int relativeAddress = (int)GetSelectedItem().SubItems[1].Tag;
|
||||
if(relativeAddress < 0) {
|
||||
mnuFindOccurrences.Enabled = false;
|
||||
}
|
||||
|
@ -180,9 +182,9 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void mnuAddBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstFunctions.SelectedItems.Count > 0) {
|
||||
CodeLabel label = lstFunctions.SelectedItems[0].Tag as CodeLabel;
|
||||
int absoluteAddress = (int)lstFunctions.SelectedItems[0].SubItems[2].Tag;
|
||||
if(lstFunctions.SelectedIndices.Count > 0) {
|
||||
CodeLabel label = GetSelectedItem().Tag as CodeLabel;
|
||||
int absoluteAddress = (int)GetSelectedItem().SubItems[2].Tag;
|
||||
BreakpointManager.AddBreakpoint(new Breakpoint() {
|
||||
MemoryType = DebugMemoryType.PrgRom,
|
||||
BreakOnExec = true,
|
||||
|
@ -195,5 +197,15 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void lstFunctions_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
|
||||
{
|
||||
e.Item = _listItems[e.ItemIndex];
|
||||
}
|
||||
|
||||
private void lstFunctions_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,6 +147,8 @@
|
|||
this.lstLabels.UseCompatibleStateImageBehavior = false;
|
||||
this.lstLabels.View = System.Windows.Forms.View.Details;
|
||||
this.lstLabels.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lstLabels_ColumnClick);
|
||||
this.lstLabels.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lstLabels_RetrieveVirtualItem);
|
||||
this.lstLabels.SearchForVirtualItem += new System.Windows.Forms.SearchForVirtualItemEventHandler(this.lstLabels_SearchForVirtualItem);
|
||||
this.lstLabels.SelectedIndexChanged += new System.EventHandler(this.lstLabels_SelectedIndexChanged);
|
||||
this.lstLabels.DoubleClick += new System.EventHandler(this.lstLabels_DoubleClick);
|
||||
//
|
||||
|
|
|
@ -17,33 +17,14 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
{
|
||||
public event EventHandler OnFindOccurrence;
|
||||
public event EventHandler OnLabelSelected;
|
||||
|
||||
private List<ListViewItem> _listItems = new List<ListViewItem>();
|
||||
|
||||
private class LabelComparer : IComparer
|
||||
{
|
||||
private int _columnIndex;
|
||||
private bool _sortOrder;
|
||||
public LabelComparer(int columnIndex, bool sortOrder)
|
||||
{
|
||||
_columnIndex = columnIndex;
|
||||
_sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public int Compare(object x, object y)
|
||||
{
|
||||
int result = String.Compare(((ListViewItem)x).SubItems[_columnIndex].Text, ((ListViewItem)y).SubItems[_columnIndex].Text);
|
||||
if(result == 0 && (_columnIndex == 0 || _columnIndex == 3)) {
|
||||
result = String.Compare(((ListViewItem)x).SubItems[2].Text, ((ListViewItem)y).SubItems[2].Text);
|
||||
}
|
||||
|
||||
return result * (_sortOrder ? -1 : 1);
|
||||
}
|
||||
}
|
||||
private int _sortColumn = 0;
|
||||
private bool _descSort = false;
|
||||
|
||||
public ctrlLabelList()
|
||||
{
|
||||
InitializeComponent();
|
||||
lstLabels.ListViewItemSorter = new LabelComparer(0, false);
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
|
@ -83,33 +64,52 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
}
|
||||
}
|
||||
|
||||
public int CompareLabels(ListViewItem x, ListViewItem y)
|
||||
{
|
||||
int result = String.Compare(((ListViewItem)x).SubItems[_sortColumn].Text, ((ListViewItem)y).SubItems[_sortColumn].Text);
|
||||
if(result == 0 && (_sortColumn == 0 || _sortColumn == 3)) {
|
||||
result = String.Compare(((ListViewItem)x).SubItems[2].Text, ((ListViewItem)y).SubItems[2].Text);
|
||||
}
|
||||
return result * (_descSort ? -1 : 1);
|
||||
}
|
||||
|
||||
private void SortItems()
|
||||
{
|
||||
_listItems.Sort(CompareLabels);
|
||||
}
|
||||
|
||||
public void UpdateLabelListAddresses()
|
||||
{
|
||||
bool updating = false;
|
||||
bool needUpdate = false;
|
||||
Font italicFont = null;
|
||||
Font regularFont = null;
|
||||
|
||||
foreach(ListViewItem item in _listItems) {
|
||||
CodeLabel label = (CodeLabel)item.SubItems[1].Tag;
|
||||
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
||||
if(relativeAddress != (Int32)item.Tag) {
|
||||
if(!updating) {
|
||||
lstLabels.BeginUpdate();
|
||||
updating = true;
|
||||
}
|
||||
needUpdate = true;
|
||||
if(relativeAddress >= 0) {
|
||||
item.SubItems[1].Text = "$" + relativeAddress.ToString("X4");
|
||||
item.ForeColor = Color.Black;
|
||||
item.Font = new Font(item.Font, FontStyle.Regular);
|
||||
if(regularFont == null) {
|
||||
regularFont = new Font(item.Font, FontStyle.Regular);
|
||||
}
|
||||
item.Font = regularFont;
|
||||
} else {
|
||||
item.SubItems[1].Text = "[n/a]";
|
||||
item.ForeColor = Color.Gray;
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
if(italicFont == null) {
|
||||
italicFont = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
item.Font = italicFont;
|
||||
}
|
||||
item.Tag = relativeAddress;
|
||||
}
|
||||
}
|
||||
if(updating) {
|
||||
lstLabels.Sort();
|
||||
lstLabels.EndUpdate();
|
||||
if(needUpdate) {
|
||||
SortItems();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
{
|
||||
List<CodeLabel> labels = LabelManager.GetLabels();
|
||||
List<ListViewItem> items = new List<ListViewItem>(labels.Count);
|
||||
Font italicFont = null;
|
||||
foreach(CodeLabel label in labels) {
|
||||
if(label.Label.Length > 0 || ConfigManager.Config.DebugInfo.ShowCommentsInLabelList) {
|
||||
ListViewItem item = new ListViewItem(label.Label);
|
||||
|
@ -127,18 +128,20 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
} else {
|
||||
item.SubItems.Add("[n/a]");
|
||||
item.ForeColor = Color.Gray;
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
if(italicFont == null) {
|
||||
italicFont = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
item.Font = italicFont;
|
||||
}
|
||||
string absAddress = string.Empty;
|
||||
string prefix = string.Empty;
|
||||
switch(label.AddressType) {
|
||||
case AddressType.InternalRam: absAddress += "RAM: "; break;
|
||||
case AddressType.PrgRom: absAddress += "PRG: "; break;
|
||||
case AddressType.Register: absAddress += "REG: "; break;
|
||||
case AddressType.SaveRam: absAddress += "SRAM: "; break;
|
||||
case AddressType.WorkRam: absAddress += "WRAM: "; break;
|
||||
case AddressType.InternalRam: prefix = "RAM: $"; break;
|
||||
case AddressType.PrgRom: prefix = "PRG: $"; break;
|
||||
case AddressType.Register: prefix = "REG: $"; break;
|
||||
case AddressType.SaveRam: prefix = "SRAM: $"; break;
|
||||
case AddressType.WorkRam: prefix = "WRAM: $"; break;
|
||||
}
|
||||
absAddress += "$" + label.Address.ToString("X4");
|
||||
item.SubItems.Add(absAddress);
|
||||
item.SubItems.Add(prefix + label.Address.ToString("X4"));
|
||||
item.SubItems.Add(ConfigManager.Config.DebugInfo.ShowCommentsInLabelList ? label.Comment : "");
|
||||
item.SubItems[1].Tag = label;
|
||||
|
||||
|
@ -147,25 +150,29 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
}
|
||||
}
|
||||
|
||||
_listItems = items;
|
||||
SortItems();
|
||||
|
||||
lstLabels.BeginUpdate();
|
||||
lstLabels.Items.Clear();
|
||||
lstLabels.Items.AddRange(items.ToArray());
|
||||
lstLabels.Sort();
|
||||
lstLabels.VirtualMode = true;
|
||||
lstLabels.VirtualListSize = items.Count;
|
||||
lstLabels.EndUpdate();
|
||||
|
||||
colComment.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||
if(!ConfigManager.Config.DebugInfo.ShowCommentsInLabelList) {
|
||||
colComment.Width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lstLabels.EndUpdate();
|
||||
|
||||
_listItems = items;
|
||||
private ListViewItem GetSelectedItem()
|
||||
{
|
||||
return _listItems[lstLabels.SelectedIndices[0]];
|
||||
}
|
||||
|
||||
private void lstLabels_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(lstLabels.SelectedItems.Count > 0) {
|
||||
Int32 relativeAddress = (Int32)lstLabels.SelectedItems[0].Tag;
|
||||
if(lstLabels.SelectedIndices.Count > 0) {
|
||||
Int32 relativeAddress = (Int32)GetSelectedItem().Tag;
|
||||
|
||||
if(relativeAddress >= 0) {
|
||||
OnLabelSelected?.Invoke(relativeAddress, e);
|
||||
|
@ -175,20 +182,20 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void lstLabels_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
mnuDelete.Enabled = lstLabels.SelectedItems.Count > 0;
|
||||
mnuEdit.Enabled = lstLabels.SelectedItems.Count == 1;
|
||||
mnuFindOccurrences.Enabled = lstLabels.SelectedItems.Count == 1;
|
||||
mnuAddToWatch.Enabled = lstLabels.SelectedItems.Count == 1;
|
||||
mnuAddBreakpoint.Enabled = lstLabels.SelectedItems.Count == 1;
|
||||
mnuDelete.Enabled = lstLabels.SelectedIndices.Count > 0;
|
||||
mnuEdit.Enabled = lstLabels.SelectedIndices.Count == 1;
|
||||
mnuFindOccurrences.Enabled = lstLabels.SelectedIndices.Count == 1;
|
||||
mnuAddToWatch.Enabled = lstLabels.SelectedIndices.Count == 1;
|
||||
mnuAddBreakpoint.Enabled = lstLabels.SelectedIndices.Count == 1;
|
||||
}
|
||||
|
||||
private void mnuDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstLabels.SelectedItems.Count > 0) {
|
||||
if(lstLabels.SelectedIndices.Count > 0) {
|
||||
int topIndex = lstLabels.TopItem.Index;
|
||||
int lastSelectedIndex = lstLabels.SelectedIndices[lstLabels.SelectedIndices.Count - 1];
|
||||
for(int i = lstLabels.SelectedItems.Count - 1; i >= 0; i--) {
|
||||
CodeLabel label = (CodeLabel)lstLabels.SelectedItems[i].SubItems[1].Tag;
|
||||
for(int i = lstLabels.SelectedIndices.Count - 1; i >= 0; i--) {
|
||||
CodeLabel label = (CodeLabel)GetSelectedItem().SubItems[1].Tag;
|
||||
LabelManager.DeleteLabel(label.Address, label.AddressType, i == 0);
|
||||
}
|
||||
|
||||
|
@ -201,8 +208,8 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
} else if(lstLabels.Items.Count > 0) {
|
||||
lstLabels.Items[lstLabels.Items.Count - 1].Selected = true;
|
||||
}
|
||||
if(lstLabels.SelectedItems.Count > 0) {
|
||||
lstLabels.SelectedItems[0].Focused = true;
|
||||
if(lstLabels.SelectedIndices.Count > 0) {
|
||||
GetSelectedItem().Focused = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,32 +226,32 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void mnuEdit_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstLabels.SelectedItems.Count > 0) {
|
||||
CodeLabel label = (CodeLabel)lstLabels.SelectedItems[0].SubItems[1].Tag;
|
||||
if(lstLabels.SelectedIndices.Count > 0) {
|
||||
CodeLabel label = (CodeLabel)GetSelectedItem().SubItems[1].Tag;
|
||||
EditLabel(label.Address, label.AddressType);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuFindOccurrences_Click(object sender, EventArgs e)
|
||||
{
|
||||
OnFindOccurrence?.Invoke(lstLabels.SelectedItems[0].SubItems[1].Tag, null);
|
||||
OnFindOccurrence?.Invoke(GetSelectedItem().SubItems[1].Tag, null);
|
||||
}
|
||||
|
||||
int _prevSortColumn = 0;
|
||||
bool _descSort = false;
|
||||
private void lstLabels_ColumnClick(object sender, ColumnClickEventArgs e)
|
||||
{
|
||||
if(_prevSortColumn == e.Column) {
|
||||
lstLabels.BeginUpdate();
|
||||
if(_sortColumn == e.Column) {
|
||||
_descSort = !_descSort;
|
||||
}
|
||||
lstLabels.ListViewItemSorter = new LabelComparer(e.Column, _descSort);
|
||||
_prevSortColumn = e.Column;
|
||||
_sortColumn = e.Column;
|
||||
SortItems();
|
||||
lstLabels.EndUpdate();
|
||||
}
|
||||
|
||||
private void mnuAddBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstLabels.SelectedItems.Count > 0) {
|
||||
CodeLabel label = (CodeLabel)lstLabels.SelectedItems[0].SubItems[1].Tag;
|
||||
if(lstLabels.SelectedIndices.Count > 0) {
|
||||
CodeLabel label = (CodeLabel)GetSelectedItem().SubItems[1].Tag;
|
||||
if(label.AddressType == AddressType.InternalRam || label.AddressType == AddressType.Register) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(label.Address, ref info);
|
||||
|
@ -277,8 +284,8 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void mnuAddToWatch_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstLabels.SelectedItems.Count > 0) {
|
||||
CodeLabel label = (CodeLabel)lstLabels.SelectedItems[0].SubItems[1].Tag;
|
||||
if(lstLabels.SelectedIndices.Count > 0) {
|
||||
CodeLabel label = (CodeLabel)GetSelectedItem().SubItems[1].Tag;
|
||||
WatchManager.AddWatch("[" + label.Label + "]");
|
||||
}
|
||||
}
|
||||
|
@ -289,5 +296,20 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
ConfigManager.ApplyChanges();
|
||||
this.UpdateLabelList();
|
||||
}
|
||||
|
||||
private void lstLabels_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
|
||||
{
|
||||
e.Item = _listItems[e.ItemIndex];
|
||||
}
|
||||
|
||||
private void lstLabels_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
|
||||
{
|
||||
for(int i = 0; i < _listItems.Count; i++) {
|
||||
if(_listItems[i].Text.StartsWith(e.Text, StringComparison.InvariantCultureIgnoreCase)) {
|
||||
e.Index = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -499,15 +499,17 @@ namespace Mesen.GUI.Debugger
|
|||
if(config.DbgImportComments) {
|
||||
LoadComments();
|
||||
}
|
||||
List<CodeLabel> labels = new List<CodeLabel>(_romLabels.Count + _ramLabels.Count);
|
||||
if(config.DbgImportPrgRomLabels) {
|
||||
LabelManager.SetLabels(_romLabels.Values);
|
||||
labels.AddRange(_romLabels.Values);
|
||||
labelCount += _romLabels.Count;
|
||||
}
|
||||
if(config.DbgImportRamLabels) {
|
||||
LabelManager.SetLabels(_ramLabels.Values);
|
||||
labels.AddRange(_ramLabels.Values);
|
||||
labelCount += _ramLabels.Count;
|
||||
}
|
||||
|
||||
LabelManager.SetLabels(labels);
|
||||
|
||||
if(!silent) {
|
||||
if(_errorCount > 0) {
|
||||
_errorCount -= _filesNotFound.Count;
|
||||
|
|
|
@ -50,16 +50,16 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public static void ResetLabels()
|
||||
{
|
||||
foreach(CodeLabel label in _labels.Values.ToList<CodeLabel>()) {
|
||||
DeleteLabel(label.Address, label.AddressType, false);
|
||||
}
|
||||
InteropEmu.DebugDeleteLabels();
|
||||
_labels.Clear();
|
||||
_reverseLookup.Clear();
|
||||
}
|
||||
|
||||
public static CodeLabel GetLabel(UInt32 address, AddressType type)
|
||||
{
|
||||
return _labels.ContainsKey(GetKey(address, type)) ? _labels[GetKey(address, type)] : null;
|
||||
CodeLabel label;
|
||||
_labels.TryGetValue(GetKey(address, type), out label);
|
||||
return label;
|
||||
}
|
||||
|
||||
public static CodeLabel GetLabel(UInt16 relativeAddress)
|
||||
|
@ -99,13 +99,14 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public static bool SetLabel(UInt32 address, AddressType type, string label, string comment, bool raiseEvent = true)
|
||||
{
|
||||
if(_labels.ContainsKey(GetKey(address, type))) {
|
||||
_reverseLookup.Remove(_labels[GetKey(address, type)].Label);
|
||||
string key = GetKey(address, type);
|
||||
if(_labels.ContainsKey(key)) {
|
||||
_reverseLookup.Remove(_labels[key].Label);
|
||||
}
|
||||
|
||||
_labels[GetKey(address, type)] = new CodeLabel() { Address = address, AddressType = type, Label = label, Comment = comment };
|
||||
_labels[key] = new CodeLabel() { Address = address, AddressType = type, Label = label, Comment = comment };
|
||||
if(label.Length > 0) {
|
||||
_reverseLookup[label] = _labels[GetKey(address, type)];
|
||||
_reverseLookup[label] = _labels[key];
|
||||
}
|
||||
|
||||
InteropEmu.DebugSetLabel(address, type, label, comment.Replace(Environment.NewLine, "\n"));
|
||||
|
@ -118,10 +119,11 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public static void DeleteLabel(UInt32 address, AddressType type, bool raiseEvent)
|
||||
{
|
||||
if(_labels.ContainsKey(GetKey(address, type))) {
|
||||
_reverseLookup.Remove(_labels[GetKey(address, type)].Label);
|
||||
string key = GetKey(address, type);
|
||||
if(_labels.ContainsKey(key)) {
|
||||
_reverseLookup.Remove(_labels[key].Label);
|
||||
}
|
||||
if(_labels.Remove(GetKey(address, type))) {
|
||||
if(_labels.Remove(key)) {
|
||||
InteropEmu.DebugSetLabel(address, type, string.Empty, string.Empty);
|
||||
if(raiseEvent) {
|
||||
OnLabelUpdated?.Invoke(null, null);
|
||||
|
|
|
@ -63,9 +63,13 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
int labelCount = 0;
|
||||
foreach(KeyValuePair<AddressType, Dictionary<UInt32, CodeLabel>> kvp in labels) {
|
||||
LabelManager.SetLabels(kvp.Value.Values);
|
||||
labelCount += kvp.Value.Values.Count;
|
||||
}
|
||||
List<CodeLabel> codeLabels = new List<CodeLabel>();
|
||||
foreach(KeyValuePair<AddressType, Dictionary<UInt32, CodeLabel>> kvp in labels) {
|
||||
codeLabels.AddRange(kvp.Value.Values);
|
||||
}
|
||||
LabelManager.SetLabels(codeLabels);
|
||||
|
||||
if(!silent) {
|
||||
MessageBox.Show($"Import completed with {labelCount} labels imported.", "Mesen", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
|
|
@ -209,6 +209,7 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern void DebugSetState(DebugState state);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]InteropBreakpoint[] breakpoints, UInt32 length);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetLabel(UInt32 address, AddressType addressType, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string label, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string comment);
|
||||
[DllImport(DLLPath)] public static extern void DebugDeleteLabels();
|
||||
[DllImport(DLLPath)] public static extern void DebugStep(UInt32 count);
|
||||
[DllImport(DLLPath)] public static extern void DebugPpuStep(UInt32 count);
|
||||
[DllImport(DLLPath)] public static extern void DebugStepCycles(UInt32 count);
|
||||
|
|
|
@ -39,6 +39,7 @@ extern "C"
|
|||
|
||||
DllExport void __stdcall DebugSetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->SetBreakpoints(breakpoints, length); }
|
||||
DllExport void __stdcall DebugSetLabel(uint32_t address, AddressType addressType, char* label, char* comment) { GetDebugger()->GetLabelManager()->SetLabel(address, addressType, label, comment); }
|
||||
DllExport void __stdcall DebugDeleteLabels() { GetDebugger()->GetLabelManager()->DeleteLabels(); }
|
||||
|
||||
DllExport bool __stdcall DebugIsExecutionStopped() { return GetDebugger()->IsExecutionStopped(); }
|
||||
DllExport void __stdcall DebugRun() { GetDebugger()->Run(); }
|
||||
|
|
Loading…
Add table
Reference in a new issue