Qt: Add GameController::Interrupter
@@ -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) {
@@ -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() {
@@ -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() {
@@ -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()); + } +}
@@ -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();
@@ -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(); }
@@ -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(); }
@@ -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) {