/* * Copyright 2017 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkTypes.h" #include "include/private/SkTHash.h" #include "tools/sk_app/Application.h" #include "tools/sk_app/ios/Window_ios.h" #include "tools/timer/Timer.h" #import using sk_app::Application; //////////////////////////////////////////////////////////////////// @interface AppDelegate : UIResponder @property (nonatomic, assign) BOOL done; @property (strong, nonatomic) UIWindow *window; @end @implementation AppDelegate @synthesize done = _done; @synthesize window = _window; - (void)applicationWillTerminate:(UIApplication *)sender { _done = TRUE; } - (void)launchApp { // Extract argc and argv from NSProcessInfo NSArray *arguments = [[NSProcessInfo processInfo] arguments]; int argc = arguments.count; char** argv = (char **)malloc((argc+1) * sizeof(char *)); int i = 0; for (NSString* string in arguments) { size_t bufferSize = (string.length+1) * sizeof(char); argv[i] = (char*)malloc(bufferSize); [string getCString:argv[i] maxLength:bufferSize encoding:NSUTF8StringEncoding]; ++i; } argv[i] = NULL; [arguments release]; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Application* app = Application::Create(argc, argv, nullptr); // Free the memory we used for argc and argv for (i = 0; i < argc; i++) { free(argv[i]); } free(argv); sk_app::Window_ios* mainWindow = sk_app::Window_ios::MainWindow(); if (!mainWindow) { return; } self.window = mainWindow->uiWindow(); // take over the main event loop bool done = false; while (!done) { // TODO: consider using a dispatch queue or CADisplayLink instead of this const CFTimeInterval kSeconds = 0.000002; CFRunLoopRunResult result; do { result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kSeconds, TRUE); } while (result == kCFRunLoopRunHandledSource); [pool drain]; pool = [[NSAutoreleasePool alloc] init]; // TODO: is this the right approach for iOS? // Rather than depending on an iOS event to drive this, we treat our window // invalidation flag as a separate event stream. Window::onPaint() will clear // the invalidation flag, effectively removing it from the stream. sk_app::Window_ios::PaintWindow(); app->onIdle(); } delete app; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // let the system event loop run once, then launch into our main loop [self performSelector:@selector(launchApp) withObject:nil afterDelay:0.0]; return YES; } @end /////////////////////////////////////////////////////////////////// int main(int argc, char **argv) { /* Give over control to run loop, AppDelegate will handle most things from here */ @autoreleasepool { UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } return EXIT_SUCCESS; }