mirror of
https://github.com/amwatson/CitraVR.git
synced 2024-09-20 03:11:40 +02:00
[vr_main] declared appstate-modifying state change methods const
This commit is contained in:
parent
3216dd962c
commit
44d4c2d609
1 changed files with 134 additions and 126 deletions
|
@ -174,8 +174,8 @@ public:
|
||||||
while (true) {
|
while (true) {
|
||||||
// Handle events/state-changes.
|
// Handle events/state-changes.
|
||||||
const AppState appState = HandleEvents(jni);
|
const AppState appState = HandleEvents(jni);
|
||||||
|
|
||||||
if (appState.mIsStopRequested) { break; }
|
if (appState.mIsStopRequested) { break; }
|
||||||
|
HandleStateChanges(jni, appState);
|
||||||
if (!appState.mIsXrSessionActive) {
|
if (!appState.mIsXrSessionActive) {
|
||||||
// TODO should block here
|
// TODO should block here
|
||||||
mFrameIndex = 0;
|
mFrameIndex = 0;
|
||||||
|
@ -194,13 +194,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppState HandleEvents(JNIEnv* jni) {
|
|
||||||
AppState newState = mLastAppState;
|
|
||||||
OXRPollEvents(jni, newState);
|
|
||||||
HandleMessageQueueEvents(jni, newState);
|
|
||||||
return newState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init(JNIEnv* jni) {
|
void Init(JNIEnv* jni) {
|
||||||
assert(gOpenXr != nullptr);
|
assert(gOpenXr != nullptr);
|
||||||
mInputStateStatic =
|
mInputStateStatic =
|
||||||
|
@ -804,7 +797,128 @@ private:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSessionStateChanges(const XrSessionState state, AppState& newAppState) {
|
AppState HandleEvents(JNIEnv* jni) const {
|
||||||
|
AppState newState = mLastAppState;
|
||||||
|
OXRPollEvents(jni, newState);
|
||||||
|
HandleMessageQueueEvents(jni, newState);
|
||||||
|
return newState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleStateChanges(JNIEnv* jni, const AppState& newState) const {
|
||||||
|
if (newState.mIsEmulationPaused != mLastAppState.mIsEmulationPaused) {
|
||||||
|
ALOGI("State change: Emulation paused: {} -> {}", mLastAppState.mIsEmulationPaused,
|
||||||
|
newState.mIsEmulationPaused);
|
||||||
|
if (newState.mIsEmulationPaused) {
|
||||||
|
PauseEmulation(jni);
|
||||||
|
} else {
|
||||||
|
ResumeEmulation(jni);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OXRPollEvents(JNIEnv* jni, AppState& newAppState) const {
|
||||||
|
XrEventDataBuffer eventDataBuffer = {};
|
||||||
|
|
||||||
|
// Process all pending messages.
|
||||||
|
for (;;) {
|
||||||
|
XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
|
||||||
|
baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
|
||||||
|
baseEventHeader->next = NULL;
|
||||||
|
XrResult r;
|
||||||
|
OXR(r = xrPollEvent(gOpenXr->mInstance, &eventDataBuffer));
|
||||||
|
if (r != XR_SUCCESS) { break; }
|
||||||
|
|
||||||
|
switch (baseEventHeader->type) {
|
||||||
|
case XR_TYPE_EVENT_DATA_EVENTS_LOST:
|
||||||
|
ALOGV("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_EVENTS_LOST "
|
||||||
|
"event",
|
||||||
|
__func__);
|
||||||
|
break;
|
||||||
|
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
|
||||||
|
ALOGV("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING event",
|
||||||
|
__func__);
|
||||||
|
break;
|
||||||
|
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
|
||||||
|
const XrEventDataSessionStateChanged* ssce =
|
||||||
|
(XrEventDataSessionStateChanged*)(baseEventHeader);
|
||||||
|
if (ssce != nullptr) {
|
||||||
|
ALOGV("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED",
|
||||||
|
__func__);
|
||||||
|
OXRHandleSessionStateChangedEvent(jni, newAppState, *ssce);
|
||||||
|
} else {
|
||||||
|
ALOGE("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: nullptr",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
|
||||||
|
ALOGV("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED event",
|
||||||
|
__func__);
|
||||||
|
break;
|
||||||
|
case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: {
|
||||||
|
[[maybe_unused]] const XrEventDataPerfSettingsEXT* pfs =
|
||||||
|
(XrEventDataPerfSettingsEXT*)(baseEventHeader);
|
||||||
|
ALOGV("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT event: type {} "
|
||||||
|
"subdomain {} : level {} -> level {}",
|
||||||
|
__func__, pfs->type, pfs->subDomain, pfs->fromLevel, pfs->toLevel);
|
||||||
|
} break;
|
||||||
|
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING:
|
||||||
|
ALOGV("{}(): Received "
|
||||||
|
"XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING "
|
||||||
|
"event",
|
||||||
|
__func__);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ALOGV("{}(): Unknown event", __func__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OXRHandleSessionStateChangedEvent(JNIEnv* jni,
|
||||||
|
AppState& newAppState,
|
||||||
|
const XrEventDataSessionStateChanged& newState) const {
|
||||||
|
static XrSessionState lastState = XR_SESSION_STATE_UNKNOWN;
|
||||||
|
if (newState.state != lastState) {
|
||||||
|
ALOGV("{}(): Received XR_SESSION_STATE_CHANGED state {}->{} "
|
||||||
|
"session={} time={}",
|
||||||
|
__func__, XrSessionStateToString(lastState),
|
||||||
|
XrSessionStateToString(newState.state), newState.session, newState.time);
|
||||||
|
}
|
||||||
|
lastState = newState.state;
|
||||||
|
switch (newState.state) {
|
||||||
|
case XR_SESSION_STATE_FOCUSED:
|
||||||
|
ALOGV("{}(): Received XR_SESSION_STATE_FOCUSED event", __func__);
|
||||||
|
if (!mLastAppState.mHasFocus && !mLastAppState.mShouldShowErrorMessage) {
|
||||||
|
newAppState.mIsEmulationPaused = false;
|
||||||
|
}
|
||||||
|
newAppState.mHasFocus = true;
|
||||||
|
break;
|
||||||
|
case XR_SESSION_STATE_VISIBLE:
|
||||||
|
ALOGV("{}(): Received XR_SESSION_STATE_VISIBLE event", __func__);
|
||||||
|
if (mLastAppState.mHasFocus) {
|
||||||
|
newAppState.mIsEmulationPaused = true;
|
||||||
|
}
|
||||||
|
newAppState.mHasFocus = false;
|
||||||
|
break;
|
||||||
|
case XR_SESSION_STATE_READY:
|
||||||
|
case XR_SESSION_STATE_STOPPING:
|
||||||
|
OXRHandleSessionStateChanges(newState.state, newAppState);
|
||||||
|
break;
|
||||||
|
case XR_SESSION_STATE_EXITING:
|
||||||
|
newAppState.mIsStopRequested = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OXRHandleSessionStateChanges(const XrSessionState state, AppState& newAppState) const {
|
||||||
if (state == XR_SESSION_STATE_READY) {
|
if (state == XR_SESSION_STATE_READY) {
|
||||||
assert(mIsXrSessionActive == false);
|
assert(mIsXrSessionActive == false);
|
||||||
|
|
||||||
|
@ -862,121 +976,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSessionStateChangedEvent(JNIEnv* jni,
|
void HandleMessageQueueEvents(JNIEnv* jni, AppState& newAppState) const {
|
||||||
AppState& newAppState,
|
|
||||||
const XrEventDataSessionStateChanged& newState) {
|
|
||||||
static XrSessionState lastState = XR_SESSION_STATE_UNKNOWN;
|
|
||||||
if (newState.state != lastState) {
|
|
||||||
ALOGV("{}(): Received XR_SESSION_STATE_CHANGED state {}->{} "
|
|
||||||
"session={} time={}",
|
|
||||||
__func__, XrSessionStateToString(lastState),
|
|
||||||
XrSessionStateToString(newState.state), newState.session, newState.time);
|
|
||||||
}
|
|
||||||
lastState = newState.state;
|
|
||||||
switch (newState.state) {
|
|
||||||
case XR_SESSION_STATE_FOCUSED:
|
|
||||||
ALOGV("{}(): Received XR_SESSION_STATE_FOCUSED event", __func__);
|
|
||||||
if (!mLastAppState.mHasFocus && !mLastAppState.mShouldShowErrorMessage) {
|
|
||||||
ResumeEmulation(jni);
|
|
||||||
newAppState.mIsEmulationPaused = false;
|
|
||||||
}
|
|
||||||
newAppState.mHasFocus = true;
|
|
||||||
break;
|
|
||||||
case XR_SESSION_STATE_VISIBLE:
|
|
||||||
ALOGV("{}(): Received XR_SESSION_STATE_VISIBLE event", __func__);
|
|
||||||
if (mLastAppState.mHasFocus) {
|
|
||||||
PauseEmulation(jni);
|
|
||||||
newAppState.mIsEmulationPaused = true;
|
|
||||||
}
|
|
||||||
newAppState.mHasFocus = false;
|
|
||||||
break;
|
|
||||||
case XR_SESSION_STATE_READY:
|
|
||||||
case XR_SESSION_STATE_STOPPING:
|
|
||||||
HandleSessionStateChanges(newState.state, newAppState);
|
|
||||||
break;
|
|
||||||
case XR_SESSION_STATE_EXITING:
|
|
||||||
newAppState.mIsStopRequested = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PauseEmulation(JNIEnv* jni) {
|
|
||||||
assert(jni != nullptr);
|
|
||||||
jni->CallVoidMethod(mActivityObject, mPauseGameMethodID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResumeEmulation(JNIEnv* jni) {
|
|
||||||
assert(jni != nullptr);
|
|
||||||
jni->CallVoidMethod(mActivityObject, mResumeGameMethodID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OXRPollEvents(JNIEnv* jni, AppState& newAppState) {
|
|
||||||
XrEventDataBuffer eventDataBuffer = {};
|
|
||||||
|
|
||||||
// Process all pending messages.
|
|
||||||
for (;;) {
|
|
||||||
XrEventDataBaseHeader* baseEventHeader = (XrEventDataBaseHeader*)(&eventDataBuffer);
|
|
||||||
baseEventHeader->type = XR_TYPE_EVENT_DATA_BUFFER;
|
|
||||||
baseEventHeader->next = NULL;
|
|
||||||
XrResult r;
|
|
||||||
OXR(r = xrPollEvent(gOpenXr->mInstance, &eventDataBuffer));
|
|
||||||
if (r != XR_SUCCESS) { break; }
|
|
||||||
|
|
||||||
switch (baseEventHeader->type) {
|
|
||||||
case XR_TYPE_EVENT_DATA_EVENTS_LOST:
|
|
||||||
ALOGV("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_EVENTS_LOST "
|
|
||||||
"event",
|
|
||||||
__func__);
|
|
||||||
break;
|
|
||||||
case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING:
|
|
||||||
ALOGV("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING event",
|
|
||||||
__func__);
|
|
||||||
break;
|
|
||||||
case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: {
|
|
||||||
const XrEventDataSessionStateChanged* ssce =
|
|
||||||
(XrEventDataSessionStateChanged*)(baseEventHeader);
|
|
||||||
if (ssce != nullptr) {
|
|
||||||
ALOGV("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED",
|
|
||||||
__func__);
|
|
||||||
HandleSessionStateChangedEvent(jni, newAppState, *ssce);
|
|
||||||
} else {
|
|
||||||
ALOGE("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: nullptr",
|
|
||||||
__func__);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED:
|
|
||||||
ALOGV("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED event",
|
|
||||||
__func__);
|
|
||||||
break;
|
|
||||||
case XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT: {
|
|
||||||
[[maybe_unused]] const XrEventDataPerfSettingsEXT* pfs =
|
|
||||||
(XrEventDataPerfSettingsEXT*)(baseEventHeader);
|
|
||||||
ALOGV("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT event: type {} "
|
|
||||||
"subdomain {} : level {} -> level {}",
|
|
||||||
__func__, pfs->type, pfs->subDomain, pfs->fromLevel, pfs->toLevel);
|
|
||||||
} break;
|
|
||||||
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING:
|
|
||||||
ALOGV("{}(): Received "
|
|
||||||
"XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING "
|
|
||||||
"event",
|
|
||||||
__func__);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ALOGV("{}(): Unknown event", __func__);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleMessageQueueEvents(JNIEnv* jni, AppState& newAppState) {
|
|
||||||
// Arbitrary limit to prevent the render thread from blocking too long
|
// Arbitrary limit to prevent the render thread from blocking too long
|
||||||
// on a single frame. This may happen if the app is paused in an edge
|
// on a single frame. This may happen if the app is paused in an edge
|
||||||
// case. We should try to avoid these cases as it will result in a
|
// case. We should try to avoid these cases as it will result in a
|
||||||
|
@ -1011,13 +1011,11 @@ private:
|
||||||
newAppState.mShouldShowErrorMessage = shouldShowErrorMessage;
|
newAppState.mShouldShowErrorMessage = shouldShowErrorMessage;
|
||||||
if (newAppState.mShouldShowErrorMessage && !newAppState.mIsEmulationPaused) {
|
if (newAppState.mShouldShowErrorMessage && !newAppState.mIsEmulationPaused) {
|
||||||
ALOGD("Pausing emulation due to error message");
|
ALOGD("Pausing emulation due to error message");
|
||||||
PauseEmulation(jni);
|
|
||||||
newAppState.mIsEmulationPaused = true;
|
newAppState.mIsEmulationPaused = true;
|
||||||
}
|
}
|
||||||
if (!newAppState.mShouldShowErrorMessage && newAppState.mIsEmulationPaused &&
|
if (!newAppState.mShouldShowErrorMessage && newAppState.mIsEmulationPaused &&
|
||||||
newAppState.mHasFocus) {
|
newAppState.mHasFocus) {
|
||||||
ALOGD("Resuming emulation after error message");
|
ALOGD("Resuming emulation after error message");
|
||||||
ResumeEmulation(jni);
|
|
||||||
newAppState.mIsEmulationPaused = false;
|
newAppState.mIsEmulationPaused = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1035,6 +1033,16 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PauseEmulation(JNIEnv* jni) const {
|
||||||
|
assert(jni != nullptr);
|
||||||
|
jni->CallVoidMethod(mActivityObject, mPauseGameMethodID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResumeEmulation(JNIEnv* jni) const {
|
||||||
|
assert(jni != nullptr);
|
||||||
|
jni->CallVoidMethod(mActivityObject, mResumeGameMethodID);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t mFrameIndex = 0;
|
uint64_t mFrameIndex = 0;
|
||||||
std::thread mThread;
|
std::thread mThread;
|
||||||
jobject mActivityObject;
|
jobject mActivityObject;
|
||||||
|
|
Loading…
Reference in a new issue