all repos — mgba @ 7d009ec43c0ce59903643913609bc7766f3cb7fb

mGBA Game Boy Advance Emulator

Qt: Add GameController::Interrupter
Jeffrey Pfau jeffrey@endrift.com
Wed, 26 Oct 2016 17:35:18 -0700
commit

7d009ec43c0ce59903643913609bc7766f3cb7fb

parent

4cb243f15c011264e3b4e84100f6e4a050c4a623

M src/platform/qt/CheatsView.cppsrc/platform/qt/CheatsView.cpp

@@ -125,10 +125,9 @@ }

} void CheatsView::addSet() { - m_controller->threadInterrupt(); + GameController::Interrupter interrupter(m_controller); mCheatSet* set = m_controller->cheatDevice()->createSet(m_controller->cheatDevice(), nullptr); m_model.addSet(set); - m_controller->threadContinue(); } void CheatsView::removeSet() {

@@ -137,11 +136,10 @@ QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes();

if (selection.count() < 1) { return; } - m_controller->threadInterrupt(); + GameController::Interrupter interrupter(m_controller); for (const QModelIndex& index : selection) { m_model.removeAt(selection[0]); } - m_controller->threadContinue(); } void CheatsView::enterCheat(int codeType) {
M src/platform/qt/DebuggerController.cppsrc/platform/qt/DebuggerController.cpp

@@ -38,19 +38,17 @@ QObject::disconnect(m_autoattach);

if (!isAttached()) { return; } - m_gameController->threadInterrupt(); + GameController::Interrupter interrupter(m_gameController); shutdownInternal(); m_gameController->setDebugger(nullptr); - m_gameController->threadContinue(); } void DebuggerController::breakInto() { if (!isAttached()) { return; } - m_gameController->threadInterrupt(); + GameController::Interrupter interrupter(m_gameController); mDebuggerEnter(m_debugger, DEBUGGER_ENTER_MANUAL, 0); - m_gameController->threadContinue(); } void DebuggerController::shutdown() {

@@ -58,9 +56,8 @@ QObject::disconnect(m_autoattach);

if (!isAttached()) { return; } - m_gameController->threadInterrupt(); + GameController::Interrupter interrupter(m_gameController); shutdownInternal(); - m_gameController->threadContinue(); } void DebuggerController::shutdownInternal() {
M src/platform/qt/GDBController.cppsrc/platform/qt/GDBController.cpp

@@ -35,7 +35,7 @@ m_bindAddress.ipv4 = htonl(bindAddress);

} void GDBController::listen() { - m_gameController->threadInterrupt(); + GameController::Interrupter interrupter(m_gameController); if (!isAttached()) { attach(); }

@@ -45,7 +45,6 @@ } else {

detach(); emit listenFailed(); } - m_gameController->threadContinue(); } void GDBController::shutdownInternal() {
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -320,9 +320,8 @@

void GameController::setOverride(Override* override) { m_override = override; if (isLoaded()) { - threadInterrupt(); + Interrupter interrupter(this); m_override->identify(m_threadContext.core); - threadContinue(); } }

@@ -334,10 +333,9 @@

void GameController::setConfig(const mCoreConfig* config) { m_config = config; if (isLoaded()) { - threadInterrupt(); + Interrupter interrupter(this); mCoreLoadForeignConfig(m_threadContext.core, config); m_audioProcessor->setInput(&m_threadContext); - threadContinue(); } }

@@ -350,13 +348,12 @@ return m_threadContext.core->debugger;

} void GameController::setDebugger(mDebugger* debugger) { - threadInterrupt(); + Interrupter interrupter(this); if (debugger) { mDebuggerAttach(debugger, m_threadContext.core); } else { m_threadContext.core->detachDebugger(m_threadContext.core); } - threadContinue(); } #endif

@@ -518,9 +515,8 @@ void GameController::yankPak() {

if (!m_gameOpen) { return; } - threadInterrupt(); + Interrupter interrupter(this); GBAYankROM(static_cast<GBA*>(m_threadContext.core->board)); - threadContinue(); } void GameController::replaceGame(const QString& path) {

@@ -534,10 +530,9 @@ LOG(QT, ERROR) << tr("Failed to open game file: %1").arg(path);

return; } m_fname = info.canonicalFilePath(); - threadInterrupt(); + Interrupter interrupter(this); mDirectorySetDetachBase(&m_threadContext.core->dirs); mCoreLoadFile(m_threadContext.core, m_fname.toLocal8Bit().constData()); - threadContinue(); } void GameController::loadPatch(const QString& path) {

@@ -675,12 +670,11 @@ return;

} bool wasPaused = isPaused(); setPaused(false); - threadInterrupt(); + Interrupter interrupter(this); mCoreThreadReset(&m_threadContext); if (wasPaused) { setPaused(true); } - threadContinue(); } void GameController::threadInterrupt() {

@@ -703,7 +697,7 @@ }

void GameController::setRewind(bool enable, int capacity) { if (m_gameOpen) { - threadInterrupt(); + Interrupter interrupter(this); if (m_threadContext.core->opts.rewindEnable && m_threadContext.core->opts.rewindBufferCapacity > 0) { mCoreRewindContextDeinit(&m_threadContext.rewind); }

@@ -712,7 +706,6 @@ m_threadContext.core->opts.rewindBufferCapacity = capacity;

if (enable && capacity > 0) { mCoreRewindContextInit(&m_threadContext.rewind, capacity); } - threadContinue(); } }

@@ -915,7 +908,7 @@ #endif

} void GameController::setFPSTarget(float fps) { - threadInterrupt(); + Interrupter interrupter(this); m_fpsTarget = fps; m_threadContext.sync.fpsTarget = fps; if (m_turbo && m_turboSpeed > 0) {

@@ -924,7 +917,6 @@ }

if (m_audioProcessor) { redoSamples(m_audioProcessor->getBufferSamples()); } - threadContinue(); } void GameController::setUseBIOS(bool use) {

@@ -1037,7 +1029,7 @@ enableTurbo();

} void GameController::enableTurbo() { - threadInterrupt(); + Interrupter interrupter(this); bool shouldRedoSamples = false; if (!m_turbo) { shouldRedoSamples = m_threadContext.sync.fpsTarget != m_fpsTarget;

@@ -1058,7 +1050,6 @@ }

if (m_audioProcessor && shouldRedoSamples) { redoSamples(m_audioProcessor->getBufferSamples()); } - threadContinue(); } void GameController::setSync(bool enable) {

@@ -1074,21 +1065,19 @@ }

m_sync = enable; } void GameController::setAVStream(mAVStream* stream) { - threadInterrupt(); + Interrupter interrupter(this); m_stream = stream; if (isLoaded()) { m_threadContext.core->setAVStream(m_threadContext.core, stream); } - threadContinue(); } void GameController::clearAVStream() { - threadInterrupt(); + Interrupter interrupter(this); m_stream = nullptr; if (isLoaded()) { m_threadContext.core->setAVStream(m_threadContext.core, nullptr); } - threadContinue(); } #ifdef USE_PNG

@@ -1185,21 +1174,18 @@ QMetaObject::invokeMethod(m_audioProcessor, "inputParametersChanged");

} void GameController::setLogLevel(int levels) { - threadInterrupt(); + Interrupter interrupter(this); m_logLevels = levels; - threadContinue(); } void GameController::enableLogLevel(int levels) { - threadInterrupt(); + Interrupter interrupter(this); m_logLevels |= levels; - threadContinue(); } void GameController::disableLogLevel(int levels) { - threadInterrupt(); + Interrupter interrupter(this); m_logLevels &= ~levels; - threadContinue(); } void GameController::pollEvents() {

@@ -1233,25 +1219,23 @@ }

switch (platform()) { #ifdef M_CORE_GBA case PLATFORM_GBA: { - threadInterrupt(); + Interrupter interrupter(this); GBA* gba = static_cast<GBA*>(m_threadContext.core->board); m_tileCache = std::make_shared<mTileCache>(); GBAVideoTileCacheInit(m_tileCache.get()); GBAVideoTileCacheAssociate(m_tileCache.get(), &gba->video); mTileCacheSetPalette(m_tileCache.get(), 0); - threadContinue(); break; } #endif #ifdef M_CORE_GB case PLATFORM_GB: { - threadInterrupt(); + Interrupter interrupter(this); GB* gb = static_cast<GB*>(m_threadContext.core->board); m_tileCache = std::make_shared<mTileCache>(); GBVideoTileCacheInit(m_tileCache.get()); GBVideoTileCacheAssociate(m_tileCache.get(), &gb->video); mTileCacheSetPalette(m_tileCache.get(), 0); - threadContinue(); break; } #endif

@@ -1260,3 +1244,22 @@ return nullptr;

} return m_tileCache; } + +GameController::Interrupter::Interrupter(GameController* parent, bool fromThread) + : m_parent(parent) + , m_fromThread(fromThread) +{ + if (!m_fromThread) { + m_parent->threadInterrupt(); + } else { + mCoreThreadInterruptFromThread(m_parent->thread()); + } +} + +GameController::Interrupter::~Interrupter() { + if (!m_fromThread) { + m_parent->threadContinue(); + } else { + mCoreThreadContinue(m_parent->thread()); + } +}
M src/platform/qt/GameController.hsrc/platform/qt/GameController.h

@@ -49,6 +49,16 @@ public:

static const bool VIDEO_SYNC = false; static const bool AUDIO_SYNC = true; + class Interrupter { + public: + Interrupter(GameController*, bool fromThread = false); + ~Interrupter(); + + private: + GameController* m_parent; + bool m_fromThread; + }; + GameController(QObject* parent = nullptr); ~GameController();
M src/platform/qt/PaletteView.cppsrc/platform/qt/PaletteView.cpp

@@ -134,18 +134,17 @@ }

if (start + length > 512) { length = 512 - start; } - m_controller->threadInterrupt(); + + GameController::Interrupter interrupter(m_controller); QFileDialog* dialog = GBAApp::app()->getSaveFileDialog(this, tr("Export palette"), tr("Windows PAL (*.pal);;Adobe Color Table (*.act)")); if (!dialog->exec()) { - m_controller->threadContinue(); return; } QString filename = dialog->selectedFiles()[0]; VFile* vf = VFileDevice::open(filename, O_WRONLY | O_CREAT | O_TRUNC); if (!vf) { LOG(QT, ERROR) << tr("Failed to open output palette file: %1").arg(filename); - m_controller->threadContinue(); return; } QString filter = dialog->selectedNameFilter();

@@ -155,5 +154,4 @@ } else if (filter.contains("*.act")) {

exportPaletteACT(vf, length, &static_cast<GBA*>(m_controller->thread()->core->board)->video.palette[start]); } vf->close(vf); - m_controller->threadContinue(); }
M src/platform/qt/ROMInfo.cppsrc/platform/qt/ROMInfo.cpp

@@ -33,7 +33,7 @@

const NoIntroDB* db = GBAApp::app()->gameDB(); uint32_t crc32 = 0; - controller->threadInterrupt(); + GameController::Interrupter interrupter(controller); mCore* core = controller->thread()->core; char title[17] = {}; core->getGameTitle(core, title);

@@ -83,5 +83,4 @@ } else {

m_ui.crc->setText(tr("(unknown)")); m_ui.name->setText(tr("(unknown)")); } - controller->threadContinue(); }
M src/platform/qt/SensorView.cppsrc/platform/qt/SensorView.cpp

@@ -108,7 +108,7 @@ return false;

} void SensorView::updateSensors() { - m_controller->threadInterrupt(); + GameController::Interrupter interrupter(m_controller); if (m_rotation->sample && (!m_controller->isLoaded() || !(static_cast<GBA*>(m_controller->thread()->core->board)->memory.hw.devices & (HW_GYRO | HW_TILT)))) { m_rotation->sample(m_rotation);

@@ -129,7 +129,6 @@ }

if (m_rotation->readGyroZ) { m_ui.gyroView->setValue(m_rotation->readGyroZ(m_rotation)); } - m_controller->threadContinue(); } void SensorView::setLuminanceValue(int value) {