IOS7: Save state as a background task when entering background

This is better than using an hardcoded delay for two main reasons.
The first one is that the application can terminate as soon as it
has finished saving the state, and the second one is that it will
still work if saving the state takes longer than the delay that
was hardcoded.
This commit is contained in:
Thierry Crozat 2020-09-06 07:05:39 +01:00
parent 97af5542b1
commit ecaa8e5440
6 changed files with 41 additions and 14 deletions

View file

@ -87,11 +87,12 @@
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Start the background task before sending the application entered background event.
// This is because this event will be handled in a separate thread and it will likely
// no be started before we return from this function.
[[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask];
[_view applicationEnteredBackground];
// Add a delay so that the app continues running and gives time for the scummvm thread to
// poll the events and call saveState(). The application says we have 5 seconds to do things
// in this function before the app is terminated. Wait 2 seconds as it should be sufficient.
usleep(2000000);
}
- (void)applicationWillEnterForeground:(UIApplication *)application {

View file

@ -393,14 +393,6 @@ void OSystem_iOS7::handleEvent_applicationResumed() {
rebuildSurface();
}
void OSystem_iOS7::handleEvent_applicationEnteredBackground() {
saveState();
}
void OSystem_iOS7::handleEvent_applicationEnteredForeground() {
restoreState();
}
void OSystem_iOS7::handleEvent_keyPressed(Common::Event &event, int keyPressed) {
int ascii = keyPressed;
//printf("key: %i\n", keyPressed);

View file

@ -246,9 +246,9 @@ void OSystem_iOS7::suspendLoop() {
if (event.type == kInputApplicationResumed)
done = true;
else if (event.type == kInputApplicationEnteredBackground)
saveState();
handleEvent_applicationEnteredBackground();
else if (event.type == kInputApplicationEnteredForeground)
restoreState();
handleEvent_applicationEnteredForeground();
}
usleep(100000);
}

View file

@ -28,6 +28,8 @@
#include <UIKit/UIKit.h>
#include <SystemConfiguration/SCNetworkReachability.h>
#include "common/translation.h"
#include "backends/platform/ios7/ios7_app_delegate.h"
#include "backends/platform/ios7/ios7_video.h"
static inline void execute_on_main_thread_async(void (^block)(void)) {
if ([NSThread currentThread] == [NSThread mainThread]) {
@ -108,3 +110,13 @@ bool OSystem_iOS7::isConnectionLimited() {
CFRelease(ref);
return (flags & kSCNetworkReachabilityFlagsIsWWAN);
}
void OSystem_iOS7::handleEvent_applicationEnteredBackground() {
[[iOS7AppDelegate iPhoneView] beginBackgroundSaveStateTask];
saveState();
[[iOS7AppDelegate iPhoneView] endBackgroundSaveStateTask];
}
void OSystem_iOS7::handleEvent_applicationEnteredForeground() {
restoreState();
}

View file

@ -50,6 +50,8 @@ typedef struct {
SoftKeyboard *_keyboardView;
BOOL _keyboardVisible;
UIBackgroundTaskIdentifier _backgroundSaveStateTask;
EAGLContext *_context;
GLuint _viewRenderbuffer;
GLuint _viewFramebuffer;
@ -132,6 +134,9 @@ typedef struct {
- (void)applicationEnteredBackground;
- (void)applicationEnteredForeground;
- (void) beginBackgroundSaveStateTask;
- (void) endBackgroundSaveStateTask;
- (bool)fetchEvent:(InternalEvent *)event;
@end

View file

@ -421,6 +421,8 @@ uint getSizeNextPOT(uint size) {
- (id)initWithFrame:(struct CGRect)frame {
self = [super initWithFrame: frame];
_backgroundSaveStateTask = UIBackgroundTaskInvalid;
#if defined(USE_SCALERS) || defined(USE_HQ_SCALERS)
InitScalers(565);
#endif
@ -1115,4 +1117,19 @@ uint getSizeNextPOT(uint size) {
[self addEvent:InternalEvent(kInputApplicationEnteredForeground, 0, 0)];
}
- (void) beginBackgroundSaveStateTask {
if (_backgroundSaveStateTask == UIBackgroundTaskInvalid) {
_backgroundSaveStateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundSaveStateTask];
}];
}
}
- (void) endBackgroundSaveStateTask {
if (_backgroundSaveStateTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask: _backgroundSaveStateTask];
_backgroundSaveStateTask = UIBackgroundTaskInvalid;
}
}
@end