Qt: Refactor out debug controller

This commit is contained in:
Jeffrey Pfau 2016-10-26 16:41:13 -07:00
parent a0d223eef7
commit 4cb243f15c
5 changed files with 120 additions and 41 deletions

View File

@ -75,6 +75,7 @@ set(SOURCE_FILES
CheatsModel.cpp CheatsModel.cpp
CheatsView.cpp CheatsView.cpp
ConfigController.cpp ConfigController.cpp
DebuggerController.cpp
Display.cpp Display.cpp
DisplayGL.cpp DisplayGL.cpp
DisplayQt.cpp DisplayQt.cpp

View File

@ -0,0 +1,68 @@
/* Copyright (c) 2013-2014 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GDBController.h"
#include "GameController.h"
using namespace QGBA;
DebuggerController::DebuggerController(GameController* controller, mDebugger* debugger, QObject* parent)
: QObject(parent)
, m_gameController(controller)
, m_debugger(debugger)
{
}
bool DebuggerController::isAttached() {
return m_gameController->debugger() == m_debugger;
}
void DebuggerController::attach() {
if (isAttached()) {
return;
}
if (m_gameController->isLoaded()) {
m_gameController->setDebugger(m_debugger);
mDebuggerEnter(m_debugger, DEBUGGER_ENTER_ATTACHED, 0);
} else {
QObject::disconnect(m_autoattach);
m_autoattach = connect(m_gameController, SIGNAL(gameStarted(mCoreThread*, const QString&)), this, SLOT(attach()));
}
}
void DebuggerController::detach() {
QObject::disconnect(m_autoattach);
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
shutdownInternal();
m_gameController->setDebugger(nullptr);
m_gameController->threadContinue();
}
void DebuggerController::breakInto() {
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
mDebuggerEnter(m_debugger, DEBUGGER_ENTER_MANUAL, 0);
m_gameController->threadContinue();
}
void DebuggerController::shutdown() {
QObject::disconnect(m_autoattach);
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
shutdownInternal();
m_gameController->threadContinue();
}
void DebuggerController::shutdownInternal() {
// No default implementation
}

View File

@ -0,0 +1,44 @@
/* Copyright (c) 2013-2014 Jeffrey Pfau
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef QGBA_DEBUGGER_CONTROLLER
#define QGBA_DEBUGGER_CONTROLLER
#include <QObject>
struct mDebugger;
namespace QGBA {
class GameController;
class DebuggerController : public QObject {
Q_OBJECT
public:
DebuggerController(GameController* controller, mDebugger* debugger, QObject* parent = nullptr);
public:
bool isAttached();
public slots:
virtual void attach();
virtual void detach();
virtual void breakInto();
virtual void shutdown();
protected:
virtual void shutdownInternal();
mDebugger* const m_debugger;
GameController* const m_gameController;
private:
QMetaObject::Connection m_autoattach;
};
}
#endif

View File

@ -10,8 +10,7 @@
using namespace QGBA; using namespace QGBA;
GDBController::GDBController(GameController* controller, QObject* parent) GDBController::GDBController(GameController* controller, QObject* parent)
: QObject(parent) : DebuggerController(controller, &m_gdbStub.d, parent)
, m_gameController(controller)
, m_port(2345) , m_port(2345)
, m_bindAddress({ IPV4, 0 }) , m_bindAddress({ IPV4, 0 })
{ {
@ -35,30 +34,6 @@ void GDBController::setBindAddress(uint32_t bindAddress) {
m_bindAddress.ipv4 = htonl(bindAddress); m_bindAddress.ipv4 = htonl(bindAddress);
} }
void GDBController::attach() {
if (isAttached() || (m_gameController->platform() != PLATFORM_GBA && m_gameController->platform() != PLATFORM_NONE)) {
return;
}
if (m_gameController->isLoaded()) {
m_gameController->setDebugger(&m_gdbStub.d);
mDebuggerEnter(&m_gdbStub.d, DEBUGGER_ENTER_ATTACHED, 0);
} else {
QObject::disconnect(m_autoattach);
m_autoattach = connect(m_gameController, SIGNAL(gameStarted(mCoreThread*, const QString&)), this, SLOT(attach()));
}
}
void GDBController::detach() {
QObject::disconnect(m_autoattach);
if (!isAttached()) {
return;
}
m_gameController->threadInterrupt();
GDBStubShutdown(&m_gdbStub);
m_gameController->setDebugger(nullptr);
m_gameController->threadContinue();
}
void GDBController::listen() { void GDBController::listen() {
m_gameController->threadInterrupt(); m_gameController->threadInterrupt();
if (!isAttached()) { if (!isAttached()) {
@ -73,11 +48,6 @@ void GDBController::listen() {
m_gameController->threadContinue(); m_gameController->threadContinue();
} }
void GDBController::breakInto() { void GDBController::shutdownInternal() {
if (!isAttached()) { GDBStubShutdown(&m_gdbStub);
return;
}
m_gameController->threadInterrupt();
mDebuggerEnter(&m_gdbStub.d, DEBUGGER_ENTER_MANUAL, 0);
m_gameController->threadContinue();
} }

View File

@ -6,7 +6,7 @@
#ifndef QGBA_GDB_CONTROLLER #ifndef QGBA_GDB_CONTROLLER
#define QGBA_GDB_CONTROLLER #define QGBA_GDB_CONTROLLER
#include <QObject> #include "DebuggerController.h"
#ifdef USE_GDB_STUB #ifdef USE_GDB_STUB
@ -18,7 +18,7 @@ namespace QGBA {
class GameController; class GameController;
class GDBController : public QObject { class GDBController : public DebuggerController {
Q_OBJECT Q_OBJECT
public: public:
@ -31,23 +31,19 @@ public:
public slots: public slots:
void setPort(ushort port); void setPort(ushort port);
void setBindAddress(uint32_t bindAddress); void setBindAddress(uint32_t bindAddress);
void attach();
void detach();
void listen(); void listen();
void breakInto();
signals: signals:
void listening(); void listening();
void listenFailed(); void listenFailed();
private: private:
virtual void shutdownInternal() override;
GDBStub m_gdbStub; GDBStub m_gdbStub;
GameController* m_gameController;
ushort m_port; ushort m_port;
Address m_bindAddress; Address m_bindAddress;
QMetaObject::Connection m_autoattach;
}; };
} }