Core: Add pause/unpause callbacks to mCoreThread

This commit is contained in:
Vicki Pfau 2017-08-03 23:56:44 -07:00
parent 1733c64561
commit 1a74924023
3 changed files with 56 additions and 18 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
}
}