all repos — mgba @ 91ee44c4580f296690e9f995d45b24f74ee8be17

mGBA Game Boy Advance Emulator

GBA Thread: Add functionality for running callbacks on the GBA thread
Jeffrey Pfau jeffrey@endrift.com
Sun, 26 Apr 2015 14:06:57 -0700
commit

91ee44c4580f296690e9f995d45b24f74ee8be17

parent

9c07698068ec289786178c36a273d0de588dcab0

M CHANGESCHANGES

@@ -46,6 +46,7 @@ - Qt: Handle saving input settings better

- Debugger: Free watchpoints in addition to breakpoints - Qt: Move GL frame drawing back onto its own thread - GBA: Add status log level + - GBA Thread: Add functionality for running callbacks on the GBA thread 0.2.0: (2015-04-03) Features:
M src/gba/supervisor/thread.csrc/gba/supervisor/thread.c

@@ -274,6 +274,13 @@ if (threadContext->state == THREAD_INTERRUPTING) {

threadContext->state = THREAD_INTERRUPTED; ConditionWake(&threadContext->stateCond); } + if (threadContext->state == THREAD_RUN_ON) { + if (threadContext->run) { + threadContext->run(threadContext); + } + threadContext->state = THREAD_RUNNING; + ConditionWake(&threadContext->stateCond); + } if (threadContext->state == THREAD_RESETING) { threadContext->state = THREAD_RUNNING; resetScheduled = 1;

@@ -595,6 +602,17 @@ if (threadContext->interruptDepth < 1 && GBAThreadIsActive(threadContext)) {

threadContext->state = threadContext->savedState; ConditionWake(&threadContext->stateCond); } + MutexUnlock(&threadContext->stateMutex); +} + +void GBARunOnThread(struct GBAThread* threadContext, void (*run)(struct GBAThread*)) { + MutexLock(&threadContext->stateMutex); + threadContext->run = run; + _waitOnInterrupt(threadContext); + threadContext->state = THREAD_RUN_ON; + threadContext->gba->cpu->nextEvent = 0; + ConditionWake(&threadContext->stateCond); + _waitUntilNotState(threadContext, THREAD_RUN_ON); MutexUnlock(&threadContext->stateMutex); }
M src/gba/supervisor/thread.hsrc/gba/supervisor/thread.h

@@ -28,6 +28,7 @@ THREAD_INTERRUPTED,

THREAD_INTERRUPTING, THREAD_PAUSED, THREAD_PAUSING, + THREAD_RUN_ON, THREAD_RESETING, THREAD_EXITING, THREAD_SHUTDOWN,

@@ -97,6 +98,7 @@ ThreadCallback startCallback;

ThreadCallback cleanCallback; ThreadCallback frameCallback; void* userData; + void (*run)(struct GBAThread*); struct GBASync sync;

@@ -125,6 +127,8 @@

bool GBAThreadIsActive(struct GBAThread* threadContext); void GBAThreadInterrupt(struct GBAThread* threadContext); void GBAThreadContinue(struct GBAThread* threadContext); + +void GBARunOnThread(struct GBAThread* threadContext, void (*run)(struct GBAThread*)); void GBAThreadPause(struct GBAThread* threadContext); void GBAThreadUnpause(struct GBAThread* threadContext);
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -506,17 +506,21 @@ threadContinue();

} void GameController::loadState(int slot) { - threadInterrupt(); - GBALoadState(&m_threadContext, m_threadContext.stateDir, slot); - threadContinue(); - emit stateLoaded(&m_threadContext); - emit frameAvailable(m_drawContext); + m_stateSlot = slot; + GBARunOnThread(&m_threadContext, [](GBAThread* context) { + GameController* controller = static_cast<GameController*>(context->userData); + GBALoadState(context, context->stateDir, controller->m_stateSlot); + controller->stateLoaded(context); + controller->frameAvailable(controller->m_drawContext); + }); } void GameController::saveState(int slot) { - threadInterrupt(); - GBASaveState(&m_threadContext, m_threadContext.stateDir, slot, true); - threadContinue(); + m_stateSlot = slot; + GBARunOnThread(&m_threadContext, [](GBAThread* context) { + GameController* controller = static_cast<GameController*>(context->userData); + GBASaveState(context, context->stateDir, controller->m_stateSlot, true); + }); } void GameController::setVideoSync(bool set) {

@@ -595,9 +599,7 @@ }

#ifdef USE_PNG void GameController::screenshot() { - GBAThreadInterrupt(&m_threadContext); - GBAThreadTakeScreenshot(&m_threadContext); - GBAThreadContinue(&m_threadContext); + GBARunOnThread(&m_threadContext, GBAThreadTakeScreenshot); } #endif
M src/platform/qt/GameController.hsrc/platform/qt/GameController.h

@@ -184,6 +184,8 @@ bool m_audioSync;

bool m_turbo; bool m_turboForced; + int m_stateSlot; + InputController* m_inputController; std::shared_ptr<MultiplayerController> m_multiplayer;