#include "SDL_internal.h"
#include "../SDL_main_callbacks.h"
#ifdef SDL_PLATFORM_IOS
#import <UIKit/UIKit.h>
#include "../../video/uikit/SDL_uikitevents.h"
@interface SDLIosMainCallbacksDisplayLink : NSObject
@property(nonatomic, retain) CADisplayLink *displayLink;
- (void)appIteration:(CADisplayLink *)sender;
- (instancetype)init:(SDL_AppIterate_func)_appiter quitfunc:(SDL_AppQuit_func)_appquit;
@end
static SDLIosMainCallbacksDisplayLink *globalDisplayLink;
@implementation SDLIosMainCallbacksDisplayLink
- (instancetype)init:(SDL_AppIterate_func)_appiter quitfunc:(SDL_AppQuit_func)_appquit;
{
if ((self = [super init])) {
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(appIteration:)];
if (@available(iOS 15.0, tvOS 15.0, *)) {
const SDL_DisplayMode *mode = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay());
if (mode && mode->refresh_rate > 60.0f) {
int frame_rate = (int)mode->refresh_rate;
self.displayLink.preferredFrameRateRange = CAFrameRateRangeMake((frame_rate * 2) / 3, frame_rate, frame_rate);
}
}
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
return self;
}
- (void)appIteration:(CADisplayLink *)sender
{
const SDL_AppResult rc = SDL_IterateMainCallbacks(true);
if (rc != SDL_APP_CONTINUE) {
[self.displayLink invalidate];
self.displayLink = nil;
globalDisplayLink = nil;
SDL_QuitMainCallbacks(rc);
SDL_UpdateLifecycleObserver();
exit((rc == SDL_APP_FAILURE) ? 1 : 0);
}
}
@end
int SDL_EnterAppMainCallbacks(int argc, char *argv[], SDL_AppInit_func appinit, SDL_AppIterate_func appiter, SDL_AppEvent_func appevent, SDL_AppQuit_func appquit)
{
SDL_AppResult rc = SDL_InitMainCallbacks(argc, argv, appinit, appiter, appevent, appquit);
if (rc == SDL_APP_CONTINUE) {
globalDisplayLink = [[SDLIosMainCallbacksDisplayLink alloc] init:appiter quitfunc:appquit];
if (globalDisplayLink == nil) {
rc = SDL_APP_FAILURE;
} else {
return 0; }
}
SDL_QuitMainCallbacks(rc);
exit((rc == SDL_APP_FAILURE) ? 1 : 0);
return 1; }
#endif