1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci* Copyright 2017 Google Inc.
3cb93a386Sopenharmony_ci*
4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci* found in the LICENSE file.
6cb93a386Sopenharmony_ci*/
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
9cb93a386Sopenharmony_ci#include "tools/sk_app/Application.h"
10cb93a386Sopenharmony_ci#include "tools/sk_app/ios/Window_ios.h"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#import <QuartzCore/QuartzCore.h>
13cb93a386Sopenharmony_ci#import <UIKit/UIKit.h>
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ci#if __has_feature(objc_arc)
16cb93a386Sopenharmony_ci#error "File should not be compiled with ARC."
17cb93a386Sopenharmony_ci#endif
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_cinamespace {
20cb93a386Sopenharmony_ci
21cb93a386Sopenharmony_cistatic int gArgc;
22cb93a386Sopenharmony_cistatic char** gArgv;
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ci}
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci////////////////////////////////////////////////////////////////////
27cb93a386Sopenharmony_ci
28cb93a386Sopenharmony_ci@interface AppDelegate : UIResponder<UIApplicationDelegate>
29cb93a386Sopenharmony_ci
30cb93a386Sopenharmony_ci@end
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci@implementation AppDelegate {
33cb93a386Sopenharmony_ci    CADisplayLink* fDisplayLink; // Owned by the run loop.
34cb93a386Sopenharmony_ci    std::unique_ptr<sk_app::Application> fApp;
35cb93a386Sopenharmony_ci}
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci#pragma mark - UIApplicationDelegate
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ci- (void)applicationWillResignActive:(UIApplication *)sender {
40cb93a386Sopenharmony_ci    sk_app::Window_ios* mainWindow = sk_app::Window_ios::MainWindow();
41cb93a386Sopenharmony_ci    if (mainWindow) {
42cb93a386Sopenharmony_ci        mainWindow->onActivate(false);
43cb93a386Sopenharmony_ci    }
44cb93a386Sopenharmony_ci}
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci- (void)applicationDidBecomeActive:(UIApplication *)sender {
47cb93a386Sopenharmony_ci    sk_app::Window_ios* mainWindow = sk_app::Window_ios::MainWindow();
48cb93a386Sopenharmony_ci    if (mainWindow) {
49cb93a386Sopenharmony_ci        mainWindow->onActivate(true);
50cb93a386Sopenharmony_ci    }
51cb93a386Sopenharmony_ci}
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_ci- (void)applicationWillTerminate:(UIApplication *)sender {
54cb93a386Sopenharmony_ci    // Display link retains us, so we break the cycle now.
55cb93a386Sopenharmony_ci    // Note: dealloc is never called.
56cb93a386Sopenharmony_ci    [fDisplayLink invalidate];
57cb93a386Sopenharmony_ci    fDisplayLink = nil;
58cb93a386Sopenharmony_ci    fApp.reset();
59cb93a386Sopenharmony_ci}
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ci- (BOOL)application:(UIApplication *)application
62cb93a386Sopenharmony_ci        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
63cb93a386Sopenharmony_ci    fApp = std::unique_ptr<sk_app::Application>(sk_app::Application::Create(gArgc, gArgv, nullptr));
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci    auto mainWindow = sk_app::Window_ios::MainWindow();
66cb93a386Sopenharmony_ci    mainWindow->onActivate(application.applicationState == UIApplicationStateActive);
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci    fDisplayLink = [CADisplayLink displayLinkWithTarget:self
69cb93a386Sopenharmony_ci                                               selector:@selector(displayLinkFired)];
70cb93a386Sopenharmony_ci    [fDisplayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes];
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    return YES;
73cb93a386Sopenharmony_ci}
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci- (void)displayLinkFired {
76cb93a386Sopenharmony_ci    // TODO: Hook into CAMetalLayer's drawing event loop or our own run loop observer.
77cb93a386Sopenharmony_ci    // Need to handle animated slides/redraw mode, so we need something that will wake up the
78cb93a386Sopenharmony_ci    // run loop.
79cb93a386Sopenharmony_ci    sk_app::Window_ios::PaintWindow();
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ci    fApp->onIdle();
82cb93a386Sopenharmony_ci}
83cb93a386Sopenharmony_ci
84cb93a386Sopenharmony_ci@end
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////
87cb93a386Sopenharmony_ci
88cb93a386Sopenharmony_ciint main(int argc, char **argv) {
89cb93a386Sopenharmony_ci    gArgc = argc;
90cb93a386Sopenharmony_ci    gArgv = argv;
91cb93a386Sopenharmony_ci    return UIApplicationMain(argc, argv, nil, @"AppDelegate");
92cb93a386Sopenharmony_ci}
93