mirror of https://github.com/PCSX2/pcsx2.git
Debugger Threads: (Refactor) Use model based widgets
This commit is contained in:
parent
37540d1c68
commit
c00caa886e
|
@ -136,6 +136,8 @@ target_sources(pcsx2-qt PRIVATE
|
||||||
Debugger/BreakpointDialog.ui
|
Debugger/BreakpointDialog.ui
|
||||||
Debugger/Models/BreakpointModel.cpp
|
Debugger/Models/BreakpointModel.cpp
|
||||||
Debugger/Models/BreakpointModel.h
|
Debugger/Models/BreakpointModel.h
|
||||||
|
Debugger/Models/ThreadModel.cpp
|
||||||
|
Debugger/Models/ThreadModel.h
|
||||||
Tools/InputRecording/NewInputRecordingDlg.cpp
|
Tools/InputRecording/NewInputRecordingDlg.cpp
|
||||||
Tools/InputRecording/NewInputRecordingDlg.h
|
Tools/InputRecording/NewInputRecordingDlg.h
|
||||||
Tools/InputRecording/NewInputRecordingDlg.ui
|
Tools/InputRecording/NewInputRecordingDlg.ui
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "DisassemblyWidget.h"
|
#include "DisassemblyWidget.h"
|
||||||
#include "BreakpointDialog.h"
|
#include "BreakpointDialog.h"
|
||||||
#include "Models/BreakpointModel.h"
|
#include "Models/BreakpointModel.h"
|
||||||
|
#include "Models/ThreadModel.h"
|
||||||
|
|
||||||
#include "DebugTools/DebugInterface.h"
|
#include "DebugTools/DebugInterface.h"
|
||||||
#include "DebugTools/Breakpoints.h"
|
#include "DebugTools/Breakpoints.h"
|
||||||
|
@ -41,6 +42,7 @@ using namespace MipsStackWalk;
|
||||||
CpuWidget::CpuWidget(QWidget* parent, DebugInterface& cpu)
|
CpuWidget::CpuWidget(QWidget* parent, DebugInterface& cpu)
|
||||||
: m_cpu(cpu)
|
: m_cpu(cpu)
|
||||||
, m_bpModel(cpu)
|
, m_bpModel(cpu)
|
||||||
|
, m_threadModel(cpu)
|
||||||
{
|
{
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
|
@ -59,13 +61,14 @@ CpuWidget::CpuWidget(QWidget* parent, DebugInterface& cpu)
|
||||||
connect(m_ui.breakpointList, &QTableView::customContextMenuRequested, this, &CpuWidget::onBPListContextMenu);
|
connect(m_ui.breakpointList, &QTableView::customContextMenuRequested, this, &CpuWidget::onBPListContextMenu);
|
||||||
connect(m_ui.breakpointList, &QTableView::doubleClicked, this, &CpuWidget::onBPListDoubleClicked);
|
connect(m_ui.breakpointList, &QTableView::doubleClicked, this, &CpuWidget::onBPListDoubleClicked);
|
||||||
|
|
||||||
|
m_ui.breakpointList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
m_ui.breakpointList->setModel(&m_bpModel);
|
m_ui.breakpointList->setModel(&m_bpModel);
|
||||||
|
|
||||||
connect(m_ui.threadList, &QTableWidget::customContextMenuRequested, this, &CpuWidget::onThreadListContextMenu);
|
connect(m_ui.threadList, &QTableView::customContextMenuRequested, this, &CpuWidget::onThreadListContextMenu);
|
||||||
connect(m_ui.threadList, &QTableWidget::cellDoubleClicked, this, &CpuWidget::onThreadListDoubleClick);
|
connect(m_ui.threadList, &QTableView::doubleClicked, this, &CpuWidget::onThreadListDoubleClick);
|
||||||
|
|
||||||
connect(m_ui.threadList, &QTableWidget::customContextMenuRequested, this, &CpuWidget::onThreadListContextMenu);
|
m_ui.threadList->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
connect(m_ui.threadList, &QTableWidget::cellDoubleClicked, this, &CpuWidget::onThreadListDoubleClick);
|
m_ui.threadList->setModel(&m_threadModel);
|
||||||
|
|
||||||
connect(m_ui.stackframeList, &QTableWidget::customContextMenuRequested, this, &CpuWidget::onStackListContextMenu);
|
connect(m_ui.stackframeList, &QTableWidget::customContextMenuRequested, this, &CpuWidget::onStackListContextMenu);
|
||||||
connect(m_ui.stackframeList, &QTableWidget::cellDoubleClicked, this, &CpuWidget::onStackListDoubleClick);
|
connect(m_ui.stackframeList, &QTableWidget::cellDoubleClicked, this, &CpuWidget::onStackListDoubleClick);
|
||||||
|
@ -247,14 +250,11 @@ void CpuWidget::onBPListContextMenu(QPoint pos)
|
||||||
if (!m_cpu.isAlive())
|
if (!m_cpu.isAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_bplistContextMenu)
|
QMenu* contextMenu = new QMenu(tr("Breakpoint List Context Menu"), m_ui.breakpointList);
|
||||||
delete m_bplistContextMenu;
|
|
||||||
|
|
||||||
m_bplistContextMenu = new QMenu(m_ui.breakpointList);
|
|
||||||
|
|
||||||
QAction* newAction = new QAction(tr("New"), m_ui.breakpointList);
|
QAction* newAction = new QAction(tr("New"), m_ui.breakpointList);
|
||||||
connect(newAction, &QAction::triggered, this, &CpuWidget::contextBPListNew);
|
connect(newAction, &QAction::triggered, this, &CpuWidget::contextBPListNew);
|
||||||
m_bplistContextMenu->addAction(newAction);
|
contextMenu->addAction(newAction);
|
||||||
|
|
||||||
const QItemSelectionModel* selModel = m_ui.breakpointList->selectionModel();
|
const QItemSelectionModel* selModel = m_ui.breakpointList->selectionModel();
|
||||||
|
|
||||||
|
@ -262,21 +262,21 @@ void CpuWidget::onBPListContextMenu(QPoint pos)
|
||||||
{
|
{
|
||||||
QAction* editAction = new QAction(tr("Edit"), m_ui.breakpointList);
|
QAction* editAction = new QAction(tr("Edit"), m_ui.breakpointList);
|
||||||
connect(editAction, &QAction::triggered, this, &CpuWidget::contextBPListEdit);
|
connect(editAction, &QAction::triggered, this, &CpuWidget::contextBPListEdit);
|
||||||
m_bplistContextMenu->addAction(editAction);
|
contextMenu->addAction(editAction);
|
||||||
|
|
||||||
if (selModel->selectedIndexes().count() == 1)
|
if (selModel->selectedIndexes().count() == 1)
|
||||||
{
|
{
|
||||||
QAction* copyAction = new QAction(tr("Copy"), m_ui.breakpointList);
|
QAction* copyAction = new QAction(tr("Copy"), m_ui.breakpointList);
|
||||||
connect(copyAction, &QAction::triggered, this, &CpuWidget::contextBPListCopy);
|
connect(copyAction, &QAction::triggered, this, &CpuWidget::contextBPListCopy);
|
||||||
m_bplistContextMenu->addAction(copyAction);
|
contextMenu->addAction(copyAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction* deleteAction = new QAction(tr("Delete"), m_ui.breakpointList);
|
QAction* deleteAction = new QAction(tr("Delete"), m_ui.breakpointList);
|
||||||
connect(deleteAction, &QAction::triggered, this, &CpuWidget::contextBPListDelete);
|
connect(deleteAction, &QAction::triggered, this, &CpuWidget::contextBPListDelete);
|
||||||
m_bplistContextMenu->addAction(deleteAction);
|
contextMenu->addAction(deleteAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bplistContextMenu->popup(m_ui.breakpointList->mapToGlobal(pos));
|
contextMenu->popup(m_ui.breakpointList->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CpuWidget::contextBPListCopy()
|
void CpuWidget::contextBPListCopy()
|
||||||
|
@ -334,8 +334,6 @@ void CpuWidget::updateFunctionList(bool whenEmpty)
|
||||||
if (!m_cpu.isAlive())
|
if (!m_cpu.isAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_bpModel.refreshData();
|
|
||||||
|
|
||||||
if (whenEmpty && m_ui.listFunctions->count())
|
if (whenEmpty && m_ui.listFunctions->count())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -371,127 +369,41 @@ void CpuWidget::updateFunctionList(bool whenEmpty)
|
||||||
|
|
||||||
void CpuWidget::updateThreads()
|
void CpuWidget::updateThreads()
|
||||||
{
|
{
|
||||||
m_ui.threadList->setRowCount(0);
|
m_threadModel.refreshData();
|
||||||
|
|
||||||
if (m_cpu.getCpuType() == BREAKPOINT_EE)
|
|
||||||
m_threadlistObjects = getEEThreads();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_threadlistObjects.size(); i++)
|
|
||||||
{
|
|
||||||
m_ui.threadList->insertRow(i);
|
|
||||||
|
|
||||||
const auto& thread = m_threadlistObjects[i];
|
|
||||||
|
|
||||||
if (thread.data.status == THS_RUN)
|
|
||||||
m_activeThread = thread;
|
|
||||||
|
|
||||||
QTableWidgetItem* idItem = new QTableWidgetItem();
|
|
||||||
idItem->setText(QString::number(thread.tid));
|
|
||||||
idItem->setFlags(Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEnabled);
|
|
||||||
m_ui.threadList->setItem(i, 0, idItem);
|
|
||||||
|
|
||||||
QTableWidgetItem* pcItem = new QTableWidgetItem();
|
|
||||||
if (thread.data.status == THS_RUN)
|
|
||||||
pcItem->setText(FilledQStringFromValue(m_cpu.getPC(), 16));
|
|
||||||
else
|
|
||||||
pcItem->setText(FilledQStringFromValue(thread.data.entry, 16));
|
|
||||||
pcItem->setFlags(Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEnabled);
|
|
||||||
m_ui.threadList->setItem(i, 1, pcItem);
|
|
||||||
|
|
||||||
QTableWidgetItem* entryItem = new QTableWidgetItem();
|
|
||||||
entryItem->setText(FilledQStringFromValue(thread.data.entry_init, 16));
|
|
||||||
entryItem->setFlags(Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEnabled);
|
|
||||||
m_ui.threadList->setItem(i, 2, entryItem);
|
|
||||||
|
|
||||||
QTableWidgetItem* priorityItem = new QTableWidgetItem();
|
|
||||||
priorityItem->setText(QString::number(thread.data.currentPriority));
|
|
||||||
priorityItem->setFlags(Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEnabled);
|
|
||||||
m_ui.threadList->setItem(i, 3, priorityItem);
|
|
||||||
|
|
||||||
QString statusString;
|
|
||||||
switch (thread.data.status)
|
|
||||||
{
|
|
||||||
case THS_BAD:
|
|
||||||
statusString = tr("Bad");
|
|
||||||
break;
|
|
||||||
case THS_RUN:
|
|
||||||
statusString = tr("Running");
|
|
||||||
break;
|
|
||||||
case THS_READY:
|
|
||||||
statusString = tr("Ready");
|
|
||||||
break;
|
|
||||||
case THS_WAIT:
|
|
||||||
statusString = tr("Waiting");
|
|
||||||
break;
|
|
||||||
case THS_SUSPEND:
|
|
||||||
statusString = tr("Suspended");
|
|
||||||
break;
|
|
||||||
case THS_WAIT_SUSPEND:
|
|
||||||
statusString = tr("Waiting/Suspended");
|
|
||||||
break;
|
|
||||||
case THS_DORMANT:
|
|
||||||
statusString = tr("Dormant");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTableWidgetItem* statusItem = new QTableWidgetItem();
|
|
||||||
statusItem->setText(statusString);
|
|
||||||
statusItem->setFlags(Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEnabled);
|
|
||||||
m_ui.threadList->setItem(i, 4, statusItem);
|
|
||||||
|
|
||||||
QString waitTypeString;
|
|
||||||
switch (thread.data.waitType)
|
|
||||||
{
|
|
||||||
case WAIT_NONE:
|
|
||||||
waitTypeString = tr("None");
|
|
||||||
break;
|
|
||||||
case WAIT_WAKEUP_REQ:
|
|
||||||
waitTypeString = tr("Wakeup request");
|
|
||||||
break;
|
|
||||||
case WAIT_SEMA:
|
|
||||||
waitTypeString = tr("Semaphore");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTableWidgetItem* waitItem = new QTableWidgetItem();
|
|
||||||
waitItem->setText(waitTypeString);
|
|
||||||
waitItem->setFlags(Qt::ItemFlag::ItemIsSelectable | Qt::ItemFlag::ItemIsEnabled);
|
|
||||||
m_ui.threadList->setItem(i, 5, waitItem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CpuWidget::onThreadListContextMenu(QPoint pos)
|
void CpuWidget::onThreadListContextMenu(QPoint pos)
|
||||||
{
|
{
|
||||||
if (!m_threadlistContextMenu)
|
if (!m_ui.threadList->selectionModel()->hasSelection())
|
||||||
{
|
return;
|
||||||
m_threadlistContextMenu = new QMenu(m_ui.threadList);
|
|
||||||
|
|
||||||
QAction* copyAction = new QAction(tr("Copy"), m_ui.threadList);
|
QMenu* contextMenu = new QMenu(tr("Thread List Context Menu"), m_ui.threadList);
|
||||||
connect(copyAction, &QAction::triggered, [this] {
|
|
||||||
const auto& items = m_ui.threadList->selectedItems();
|
|
||||||
if (!items.size())
|
|
||||||
return;
|
|
||||||
QApplication::clipboard()->setText(items.first()->text());
|
|
||||||
});
|
|
||||||
m_threadlistContextMenu->addAction(copyAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_threadlistContextMenu->exec(m_ui.threadList->mapToGlobal(pos));
|
QAction* actionCopy = new QAction(tr("Copy"), m_ui.threadList);
|
||||||
|
connect(actionCopy, &QAction::triggered, [this]() {
|
||||||
|
const auto* selModel = m_ui.threadList->selectionModel();
|
||||||
|
|
||||||
|
if (!selModel->hasSelection())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QGuiApplication::clipboard()->setText(m_ui.threadList->model()->data(selModel->currentIndex()).toString());
|
||||||
|
});
|
||||||
|
contextMenu->addAction(actionCopy);
|
||||||
|
|
||||||
|
contextMenu->popup(m_ui.threadList->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CpuWidget::onThreadListDoubleClick(int row, int column)
|
void CpuWidget::onThreadListDoubleClick(const QModelIndex& index)
|
||||||
{
|
{
|
||||||
const auto& entry = m_threadlistObjects.at(row);
|
switch (index.column())
|
||||||
if (column == 1) // PC
|
|
||||||
{
|
{
|
||||||
if (entry.data.status == THS_RUN)
|
case ThreadModel::ThreadColumns::ENTRY:
|
||||||
m_ui.disassemblyWidget->gotoAddress(m_cpu.getPC());
|
m_ui.memoryviewWidget->gotoAddress(m_ui.threadList->model()->data(index, Qt::UserRole).toUInt());
|
||||||
else
|
m_ui.tabWidget->setCurrentWidget(m_ui.tab_memory);
|
||||||
m_ui.disassemblyWidget->gotoAddress(entry.data.entry);
|
break;
|
||||||
}
|
default: // Default to PC
|
||||||
else if (column == 2) // Entry Point
|
m_ui.disassemblyWidget->gotoAddress(m_ui.threadList->model()->data(m_ui.threadList->model()->index(index.row(), ThreadModel::ThreadColumns::PC), Qt::UserRole).toUInt());
|
||||||
{
|
break;
|
||||||
m_ui.disassemblyWidget->gotoAddress(entry.data.entry_init);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "DebugTools/MipsStackWalk.h"
|
#include "DebugTools/MipsStackWalk.h"
|
||||||
|
|
||||||
#include "Models/BreakpointModel.h"
|
#include "Models/BreakpointModel.h"
|
||||||
|
#include "Models/ThreadModel.h"
|
||||||
|
|
||||||
#include "QtHost.h"
|
#include "QtHost.h"
|
||||||
#include <QtWidgets/QWidget>
|
#include <QtWidgets/QWidget>
|
||||||
|
@ -50,7 +51,6 @@ public slots:
|
||||||
void onVMPaused();
|
void onVMPaused();
|
||||||
|
|
||||||
void updateBreakpoints();
|
void updateBreakpoints();
|
||||||
|
|
||||||
void onBPListDoubleClicked(const QModelIndex& index);
|
void onBPListDoubleClicked(const QModelIndex& index);
|
||||||
void onBPListContextMenu(QPoint pos);
|
void onBPListContextMenu(QPoint pos);
|
||||||
|
|
||||||
|
@ -60,8 +60,8 @@ public slots:
|
||||||
void contextBPListEdit();
|
void contextBPListEdit();
|
||||||
|
|
||||||
void updateThreads();
|
void updateThreads();
|
||||||
|
void onThreadListDoubleClick(const QModelIndex& index);
|
||||||
void onThreadListContextMenu(QPoint pos);
|
void onThreadListContextMenu(QPoint pos);
|
||||||
void onThreadListDoubleClick(int row, int column);
|
|
||||||
|
|
||||||
void updateStackFrames();
|
void updateStackFrames();
|
||||||
void onStackListContextMenu(QPoint pos);
|
void onStackListContextMenu(QPoint pos);
|
||||||
|
@ -93,8 +93,6 @@ public slots:
|
||||||
private:
|
private:
|
||||||
std::vector<QTableWidget*> m_registerTableViews;
|
std::vector<QTableWidget*> m_registerTableViews;
|
||||||
|
|
||||||
QMenu* m_bplistContextMenu = 0;
|
|
||||||
QMenu* m_threadlistContextMenu = 0;
|
|
||||||
QMenu* m_stacklistContextMenu = 0;
|
QMenu* m_stacklistContextMenu = 0;
|
||||||
QMenu* m_funclistContextMenu = 0;
|
QMenu* m_funclistContextMenu = 0;
|
||||||
|
|
||||||
|
@ -103,6 +101,7 @@ private:
|
||||||
DebugInterface& m_cpu;
|
DebugInterface& m_cpu;
|
||||||
|
|
||||||
BreakpointModel m_bpModel;
|
BreakpointModel m_bpModel;
|
||||||
|
ThreadModel m_threadModel;
|
||||||
|
|
||||||
std::vector<EEThread> m_threadlistObjects;
|
std::vector<EEThread> m_threadlistObjects;
|
||||||
EEThread m_activeThread;
|
EEThread m_activeThread;
|
||||||
|
|
|
@ -322,7 +322,7 @@
|
||||||
<enum>QTabWidget::South</enum>
|
<enum>QTabWidget::South</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab_memory">
|
<widget class="QWidget" name="tab_memory">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -438,7 +438,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTableWidget" name="threadList">
|
<widget class="QTableView" name="threadList">
|
||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -451,48 +451,6 @@
|
||||||
<property name="cornerButtonEnabled">
|
<property name="cornerButtonEnabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="rowCount">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="columnCount">
|
|
||||||
<number>6</number>
|
|
||||||
</property>
|
|
||||||
<attribute name="horizontalHeaderStretchLastSection">
|
|
||||||
<bool>true</bool>
|
|
||||||
</attribute>
|
|
||||||
<attribute name="verticalHeaderVisible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>ID</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>PC</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Entry Point</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Priority</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>State</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
<column>
|
|
||||||
<property name="text">
|
|
||||||
<string>Wait Type</string>
|
|
||||||
</property>
|
|
||||||
</column>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -734,4 +734,5 @@ void DisassemblyWidget::gotoAddress(u32 address)
|
||||||
m_selectedAddressEnd = destAddress;
|
m_selectedAddressEnd = destAddress;
|
||||||
|
|
||||||
this->repaint();
|
this->repaint();
|
||||||
|
this->setFocus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,4 +500,5 @@ void MemoryViewWidget::gotoAddress(u32 address)
|
||||||
m_table.UpdateStartAddress(address & ~0xF);
|
m_table.UpdateStartAddress(address & ~0xF);
|
||||||
m_table.selectedAddress = address;
|
m_table.selectedAddress = address;
|
||||||
this->repaint();
|
this->repaint();
|
||||||
|
this->setFocus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
bool insertRows(int row, int count, std::vector<BreakpointMemcheck> breakpoints, const QModelIndex& index = QModelIndex());
|
bool insertRows(int row, int count, std::vector<BreakpointMemcheck> breakpoints, const QModelIndex& index = QModelIndex());
|
||||||
|
|
||||||
BreakpointMemcheck at(int row) const { return m_breakpoints.at(row); };
|
BreakpointMemcheck at(int row) const { return m_breakpoints.at(row); };
|
||||||
public slots:
|
|
||||||
void refreshData();
|
void refreshData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||||
|
*
|
||||||
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
|
* ation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "PrecompiledHeader.h"
|
||||||
|
|
||||||
|
#include "ThreadModel.h"
|
||||||
|
|
||||||
|
#include "QtUtils.h"
|
||||||
|
|
||||||
|
ThreadModel::ThreadModel(DebugInterface& cpu, QObject* parent)
|
||||||
|
: QAbstractTableModel(parent)
|
||||||
|
, m_cpu(cpu)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ThreadModel::rowCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
if (m_cpu.getCpuType() == BREAKPOINT_EE)
|
||||||
|
{
|
||||||
|
Console.Warning("%d", getEEThreads().size());
|
||||||
|
return getEEThreads().size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ThreadModel::columnCount(const QModelIndex&) const
|
||||||
|
{
|
||||||
|
return ThreadModel::COLUMN_COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ThreadModel::data(const QModelIndex& index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
const auto thread = getEEThreads().at(index.row());
|
||||||
|
|
||||||
|
switch (index.column())
|
||||||
|
{
|
||||||
|
case ThreadModel::ID:
|
||||||
|
return thread.tid;
|
||||||
|
case ThreadModel::PC:
|
||||||
|
{
|
||||||
|
if (thread.data.status == THS_RUN)
|
||||||
|
return QtUtils::FilledQStringFromValue(m_cpu.getPC(), 16);
|
||||||
|
else
|
||||||
|
return QtUtils::FilledQStringFromValue(thread.data.entry, 16);
|
||||||
|
}
|
||||||
|
case ThreadModel::ENTRY:
|
||||||
|
return QtUtils::FilledQStringFromValue(thread.data.entry_init, 16);
|
||||||
|
case ThreadModel::PRIORITY:
|
||||||
|
return QString::number(thread.data.currentPriority);
|
||||||
|
case ThreadModel::STATE:
|
||||||
|
{
|
||||||
|
const auto& state = ThreadStateStrings.find(thread.data.status);
|
||||||
|
if (state != ThreadStateStrings.end())
|
||||||
|
return state->second;
|
||||||
|
else
|
||||||
|
return tr("INVALID");
|
||||||
|
}
|
||||||
|
case ThreadModel::WAIT_TYPE:
|
||||||
|
{
|
||||||
|
const auto& waitType = ThreadWaitStrings.find(thread.data.waitType);
|
||||||
|
if (waitType != ThreadWaitStrings.end())
|
||||||
|
return waitType->second;
|
||||||
|
else
|
||||||
|
return tr("INVALID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (role == Qt::UserRole)
|
||||||
|
{
|
||||||
|
const auto& thread = getEEThreads().at(index.row());
|
||||||
|
|
||||||
|
switch (index.column())
|
||||||
|
{
|
||||||
|
case ThreadModel::ID:
|
||||||
|
return thread.tid;
|
||||||
|
case ThreadModel::PC:
|
||||||
|
{
|
||||||
|
if (thread.data.status == THS_RUN)
|
||||||
|
return m_cpu.getPC();
|
||||||
|
else
|
||||||
|
return thread.data.entry;
|
||||||
|
}
|
||||||
|
case ThreadModel::ENTRY:
|
||||||
|
return thread.data.entry_init;
|
||||||
|
case ThreadModel::PRIORITY:
|
||||||
|
return thread.data.currentPriority;
|
||||||
|
case ThreadModel::STATE:
|
||||||
|
return thread.data.status;
|
||||||
|
case ThreadModel::WAIT_TYPE:
|
||||||
|
return thread.data.waitType;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant ThreadModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
||||||
|
{
|
||||||
|
switch (section)
|
||||||
|
{
|
||||||
|
case ThreadColumns::ID:
|
||||||
|
return tr("ID");
|
||||||
|
case ThreadColumns::PC:
|
||||||
|
return tr("PC");
|
||||||
|
case ThreadColumns::ENTRY:
|
||||||
|
return tr("ENTRY");
|
||||||
|
case ThreadColumns::PRIORITY:
|
||||||
|
return tr("PRIORITY");
|
||||||
|
case ThreadColumns::STATE:
|
||||||
|
return tr("STATE");
|
||||||
|
case ThreadColumns::WAIT_TYPE:
|
||||||
|
return tr("WAIT TYPE");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadModel::refreshData()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
endResetModel();
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* PCSX2 - PS2 Emulator for PCs
|
||||||
|
* Copyright (C) 2002-2023 PCSX2 Dev Team
|
||||||
|
*
|
||||||
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||||
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||||
|
* ation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE. See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QAbstractTableModel>
|
||||||
|
|
||||||
|
#include "DebugTools/DebugInterface.h"
|
||||||
|
#include "DebugTools/BiosDebugData.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class ThreadModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ThreadColumns : int
|
||||||
|
{
|
||||||
|
ID = 0,
|
||||||
|
PC,
|
||||||
|
ENTRY,
|
||||||
|
PRIORITY,
|
||||||
|
STATE,
|
||||||
|
WAIT_TYPE,
|
||||||
|
COLUMN_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit ThreadModel(DebugInterface& cpu, QObject* parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
|
||||||
|
void refreshData();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::map<int, QString> ThreadStateStrings{
|
||||||
|
{THS_BAD, tr("BAD")},
|
||||||
|
{THS_RUN, tr("RUN")},
|
||||||
|
{THS_READY, tr("READY")},
|
||||||
|
{THS_WAIT, tr("WAIT")},
|
||||||
|
{THS_SUSPEND, tr("SUSPEND")},
|
||||||
|
{THS_WAIT_SUSPEND, tr("WAIT SUSPEND")},
|
||||||
|
{THS_DORMANT, tr("DORMANT")}};
|
||||||
|
|
||||||
|
const std::map<int, QString> ThreadWaitStrings{
|
||||||
|
{WAIT_NONE, tr("NONE")},
|
||||||
|
{WAIT_WAKEUP_REQ, tr("WAKEUP REQUEST")},
|
||||||
|
{WAIT_SEMA, tr("SEMAPHORE")}};
|
||||||
|
|
||||||
|
DebugInterface& m_cpu;
|
||||||
|
};
|
|
@ -149,6 +149,7 @@
|
||||||
<ClCompile Include="Debugger\RegisterWidget.cpp" />
|
<ClCompile Include="Debugger\RegisterWidget.cpp" />
|
||||||
<ClCompile Include="Debugger\BreakpointDialog.cpp" />
|
<ClCompile Include="Debugger\BreakpointDialog.cpp" />
|
||||||
<ClCompile Include="Debugger\Models\BreakpointModel.cpp" />
|
<ClCompile Include="Debugger\Models\BreakpointModel.cpp" />
|
||||||
|
<ClCompile Include="Debugger\Models\ThreadModel.cpp" />
|
||||||
<ClCompile Include="Settings\BIOSSettingsWidget.cpp" />
|
<ClCompile Include="Settings\BIOSSettingsWidget.cpp" />
|
||||||
<ClCompile Include="Settings\ControllerBindingWidgets.cpp" />
|
<ClCompile Include="Settings\ControllerBindingWidgets.cpp" />
|
||||||
<ClCompile Include="Settings\ControllerGlobalSettingsWidget.cpp" />
|
<ClCompile Include="Settings\ControllerGlobalSettingsWidget.cpp" />
|
||||||
|
@ -230,6 +231,7 @@
|
||||||
<QtMoc Include="Debugger\RegisterWidget.h" />
|
<QtMoc Include="Debugger\RegisterWidget.h" />
|
||||||
<QtMoc Include="Debugger\BreakpointDialog.h" />
|
<QtMoc Include="Debugger\BreakpointDialog.h" />
|
||||||
<QtMoc Include="Debugger\Models\BreakpointModel.h" />
|
<QtMoc Include="Debugger\Models\BreakpointModel.h" />
|
||||||
|
<QtMoc Include="Debugger\Models\ThreadModel.h" />
|
||||||
<QtMoc Include="Settings\ControllerBindingWidgets.h" />
|
<QtMoc Include="Settings\ControllerBindingWidgets.h" />
|
||||||
<QtMoc Include="Settings\ControllerGlobalSettingsWidget.h" />
|
<QtMoc Include="Settings\ControllerGlobalSettingsWidget.h" />
|
||||||
<ClInclude Include="Settings\MemoryCardConvertWorker.h" />
|
<ClInclude Include="Settings\MemoryCardConvertWorker.h" />
|
||||||
|
@ -281,6 +283,7 @@
|
||||||
<ClCompile Include="$(IntDir)Debugger\moc_MemoryViewWidget.cpp" />
|
<ClCompile Include="$(IntDir)Debugger\moc_MemoryViewWidget.cpp" />
|
||||||
<ClCompile Include="$(IntDir)Debugger\moc_BreakpointDialog.cpp" />
|
<ClCompile Include="$(IntDir)Debugger\moc_BreakpointDialog.cpp" />
|
||||||
<ClCompile Include="$(IntDir)Debugger\Models\moc_BreakpointModel.cpp" />
|
<ClCompile Include="$(IntDir)Debugger\Models\moc_BreakpointModel.cpp" />
|
||||||
|
<ClCompile Include="$(IntDir)Debugger\Models\moc_ThreadModel.cpp" />
|
||||||
<ClCompile Include="$(IntDir)GameList\moc_GameListModel.cpp" />
|
<ClCompile Include="$(IntDir)GameList\moc_GameListModel.cpp" />
|
||||||
<ClCompile Include="$(IntDir)GameList\moc_GameListRefreshThread.cpp" />
|
<ClCompile Include="$(IntDir)GameList\moc_GameListRefreshThread.cpp" />
|
||||||
<ClCompile Include="$(IntDir)GameList\moc_GameListWidget.cpp" />
|
<ClCompile Include="$(IntDir)GameList\moc_GameListWidget.cpp" />
|
||||||
|
|
|
@ -280,6 +280,9 @@
|
||||||
<ClCompile Include="Debugger\Models\BreakpointModel.cpp">
|
<ClCompile Include="Debugger\Models\BreakpointModel.cpp">
|
||||||
<Filter>Debugger\Models</Filter>
|
<Filter>Debugger\Models</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Debugger\Models\ThreadModel.cpp">
|
||||||
|
<Filter>Debugger\Models</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="$(IntDir)Debugger\moc_CpuWidget.cpp">
|
<ClCompile Include="$(IntDir)Debugger\moc_CpuWidget.cpp">
|
||||||
<Filter>moc</Filter>
|
<Filter>moc</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -301,6 +304,9 @@
|
||||||
<ClCompile Include="$(IntDir)Debugger\Models\moc_BreakpointModel.cpp">
|
<ClCompile Include="$(IntDir)Debugger\Models\moc_BreakpointModel.cpp">
|
||||||
<Filter>moc</Filter>
|
<Filter>moc</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="$(IntDir)Debugger\Models\moc_ThreadModel.cpp">
|
||||||
|
<Filter>moc</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
|
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
|
||||||
|
@ -441,6 +447,9 @@
|
||||||
<QtMoc Include="Debugger\Models\BreakpointModel.h">
|
<QtMoc Include="Debugger\Models\BreakpointModel.h">
|
||||||
<Filter>Debugger\Models</Filter>
|
<Filter>Debugger\Models</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
|
<QtMoc Include="Debugger\Models\ThreadModel.h">
|
||||||
|
<Filter>Debugger\Models</Filter>
|
||||||
|
</QtMoc>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtResource Include="resources\resources.qrc">
|
<QtResource Include="resources\resources.qrc">
|
||||||
|
|
Loading…
Reference in New Issue