From eac69ae30c4777f2593fe3d46c10e9fc1449211c Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 23:13:20 -0800 Subject: [PATCH] move to cancellable tile-specific fetches on OS X --- macosx/llmr-app.gyp | 2 +- macosx/main.mm | 71 +++++++++++++++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/macosx/llmr-app.gyp b/macosx/llmr-app.gyp index 9b589c723..b206e8d76 100644 --- a/macosx/llmr-app.gyp +++ b/macosx/llmr-app.gyp @@ -41,7 +41,7 @@ 'INFOPLIST_FILE': 'Info.plist', 'CLANG_CXX_LIBRARY': 'libc++', 'CLANG_CXX_LANGUAGE_STANDARD':'c++11', - 'MACOSX_DEPLOYMENT_TARGET':'10.8', + 'MACOSX_DEPLOYMENT_TARGET':'10.9', 'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0', 'CLANG_ENABLE_OBJC_ARC': 'YES' }, diff --git a/macosx/main.mm b/macosx/main.mm index 7c2f0cc1e..49fa13ea4 100644 --- a/macosx/main.mm +++ b/macosx/main.mm @@ -3,6 +3,7 @@ #import #import #include +#include #include "settings.hpp" #include @@ -229,34 +230,68 @@ void restart(void *) { mapView->dirty = true; } -void request_http(std::string url, std::function background_function, std::function foreground_callback) { - if (!queue) { - queue = [NSOperationQueue new]; - } - - NSMutableURLRequest *urlRequest = [NSMutableURLRequest - requestWithURL:[NSURL - URLWithString:@(url.c_str())]]; - - [NSURLConnection - sendAsynchronousRequest:urlRequest - queue:[NSOperationQueue mainQueue] - completionHandler: ^(NSURLResponse * response, NSData * data, NSError * error) { +void request_http(std::string url, std::function background_function, std::function foreground_callback) +{ + NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@(url.c_str())] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) + { Response res; - if (error == nil) { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - res.code = [httpResponse statusCode]; + + if ( ! error) + { + res.code = [(NSHTTPURLResponse *)response statusCode]; res.body = { (const char *)[data bytes], [data length] }; } background_function(res); - dispatch_async(dispatch_get_main_queue(), ^(void) { + + dispatch_async(dispatch_get_main_queue(), ^(void) + { foreground_callback(); }); - [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; }]; + + [task resume]; } +void request_http_tile(std::string url, tile_ptr tile_object, std::function background_function, std::function foreground_callback) +{ + NSString *latestZoom = [@(tile_object->id.z) stringValue]; + + [[NSURLSession sharedSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) + { + for (NSURLSessionDownloadTask *task in downloadTasks) + if (task.taskDescription && ! [task.taskDescription isEqualToString:latestZoom]) + [task cancel]; + }]; + + NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@(url.c_str())] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) + { + if (error && [[error domain] isEqualToString:NSURLErrorDomain] && [error code] == NSURLErrorCancelled) + return; + + Response res; + + if ( ! error) + { + res.code = [(NSHTTPURLResponse *)response statusCode]; + res.body = { (const char *)[data bytes], [data length] }; + } + + background_function(res); + + dispatch_async(dispatch_get_main_queue(), ^(void) + { + foreground_callback(); + }); + + if ( ! error) + [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; + }]; + + task.taskDescription = [@(tile_object->id.z) stringValue]; + + [task resume]; +} double time() { return glfwGetTime();