pcsx2/pcsx2-qt/Debugger/Docking/DockTables.cpp

213 lines
7.6 KiB
C++

// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "DockTables.h"
#include "Debugger/DebuggerEvents.h"
#include "Debugger/DisassemblyView.h"
#include "Debugger/ModuleView.h"
#include "Debugger/RegisterView.h"
#include "Debugger/StackView.h"
#include "Debugger/ThreadView.h"
#include "Debugger/Breakpoints/BreakpointView.h"
#include "Debugger/Memory/MemorySearchView.h"
#include "Debugger/Memory/MemoryView.h"
#include "Debugger/Memory/SavedAddressesView.h"
#include "Debugger/SymbolTree/SymbolTreeViews.h"
using namespace DockUtils;
static void hashDefaultLayout(const DockTables::DefaultDockLayout& layout, u32& hash);
static void hashDefaultGroup(const DockTables::DefaultDockGroupDescription& group, u32& hash);
static void hashDefaultDockWidget(const DockTables::DefaultDockWidgetDescription& widget, u32& hash);
static void hashNumber(u32 number, u32& hash);
static void hashString(const char* string, u32& hash);
#define DEBUGGER_VIEW(type, display_name, preferred_location) \
{ \
#type, \
{ \
[](const DebuggerViewParameters& parameters) -> DebuggerView* { \
DebuggerView* widget = new type(parameters); \
widget->handleEvent(DebuggerEvents::Refresh()); \
return widget; \
}, \
display_name, \
preferred_location \
} \
}
const std::map<std::string, DockTables::DebuggerViewDescription> DockTables::DEBUGGER_VIEWS = {
DEBUGGER_VIEW(BreakpointView, QT_TRANSLATE_NOOP("DebuggerView", "Breakpoints"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(DisassemblyView, QT_TRANSLATE_NOOP("DebuggerView", "Disassembly"), TOP_RIGHT),
DEBUGGER_VIEW(FunctionTreeView, QT_TRANSLATE_NOOP("DebuggerView", "Functions"), TOP_LEFT),
DEBUGGER_VIEW(GlobalVariableTreeView, QT_TRANSLATE_NOOP("DebuggerView", "Globals"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(LocalVariableTreeView, QT_TRANSLATE_NOOP("DebuggerView", "Locals"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(MemorySearchView, QT_TRANSLATE_NOOP("DebuggerView", "Memory Search"), TOP_LEFT),
DEBUGGER_VIEW(MemoryView, QT_TRANSLATE_NOOP("DebuggerView", "Memory"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(ModuleView, QT_TRANSLATE_NOOP("DebuggerView", "Modules"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(ParameterVariableTreeView, QT_TRANSLATE_NOOP("DebuggerView", "Parameters"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(RegisterView, QT_TRANSLATE_NOOP("DebuggerView", "Registers"), TOP_LEFT),
DEBUGGER_VIEW(SavedAddressesView, QT_TRANSLATE_NOOP("DebuggerView", "Saved Addresses"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(StackView, QT_TRANSLATE_NOOP("DebuggerView", "Stack"), BOTTOM_MIDDLE),
DEBUGGER_VIEW(ThreadView, QT_TRANSLATE_NOOP("DebuggerView", "Threads"), BOTTOM_MIDDLE),
};
#undef DEBUGGER_VIEW
const std::vector<DockTables::DefaultDockLayout> DockTables::DEFAULT_DOCK_LAYOUTS = {
{
.name = QT_TRANSLATE_NOOP("DebuggerLayout", "R5900"),
.cpu = BREAKPOINT_EE,
.groups = {
/* [DefaultDockGroup::TOP_RIGHT] = */ {KDDockWidgets::Location_OnRight, DefaultDockGroup::ROOT},
/* [DefaultDockGroup::BOTTOM] = */ {KDDockWidgets::Location_OnBottom, DefaultDockGroup::TOP_RIGHT},
/* [DefaultDockGroup::TOP_LEFT] = */ {KDDockWidgets::Location_OnLeft, DefaultDockGroup::TOP_RIGHT},
},
.widgets = {
/* DefaultDockGroup::TOP_RIGHT */
{"DisassemblyView", DefaultDockGroup::TOP_RIGHT},
/* DefaultDockGroup::BOTTOM */
{"MemoryView", DefaultDockGroup::BOTTOM},
{"BreakpointView", DefaultDockGroup::BOTTOM},
{"ThreadView", DefaultDockGroup::BOTTOM},
{"StackView", DefaultDockGroup::BOTTOM},
{"SavedAddressesView", DefaultDockGroup::BOTTOM},
{"GlobalVariableTreeView", DefaultDockGroup::BOTTOM},
{"LocalVariableTreeView", DefaultDockGroup::BOTTOM},
{"ParameterVariableTreeView", DefaultDockGroup::BOTTOM},
/* DefaultDockGroup::TOP_LEFT */
{"RegisterView", DefaultDockGroup::TOP_LEFT},
{"FunctionTreeView", DefaultDockGroup::TOP_LEFT},
{"MemorySearchView", DefaultDockGroup::TOP_LEFT},
},
.toolbars = {
"toolBarDebug",
"toolBarFile",
},
},
{
.name = QT_TRANSLATE_NOOP("DebuggerLayout", "R3000"),
.cpu = BREAKPOINT_IOP,
.groups = {
/* [DefaultDockGroup::TOP_RIGHT] = */ {KDDockWidgets::Location_OnRight, DefaultDockGroup::ROOT},
/* [DefaultDockGroup::BOTTOM] = */ {KDDockWidgets::Location_OnBottom, DefaultDockGroup::TOP_RIGHT},
/* [DefaultDockGroup::TOP_LEFT] = */ {KDDockWidgets::Location_OnLeft, DefaultDockGroup::TOP_RIGHT},
},
.widgets = {
/* DefaultDockGroup::TOP_RIGHT */
{"DisassemblyView", DefaultDockGroup::TOP_RIGHT},
/* DefaultDockGroup::BOTTOM */
{"MemoryView", DefaultDockGroup::BOTTOM},
{"BreakpointView", DefaultDockGroup::BOTTOM},
{"ThreadView", DefaultDockGroup::BOTTOM},
{"ModuleView", DefaultDockGroup::BOTTOM},
{"StackView", DefaultDockGroup::BOTTOM},
{"SavedAddressesView", DefaultDockGroup::BOTTOM},
{"GlobalVariableTreeView", DefaultDockGroup::BOTTOM},
{"LocalVariableTreeView", DefaultDockGroup::BOTTOM},
{"ParameterVariableTreeView", DefaultDockGroup::BOTTOM},
/* DefaultDockGroup::TOP_LEFT */
{"RegisterView", DefaultDockGroup::TOP_LEFT},
{"FunctionTreeView", DefaultDockGroup::TOP_LEFT},
{"MemorySearchView", DefaultDockGroup::TOP_LEFT},
},
.toolbars = {
"toolBarDebug",
"toolBarFile",
},
},
};
const DockTables::DefaultDockLayout* DockTables::defaultLayout(const std::string& name)
{
for (const DockTables::DefaultDockLayout& default_layout : DockTables::DEFAULT_DOCK_LAYOUTS)
if (default_layout.name == name)
return &default_layout;
return nullptr;
}
u32 DockTables::hashDefaultLayouts()
{
static std::optional<u32> hash;
if (hash.has_value())
return *hash;
hash.emplace(0);
u32 hash_version = 2;
hashNumber(hash_version, *hash);
hashNumber(static_cast<u32>(DEFAULT_DOCK_LAYOUTS.size()), *hash);
for (const DefaultDockLayout& layout : DEFAULT_DOCK_LAYOUTS)
hashDefaultLayout(layout, *hash);
return *hash;
}
static void hashDefaultLayout(const DockTables::DefaultDockLayout& layout, u32& hash)
{
hashString(layout.name.c_str(), hash);
hashString(DebugInterface::cpuName(layout.cpu), hash);
hashNumber(static_cast<u32>(layout.groups.size()), hash);
for (const DockTables::DefaultDockGroupDescription& group : layout.groups)
hashDefaultGroup(group, hash);
hashNumber(static_cast<u32>(layout.widgets.size()), hash);
for (const DockTables::DefaultDockWidgetDescription& widget : layout.widgets)
hashDefaultDockWidget(widget, hash);
hashNumber(static_cast<u32>(layout.toolbars.size()), hash);
for (const std::string& toolbar : layout.toolbars)
hashString(toolbar.c_str(), hash);
}
static void hashDefaultGroup(const DockTables::DefaultDockGroupDescription& group, u32& hash)
{
// This is inline here so that it's obvious that changing it will affect the
// result of the hash.
const char* location = "";
switch (group.location)
{
case KDDockWidgets::Location_None:
location = "none";
break;
case KDDockWidgets::Location_OnLeft:
location = "left";
break;
case KDDockWidgets::Location_OnTop:
location = "top";
break;
case KDDockWidgets::Location_OnRight:
location = "right";
break;
case KDDockWidgets::Location_OnBottom:
location = "bottom";
break;
}
hashString(location, hash);
hashNumber(static_cast<u32>(group.parent), hash);
}
static void hashDefaultDockWidget(const DockTables::DefaultDockWidgetDescription& widget, u32& hash)
{
hashString(widget.type.c_str(), hash);
hashNumber(static_cast<u32>(widget.group), hash);
}
static void hashNumber(u32 number, u32& hash)
{
hash = hash * 31 + number;
}
static void hashString(const char* string, u32& hash)
{
u32 size = static_cast<u32>(strlen(string));
hash = hash * 31 + size;
for (u32 i = 0; i < size; i++)
hash = hash * 31 + string[i];
}