mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-07-09 17:14:47 -06:00
debugger: make symbol list virtualized
This commit is contained in:
parent
25cd379aaa
commit
1263e20bae
@ -38,13 +38,12 @@ SymbolListCtrl::SymbolListCtrl(wxWindow* parent, const wxWindowID& id, const wxP
|
||||
m_list_filter.Clear();
|
||||
|
||||
OnGameLoaded();
|
||||
|
||||
SetItemCount(m_data.size());
|
||||
}
|
||||
|
||||
void SymbolListCtrl::OnGameLoaded()
|
||||
{
|
||||
m_data.clear();
|
||||
m_visible_items.clear();
|
||||
const auto symbol_map = rplSymbolStorage_lockSymbolMap();
|
||||
for (auto const& [address, symbol_info] : symbol_map)
|
||||
{
|
||||
@ -56,48 +55,30 @@ void SymbolListCtrl::OnGameLoaded()
|
||||
wxString searchNameWX = libNameWX + symbolNameWX;
|
||||
searchNameWX.MakeLower();
|
||||
|
||||
auto new_entry = m_data.try_emplace(
|
||||
symbol_info->address,
|
||||
symbolNameWX,
|
||||
m_data.try_emplace(
|
||||
address,
|
||||
symbolNameWX,
|
||||
libNameWX,
|
||||
searchNameWX,
|
||||
false
|
||||
searchNameWX
|
||||
);
|
||||
|
||||
if (m_list_filter.IsEmpty())
|
||||
new_entry.first->second.visible = true;
|
||||
else if (new_entry.first->second.searchName.Contains(m_list_filter))
|
||||
new_entry.first->second.visible = true;
|
||||
}
|
||||
rplSymbolStorage_unlockSymbolMap();
|
||||
|
||||
SetItemCount(m_data.size());
|
||||
if (m_data.size() > 0)
|
||||
RefreshItems(GetTopItem(), std::min<long>(m_data.size() - 1, GetTopItem() + GetCountPerPage() + 1));
|
||||
RebuildVisibleItems();
|
||||
}
|
||||
|
||||
wxString SymbolListCtrl::OnGetItemText(long item, long column) const
|
||||
{
|
||||
if (item >= GetItemCount())
|
||||
if (item < 0 || item >= static_cast<long>(m_visible_items.size()))
|
||||
return wxEmptyString;
|
||||
|
||||
long visible_idx = 0;
|
||||
for (const auto& [address, symbol] : m_data)
|
||||
{
|
||||
if (!symbol.visible)
|
||||
continue;
|
||||
|
||||
if (item == visible_idx)
|
||||
{
|
||||
if (column == ColumnName)
|
||||
return wxString(symbol.name);
|
||||
if (column == ColumnAddress)
|
||||
return wxString::Format("%08x", address);
|
||||
if (column == ColumnModule)
|
||||
return wxString(symbol.libName);
|
||||
}
|
||||
visible_idx++;
|
||||
}
|
||||
const auto& [address, symbol] = *m_visible_items[item];
|
||||
if (column == ColumnName)
|
||||
return symbol.name;
|
||||
if (column == ColumnAddress)
|
||||
return wxString::Format("%08x", address);
|
||||
if (column == ColumnModule)
|
||||
return symbol.libName;
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
@ -106,10 +87,9 @@ wxString SymbolListCtrl::OnGetItemText(long item, long column) const
|
||||
void SymbolListCtrl::OnLeftDClick(wxListEvent& event)
|
||||
{
|
||||
long selected = GetFirstSelected();
|
||||
if (selected == wxNOT_FOUND)
|
||||
if (selected == wxNOT_FOUND || selected >= static_cast<long>(m_visible_items.size()))
|
||||
return;
|
||||
const auto text = GetItemText(selected, ColumnAddress);
|
||||
const auto address = std::stoul(text.ToStdString(), nullptr, 16);
|
||||
const auto address = m_visible_items[selected]->first;
|
||||
if (address == 0)
|
||||
return;
|
||||
debugger_jumpToAddressInDisasm(address);
|
||||
@ -118,10 +98,9 @@ void SymbolListCtrl::OnLeftDClick(wxListEvent& event)
|
||||
void SymbolListCtrl::OnRightClick(wxListEvent& event)
|
||||
{
|
||||
long selected = GetFirstSelected();
|
||||
if (selected == wxNOT_FOUND)
|
||||
if (selected == wxNOT_FOUND || selected >= static_cast<long>(m_visible_items.size()))
|
||||
return;
|
||||
auto text = GetItemText(selected, ColumnAddress);
|
||||
text = "0x" + text;
|
||||
auto text = wxString::Format("0x%08x", m_visible_items[selected]->first);
|
||||
#if BOOST_OS_WINDOWS
|
||||
if (OpenClipboard(nullptr))
|
||||
{
|
||||
@ -140,24 +119,31 @@ void SymbolListCtrl::OnRightClick(wxListEvent& event)
|
||||
#endif
|
||||
}
|
||||
|
||||
void SymbolListCtrl::RebuildVisibleItems()
|
||||
{
|
||||
m_visible_items.clear();
|
||||
m_visible_items.reserve(m_data.size());
|
||||
const bool has_filter = !m_list_filter.IsEmpty();
|
||||
for (auto it = m_data.cbegin(); it != m_data.cend(); ++it)
|
||||
{
|
||||
if (has_filter && !it->second.searchName.Contains(m_list_filter))
|
||||
continue;
|
||||
|
||||
m_visible_items.emplace_back(it);
|
||||
}
|
||||
|
||||
SetItemCount(static_cast<long>(m_visible_items.size()));
|
||||
if (!m_visible_items.empty())
|
||||
{
|
||||
const auto top_item = std::min<long>(GetTopItem(), static_cast<long>(m_visible_items.size() - 1));
|
||||
RefreshItems(top_item, std::min<long>(static_cast<long>(m_visible_items.size() - 1), top_item + GetCountPerPage() + 1));
|
||||
}
|
||||
else
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SymbolListCtrl::ChangeListFilter(wxString filter)
|
||||
{
|
||||
m_list_filter = filter.MakeLower();
|
||||
|
||||
size_t visible_entries = m_data.size();
|
||||
for (auto& [address, symbol] : m_data)
|
||||
{
|
||||
if (m_list_filter.IsEmpty())
|
||||
symbol.visible = true;
|
||||
else if (symbol.searchName.Contains(m_list_filter))
|
||||
symbol.visible = true;
|
||||
else
|
||||
{
|
||||
visible_entries--;
|
||||
symbol.visible = false;
|
||||
}
|
||||
}
|
||||
SetItemCount(visible_entries);
|
||||
if (visible_entries > 0)
|
||||
RefreshItems(GetTopItem(), std::min<long>(visible_entries - 1, GetTopItem() + GetCountPerPage() + 1));
|
||||
RebuildVisibleItems();
|
||||
}
|
||||
|
||||
@ -10,22 +10,23 @@ public:
|
||||
|
||||
void ChangeListFilter(wxString filter);
|
||||
|
||||
private:
|
||||
private:
|
||||
struct SymbolItem {
|
||||
SymbolItem() = default;
|
||||
SymbolItem(wxString name, wxString libName, wxString searchName, bool visible) : name(name), libName(libName), searchName(searchName), visible(visible) {}
|
||||
|
||||
SymbolItem() = default;
|
||||
SymbolItem(const wxString& name, const wxString& libName, const wxString& searchName) : name(name), libName(libName), searchName(searchName) {}
|
||||
|
||||
wxString name;
|
||||
wxString libName;
|
||||
wxString searchName;
|
||||
bool visible;
|
||||
};
|
||||
using SymbolMap = std::map<MPTR, SymbolItem>;
|
||||
|
||||
std::map<MPTR, SymbolItem> m_data;
|
||||
SymbolMap m_data;
|
||||
wxString m_list_filter;
|
||||
std::vector<SymbolMap::const_iterator> m_visible_items;
|
||||
|
||||
wxString OnGetItemText(long item, long column) const;
|
||||
wxString OnGetItemText(long item, long column) const override;
|
||||
void RebuildVisibleItems();
|
||||
void OnLeftDClick(wxListEvent& event);
|
||||
void OnRightClick(wxListEvent& event);
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user