IOS7: Properly restore state when the process has been terminated

This commit is contained in:
Thierry Crozat 2020-09-12 19:14:49 +01:00
parent 63627dc26d
commit c50ffd74c6
8 changed files with 64 additions and 31 deletions

View File

@ -29,12 +29,14 @@
UIWindow *_window;
iOS7ScummVMViewController *_controller;
iPhoneView *_view;
BOOL _restoreState;
}
- (id)init {
if (self = [super init]) {
_window = nil;
_view = nil;
_restoreState = NO;
}
return self;
}
@ -76,6 +78,11 @@
dispatch_async(dispatch_get_global_queue(0, 0), ^{
iOS7_main(iOS7_argc, iOS7_argv);
});
if (_restoreState)
[_view restoreApplicationState];
else
[_view clearApplicationState];
}
- (void)applicationWillResignActive:(UIApplication *)application {
@ -92,11 +99,19 @@
// no be started before we return from this function.
[[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask];
[_view applicationEnteredBackground];
[_view saveApplicationState];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[_view applicationEnteredForeground];
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
return YES;
}
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
return YES;
}
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
_restoreState = YES;
}
- (void)didRotate:(NSNotification *)notification {

View File

@ -39,8 +39,9 @@ enum InputEvent {
kInputKeyPressed,
kInputApplicationSuspended,
kInputApplicationResumed,
kInputApplicationEnteredBackground,
kInputApplicationEnteredForeground,
kInputApplicationSaveState,
kInputApplicationClearState,
kInputApplicationRestoreState,
kInputSwipe,
kInputTap,
kInputMainMenu

View File

@ -77,12 +77,16 @@ bool OSystem_iOS7::pollEvent(Common::Event &event) {
handleEvent_applicationResumed();
return false;
case kInputApplicationEnteredBackground:
handleEvent_applicationEnteredBackground();
case kInputApplicationSaveState:
handleEvent_applicationSaveState();
return false;
case kInputApplicationEnteredForeground:
handleEvent_applicationEnteredForeground();
case kInputApplicationRestoreState:
handleEvent_applicationRestoreState();
return false;
case kInputApplicationClearState:
handleEvent_applicationClearState();
return false;
case kInputMouseSecondDragged:

View File

@ -245,10 +245,8 @@ void OSystem_iOS7::suspendLoop() {
if (iOS7_fetchEvent(&event)) {
if (event.type == kInputApplicationResumed)
done = true;
else if (event.type == kInputApplicationEnteredBackground)
handleEvent_applicationEnteredBackground();
else if (event.type == kInputApplicationEnteredForeground)
handleEvent_applicationEnteredForeground();
else if (event.type == kInputApplicationSaveState)
handleEvent_applicationSaveState();
}
usleep(100000);
}
@ -260,11 +258,7 @@ void OSystem_iOS7::suspendLoop() {
void OSystem_iOS7::saveState() {
// Clear any previous restore state to avoid having and obsolete one if we don't save it again below.
if (ConfMan.hasKey("restore_target", Common::ConfigManager::kApplicationDomain) &&
ConfMan.hasKey("restore_slot", Common::ConfigManager::kApplicationDomain)) {
ConfMan.removeKey("restore_target", Common::ConfigManager::kApplicationDomain);
ConfMan.removeKey("restore_slot", Common::ConfigManager::kApplicationDomain);
}
clearState();
// If there is an engine running and it accepts autosave, do an autosave and add the current
// running target to the config file.
@ -285,9 +279,7 @@ void OSystem_iOS7::restoreState() {
ConfMan.hasKey("restore_slot", Common::ConfigManager::kApplicationDomain)) {
target = ConfMan.get("restore_target", Common::ConfigManager::kApplicationDomain);
slot = ConfMan.getInt("restore_slot", Common::ConfigManager::kApplicationDomain);
ConfMan.removeKey("restore_target", Common::ConfigManager::kApplicationDomain);
ConfMan.removeKey("restore_slot", Common::ConfigManager::kApplicationDomain);
ConfMan.flushToDisk();
clearState();
}
// If the g_engine is still running (i.e. the application was not terminated) we don't need to do anything.
@ -302,6 +294,15 @@ void OSystem_iOS7::restoreState() {
}
}
void OSystem_iOS7::clearState() {
if (ConfMan.hasKey("restore_target", Common::ConfigManager::kApplicationDomain) &&
ConfMan.hasKey("restore_slot", Common::ConfigManager::kApplicationDomain)) {
ConfMan.removeKey("restore_target", Common::ConfigManager::kApplicationDomain);
ConfMan.removeKey("restore_slot", Common::ConfigManager::kApplicationDomain);
ConfMan.flushToDisk();
}
}
uint32 OSystem_iOS7::getMillis(bool skipRecord) {
CFTimeInterval timeInSeconds = CACurrentMediaTime();
return (uint32) ((timeInSeconds - _startTime) * 1000.0) - _timeSuspended;

View File

@ -229,6 +229,7 @@ protected:
void suspendLoop();
void saveState();
void restoreState();
void clearState();
void drawDirtyRect(const Common::Rect &dirtyRect);
void updateMouseTexture();
static void AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);
@ -240,8 +241,9 @@ protected:
void handleEvent_orientationChanged(int orientation);
void handleEvent_applicationSuspended();
void handleEvent_applicationResumed();
void handleEvent_applicationEnteredBackground();
void handleEvent_applicationEnteredForeground();
void handleEvent_applicationSaveState();
void handleEvent_applicationRestoreState();
void handleEvent_applicationClearState();
bool handleEvent_mouseDown(Common::Event &event, int x, int y);
bool handleEvent_mouseUp(Common::Event &event, int x, int y);

View File

@ -122,12 +122,16 @@ bool OSystem_iOS7::isConnectionLimited() {
return (flags & kSCNetworkReachabilityFlagsIsWWAN);
}
void OSystem_iOS7::handleEvent_applicationEnteredBackground() {
void OSystem_iOS7::handleEvent_applicationSaveState() {
[[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask];
saveState();
[[iOS7AppDelegate iPhoneView] endBackgroundSaveStateTask];
}
void OSystem_iOS7::handleEvent_applicationEnteredForeground() {
void OSystem_iOS7::handleEvent_applicationRestoreState() {
restoreState();
}
void OSystem_iOS7::handleEvent_applicationClearState() {
clearState();
}

View File

@ -131,8 +131,10 @@ typedef struct {
- (void)applicationSuspend;
- (void)applicationResume;
- (void)applicationEnteredBackground;
- (void)applicationEnteredForeground;
- (void)saveApplicationState;
- (void)clearApplicationState;
- (void)restoreApplicationState;
- (void) beginBackgroundSaveStateTask;
- (void) endBackgroundSaveStateTask;

View File

@ -1109,12 +1109,16 @@ uint getSizeNextPOT(uint size) {
[self addEvent:InternalEvent(kInputApplicationResumed, 0, 0)];
}
- (void)applicationEnteredBackground {
[self addEvent:InternalEvent(kInputApplicationEnteredBackground, 0, 0)];
- (void)saveApplicationState {
[self addEvent:InternalEvent(kInputApplicationSaveState, 0, 0)];
}
- (void)applicationEnteredForeground {
[self addEvent:InternalEvent(kInputApplicationEnteredForeground, 0, 0)];
- (void)clearApplicationState {
[self addEvent:InternalEvent(kInputApplicationClearState, 0, 0)];
}
- (void)restoreApplicationState {
[self addEvent:InternalEvent(kInputApplicationRestoreState, 0, 0)];
}
- (void) beginBackgroundSaveStateTask {