mirror of https://github.com/mgba-emu/mgba.git
Core: Add pause/unpause callbacks to mCoreThread
This commit is contained in:
parent
1733c64561
commit
1a74924023
|
@ -34,6 +34,8 @@ struct mCoreThread {
|
|||
ThreadCallback cleanCallback;
|
||||
ThreadCallback frameCallback;
|
||||
ThreadCallback sleepCallback;
|
||||
ThreadCallback pauseCallback;
|
||||
ThreadCallback unpauseCallback;
|
||||
void* userData;
|
||||
void (*run)(struct mCoreThread*);
|
||||
|
||||
|
@ -50,13 +52,19 @@ enum mCoreThreadState {
|
|||
THREAD_RUNNING = 0,
|
||||
THREAD_REWINDING,
|
||||
THREAD_MAX_RUNNING = THREAD_REWINDING,
|
||||
|
||||
THREAD_WAITING,
|
||||
THREAD_INTERRUPTED,
|
||||
THREAD_INTERRUPTING,
|
||||
THREAD_PAUSED,
|
||||
THREAD_MAX_WAITING = THREAD_PAUSED,
|
||||
|
||||
THREAD_PAUSING,
|
||||
THREAD_RUN_ON,
|
||||
THREAD_WAITING,
|
||||
THREAD_RESETING,
|
||||
THREAD_MIN_DEFERRED = THREAD_PAUSING,
|
||||
THREAD_MAX_DEFERRED = THREAD_RESETING,
|
||||
|
||||
THREAD_INTERRUPTING,
|
||||
THREAD_EXITING,
|
||||
THREAD_SHUTDOWN,
|
||||
THREAD_CRASHED
|
||||
|
|
|
@ -195,38 +195,58 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
|
|||
}
|
||||
}
|
||||
|
||||
int resetScheduled = 0;
|
||||
enum mCoreThreadState deferred = THREAD_RUNNING;
|
||||
MutexLock(&impl->stateMutex);
|
||||
while (impl->state > THREAD_MAX_RUNNING && impl->state < THREAD_EXITING) {
|
||||
if (impl->state == THREAD_PAUSING) {
|
||||
impl->state = THREAD_PAUSED;
|
||||
ConditionWake(&impl->stateCond);
|
||||
}
|
||||
deferred = impl->state;
|
||||
|
||||
if (impl->state == THREAD_INTERRUPTING) {
|
||||
impl->state = THREAD_INTERRUPTED;
|
||||
ConditionWake(&impl->stateCond);
|
||||
}
|
||||
if (impl->state == THREAD_RUN_ON) {
|
||||
if (threadContext->run) {
|
||||
threadContext->run(threadContext);
|
||||
}
|
||||
impl->state = impl->savedState;
|
||||
ConditionWake(&impl->stateCond);
|
||||
|
||||
if (impl->state == THREAD_PAUSING) {
|
||||
impl->state = THREAD_PAUSED;
|
||||
}
|
||||
if (impl->state == THREAD_RESETING) {
|
||||
impl->state = THREAD_RUNNING;
|
||||
resetScheduled = 1;
|
||||
}
|
||||
while (impl->state == THREAD_PAUSED || impl->state == THREAD_INTERRUPTED || impl->state == THREAD_WAITING) {
|
||||
|
||||
if (deferred >= THREAD_MIN_DEFERRED && deferred <= THREAD_MAX_DEFERRED) {
|
||||
break;
|
||||
}
|
||||
|
||||
deferred = impl->state;
|
||||
while (impl->state >= THREAD_WAITING && impl->state <= THREAD_MAX_WAITING) {
|
||||
ConditionWait(&impl->stateCond, &impl->stateMutex);
|
||||
}
|
||||
}
|
||||
MutexUnlock(&impl->stateMutex);
|
||||
if (resetScheduled) {
|
||||
switch (deferred) {
|
||||
case THREAD_PAUSING:
|
||||
if (threadContext->pauseCallback) {
|
||||
threadContext->pauseCallback(threadContext);
|
||||
}
|
||||
break;
|
||||
case THREAD_PAUSED:
|
||||
if (threadContext->unpauseCallback) {
|
||||
threadContext->unpauseCallback(threadContext);
|
||||
}
|
||||
break;
|
||||
case THREAD_RUN_ON:
|
||||
if (threadContext->run) {
|
||||
threadContext->run(threadContext);
|
||||
}
|
||||
threadContext->impl->state = threadContext->impl->savedState;
|
||||
break;
|
||||
case THREAD_RESETING:
|
||||
core->reset(core);
|
||||
if (threadContext->resetCallback) {
|
||||
threadContext->resetCallback(threadContext);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,18 @@ CoreController::CoreController(mCore* core, QObject* parent)
|
|||
QMetaObject::invokeMethod(controller, "stopping");
|
||||
};
|
||||
|
||||
m_threadContext.pauseCallback = [](mCoreThread* context) {
|
||||
CoreController* controller = static_cast<CoreController*>(context->userData);
|
||||
|
||||
QMetaObject::invokeMethod(controller, "paused");
|
||||
};
|
||||
|
||||
m_threadContext.unpauseCallback = [](mCoreThread* context) {
|
||||
CoreController* controller = static_cast<CoreController*>(context->userData);
|
||||
|
||||
QMetaObject::invokeMethod(controller, "unpaused");
|
||||
};
|
||||
|
||||
m_threadContext.logger.d.log = [](mLogger* logger, int category, enum mLogLevel level, const char* format, va_list args) {
|
||||
mThreadLogger* logContext = reinterpret_cast<mThreadLogger*>(logger);
|
||||
mCoreThread* context = logContext->p;
|
||||
|
@ -344,11 +356,9 @@ void CoreController::setPaused(bool paused) {
|
|||
QMutexLocker locker(&m_mutex);
|
||||
m_frameActions.append([this]() {
|
||||
mCoreThreadPauseFromThread(&m_threadContext);
|
||||
QMetaObject::invokeMethod(this, "paused");
|
||||
});
|
||||
} else {
|
||||
mCoreThreadUnpause(&m_threadContext);
|
||||
emit unpaused();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue