From 2bc63f76a4c3200c61902e7133898d7ba35fedc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 17 Apr 2015 12:31:49 -0700 Subject: [PATCH 001/373] Made pan gestures slipperier Replaced the complex formula for overpanning with a simple one that makes the map feel much slipperier than before. `MGLMapView` now overpans just a little more aggressively than `MKMapView` but still a lot less aggressively than Google Maps. Fixes #1266. --- platform/ios/MGLMapView.mm | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5acf04ef7..b73f2647d 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -677,22 +677,8 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; else if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled) { CGPoint velocity = [pan velocityInView:pan.view]; - CGFloat duration = 0; - - if ( ! CGPointEqualToPoint(velocity, CGPointZero)) - { - CGFloat ease = 0.25; - - velocity.x = velocity.x * ease; - velocity.y = velocity.y * ease; - - CGFloat speed = sqrt(velocity.x * velocity.x + velocity.y * velocity.y); - CGFloat deceleration = 2500; - duration = speed / (deceleration * ease); - } - - CGPoint offset = CGPointMake(velocity.x * duration / 2, velocity.y * duration / 2); - + CGFloat duration = UIScrollViewDecelerationRateNormal; + CGPoint offset = CGPointMake(velocity.x * duration / 4, velocity.y * duration / 4); mbglMap->moveBy(offset.x, offset.y, secondsAsDuration(duration)); mbglMap->setGestureInProgress(false); From 4c6987b20ea21f6bea096218f871d55dc3497ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Apr 2015 19:40:26 -0700 Subject: [PATCH 002/373] Apply some friction to pan drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the panning velocity is low enough, ignore the pan gesture to simulate friction on the device’s glass screen. --- platform/ios/MGLMapView.mm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index b73f2647d..0586f17ae 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -677,13 +677,22 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; else if (pan.state == UIGestureRecognizerStateEnded || pan.state == UIGestureRecognizerStateCancelled) { CGPoint velocity = [pan velocityInView:pan.view]; + if (sqrtf(velocity.x * velocity.x + velocity.y * velocity.y) < 100) + { + // Not enough velocity to overcome friction + velocity = CGPointZero; + } + CGFloat duration = UIScrollViewDecelerationRateNormal; - CGPoint offset = CGPointMake(velocity.x * duration / 4, velocity.y * duration / 4); - mbglMap->moveBy(offset.x, offset.y, secondsAsDuration(duration)); + if ( ! CGPointEqualToPoint(velocity, CGPointZero)) + { + CGPoint offset = CGPointMake(velocity.x * duration / 4, velocity.y * duration / 4); + mbglMap->moveBy(offset.x, offset.y, secondsAsDuration(duration)); + } mbglMap->setGestureInProgress(false); - if (duration) + if ( ! CGPointEqualToPoint(velocity, CGPointZero)) { self.animatingGesture = YES; From 41d28e7203ab9545fcaaedeeb5836837a865b364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Apr 2015 19:47:52 -0700 Subject: [PATCH 003/373] Added drift-zooming effect after pinch gesture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply a subtle animated zoom after a pinch gesture completes. Lots of magic numbers involved. Avoid drifting when the pinch is near-static, and when the scale factor would go below the minimum. There is more resistance to pinching outward than pinching inward, because it’s far easier to lose your place when you accidentally zoom out. Disabled two-finger pan, which is typically reserved for changing pitch; otherwise, it’s easy to accidentally pan while intending to pinch. --- platform/ios/MGLMapView.mm | 54 ++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 0586f17ae..6c5f3cc2e 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -327,6 +327,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // _pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; _pan.delegate = self; + _pan.maximumNumberOfTouches = 1; [self addGestureRecognizer:_pan]; _scrollEnabled = YES; @@ -747,17 +748,60 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; if (log2(newScale) < mbglMap->getMinZoom()) return; - double scale = mbglMap->getScale(); - - mbglMap->scaleBy(newScale / scale, [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y); + mbglMap->setScale(newScale, [pinch locationInView:pinch.view].x, [pinch locationInView:pinch.view].y); } else if (pinch.state == UIGestureRecognizerStateEnded || pinch.state == UIGestureRecognizerStateCancelled) { + CGFloat velocity = pinch.velocity; + if (velocity > -0.5 && velocity < 3) + { + velocity = 0; + } + CGFloat duration = velocity > 0 ? 1 : 0.25; + + CGFloat scale = self.scale * pinch.scale; + CGFloat newScale = scale; + if (velocity >= 0) + { + newScale += scale * velocity * duration * 0.1; + } + else + { + newScale += scale / (velocity * duration) * 0.1; + } + + if (newScale <= 0 || log2(newScale) < mbglMap->getMinZoom()) + { + velocity = 0; + } + + if (velocity) + { + CGPoint pinchCenter = [pinch locationInView:pinch.view]; + mbglMap->setScale(newScale, pinchCenter.x, pinchCenter.y, secondsAsDuration(duration)); + } + mbglMap->setGestureInProgress(false); - + [self unrotateIfNeededAnimated:YES]; + + if (velocity) + { + self.animatingGesture = YES; - [self notifyMapChange:@(mbgl::MapChangeRegionDidChange)]; + __weak MGLMapView *weakSelf = self; + + [self animateWithDelay:duration animations:^ + { + weakSelf.animatingGesture = NO; + + [weakSelf notifyMapChange:@(mbgl::MapChangeRegionDidChangeAnimated)]; + }]; + } + else + { + [self notifyMapChange:@(mbgl::MapChangeRegionDidChange)]; + } } } From 33aeecef220af5ee78551de56a2573d6b1145fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Apr 2015 20:50:35 -0700 Subject: [PATCH 004/373] Added drift-rotation effect after rotation gesture --- platform/ios/MGLMapView.mm | 39 +++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 6c5f3cc2e..330ce289a 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -839,11 +839,40 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; } else if (rotate.state == UIGestureRecognizerStateEnded || rotate.state == UIGestureRecognizerStateCancelled) { - mbglMap->setGestureInProgress(false); - - [self unrotateIfNeededAnimated:YES]; - - [self notifyMapChange:@(mbgl::MapChangeRegionDidChange)]; + CGFloat velocity = rotate.velocity; + + if (fabs(velocity) > 5) + { + CGFloat radians = self.angle + rotate.rotation; + CGFloat duration = UIScrollViewDecelerationRateNormal; + CGFloat newRadians = radians + velocity * duration * 0.1; + CGFloat newDegrees = fmodf([MGLMapView radiansToDegrees:newRadians], 360) * -1; + + mbglMap->setBearing(newDegrees, secondsAsDuration(duration)); + + mbglMap->setGestureInProgress(false); + + self.animatingGesture = YES; + + __weak MGLMapView *weakSelf = self; + + [self animateWithDelay:duration animations:^ + { + weakSelf.animatingGesture = NO; + + [weakSelf unrotateIfNeededAnimated:YES]; + + [weakSelf notifyMapChange:@(mbgl::MapChangeRegionDidChangeAnimated)]; + }]; + } + else + { + mbglMap->setGestureInProgress(false); + + [self unrotateIfNeededAnimated:YES]; + + [self notifyMapChange:@(mbgl::MapChangeRegionDidChange)]; + } } } From fae0c4c8b3fb743f4e765a89068861cea49588c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Apr 2015 22:02:15 -0700 Subject: [PATCH 005/373] Simplified math for drift-rotation fmodf() would conflict with the fix for #1199. --- platform/ios/MGLMapView.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 330ce289a..78ad046d7 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -846,7 +846,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; CGFloat radians = self.angle + rotate.rotation; CGFloat duration = UIScrollViewDecelerationRateNormal; CGFloat newRadians = radians + velocity * duration * 0.1; - CGFloat newDegrees = fmodf([MGLMapView radiansToDegrees:newRadians], 360) * -1; + CGFloat newDegrees = [MGLMapView radiansToDegrees:newRadians] * -1; mbglMap->setBearing(newDegrees, secondsAsDuration(duration)); From 261b6161f2554520781d33183b8560613ef184ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Apr 2015 23:01:42 -0700 Subject: [PATCH 006/373] Cancel animations on touch down Cancel any map animations as soon as a finger is set upon the screen. Fixes #1258. --- platform/ios/MGLMapView.mm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5acf04ef7..1b50146a6 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -647,6 +647,15 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; #pragma clang diagnostic pop +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + (void)touches; + (void)event; + mbglMap->cancelTransitions(); + mbglMap->setGestureInProgress(false); + self.animatingGesture = NO; +} + - (void)handlePanGesture:(UIPanGestureRecognizer *)pan { if ( ! self.isScrollEnabled) return; From 0aadbedecb24f4c01ea24fd75c9fb7d17b0b8216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Mon, 20 Apr 2015 11:15:29 -0700 Subject: [PATCH 007/373] Lower threshold for rotation drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s pretty darn hard to get up to 5 rad/s with the same two fingers. --- platform/ios/MGLMapView.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 78ad046d7..274e70208 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -841,7 +841,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; { CGFloat velocity = rotate.velocity; - if (fabs(velocity) > 5) + if (fabs(velocity) > 3) { CGFloat radians = self.angle + rotate.rotation; CGFloat duration = UIScrollViewDecelerationRateNormal; From 578d48b303d5d615ac70f9f1f6f3edfef020d8a3 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Wed, 22 Apr 2015 17:19:59 -0500 Subject: [PATCH 008/373] #1225 - Initial setup of MapboxGL as a singleton object with access token --- gyp/platform-ios.gypi | 1 + include/mbgl/ios/MapboxGL.h | 6 ++++++ platform/ios/MapboxGL.m | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 platform/ios/MapboxGL.m diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index f70743118..142896c4e 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -17,6 +17,7 @@ '../platform/darwin/image.mm', '../platform/darwin/reachability.m', '../include/mbgl/ios/MapboxGL.h', + '../platform/ios/MapboxGL.m', '../include/mbgl/ios/MGLMapboxEvents.h', '../platform/ios/MGLMapboxEvents.m', '../include/mbgl/ios/MGLMapView.h', diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index c32915bc7..84c3f4542 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -2,3 +2,9 @@ #import "MGLMapView.h" #import "MGLTypes.h" #import "MGLUserLocation.h" + +@interface MapboxGL : NSObject + ++ (void) sharedInstanceWithAccessToken:(NSString *)token; + +@end \ No newline at end of file diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m new file mode 100644 index 000000000..b1cb44cbc --- /dev/null +++ b/platform/ios/MapboxGL.m @@ -0,0 +1,39 @@ +#import + +#import "MapboxGL.h" + +@interface MapboxGL() + +@end + +@property (atomic) NSString *accessToken; + +@implementation MapboxGL + + +// Can be called from any thread. Called implicitly from any +// public class convenience methods. +// ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token { + static dispatch_once_t onceToken; + static MapboxGL *_sharedManager; + dispatch_once(&onceToken, ^{ + if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { + void (^setupBlock)() = ^{ + _sharedManager = [[self alloc] init]; + _sharedManager.accessToken = token; + }; + if ( ! [[NSThread currentThread] isMainThread]) { + dispatch_sync(dispatch_get_main_queue(), ^{ + setupBlock(); + }); + } + else { + setupBlock(); + } + } + }); + return _sharedManager; +} + +@end \ No newline at end of file From 7e145780ebbd5d35a74f263c51827ae2a37c4eb8 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Thu, 23 Apr 2015 18:15:01 -0500 Subject: [PATCH 009/373] #1225 - Initial conversion of Mapbox GL app to set access token in AppDelegate and exposing MGLMapView.initWithFrame to support it --- include/mbgl/ios/MGLMapView.h | 5 +++++ include/mbgl/ios/MapboxGL.h | 3 ++- ios/app/MBXAppDelegate.m | 16 ++++++++++++++++ ios/app/MBXViewController.mm | 15 +-------------- platform/ios/MGLMapView.mm | 2 ++ platform/ios/MapboxGL.m | 15 ++++++++++++--- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 8717b5e8a..eb9a770dc 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -20,6 +20,11 @@ IB_DESIGNABLE /** @name Initializing a Map View */ +/** Initialize a map view with the default style, given frame, and access token set in MapboxGL singleton. +* @param frame The frame with which to initialize the map view. +* @return An initialized map view, or `nil` if the map view was unable to be initialized. */ +- (instancetype)initWithFrame:(CGRect)frame; + /** Initialize a map view with the default style and a given frame and access token. * @param frame The frame with which to initialize the map view. * @param accessToken A Mapbox API access token. diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index 84c3f4542..4e5ff09b2 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -5,6 +5,7 @@ @interface MapboxGL : NSObject -+ (void) sharedInstanceWithAccessToken:(NSString *)token; ++ (id) sharedInstanceWithAccessToken:(NSString *)token; ++ (NSString *) getAccessToken; @end \ No newline at end of file diff --git a/ios/app/MBXAppDelegate.m b/ios/app/MBXAppDelegate.m index f2ef69ec6..4d314483a 100644 --- a/ios/app/MBXAppDelegate.m +++ b/ios/app/MBXAppDelegate.m @@ -1,11 +1,27 @@ #import "MBXAppDelegate.h" #import "MBXViewController.h" +#import #import @implementation MBXAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Set Access Token + NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; + if (accessToken) { + // Store to preferences so that we can launch the app later on without having to specify + // token. + [[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"]; + } else { + // Try to retrieve from preferences, maybe we've stored them there previously and can reuse + // the token. + accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"]; + } + if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work."); + + [MapboxGL sharedInstanceWithAccessToken:accessToken]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MBXViewController new]]; [self.window makeKeyAndVisible]; diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 13235beb0..394536b98 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -52,20 +52,7 @@ mbgl::Settings_NSUserDefaults *settings = nullptr; { [super viewDidLoad]; - NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; - if (accessToken) { - // Store to preferences so that we can launch the app later on without having to specify - // token. - [[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"]; - } else { - // Try to retrieve from preferences, maybe we've stored them there previously and can reuse - // the token. - accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"]; - } - - if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work."); - - self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken]; + self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.mapView.viewControllerForLayoutGuides = self; self.mapView.showsUserLocation = YES; diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5f5e99b0e..e48b3d82d 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -25,6 +25,7 @@ #import "SMCalloutView.h" #import "MGLMapboxEvents.h" +#import "MapboxGL.h" #import @@ -122,6 +123,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; if (self && [self commonInit]) { self.styleURL = nil; + self.accessToken = [MapboxGL getAccessToken]; return self; } diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m index b1cb44cbc..97ac8f1d5 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MapboxGL.m @@ -1,22 +1,24 @@ #import #import "MapboxGL.h" +#import "NSProcessInfo+MGLAdditions.h" @interface MapboxGL() +@property (atomic) NSString *accessToken; + @end -@property (atomic) NSString *accessToken; @implementation MapboxGL +static MapboxGL *_sharedManager; // Can be called from any thread. Called implicitly from any // public class convenience methods. // -+ (instancetype) sharedInstanceWithAccessToken:(NSString *)token { ++ (id) sharedInstanceWithAccessToken:(NSString *)token { static dispatch_once_t onceToken; - static MapboxGL *_sharedManager; dispatch_once(&onceToken, ^{ if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { void (^setupBlock)() = ^{ @@ -36,4 +38,11 @@ return _sharedManager; } ++ (NSString *) getAccessToken { + if (_sharedManager) { + return _sharedManager.accessToken; + } + return nil; +} + @end \ No newline at end of file From 5d7dbf917f81605415bd408da7c23e2e26571433 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 24 Apr 2015 08:13:17 +0200 Subject: [PATCH 010/373] clipper union with evenodd fill type --- src/mbgl/renderer/fill_bucket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index f5726690b..0c789ace7 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -84,7 +84,7 @@ void FillBucket::tessellate() { hasVertices = false; std::vector> polygons; - clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftPositive); + clipper.Execute(ClipperLib::ctUnion, polygons, ClipperLib::pftEvenOdd, ClipperLib::pftEvenOdd); clipper.Clear(); if (polygons.size() == 0) { @@ -132,7 +132,7 @@ void FillBucket::tessellate() { lineGroup.elements_length += total_vertex_count; - if (tessTesselate(tesselator, TESS_WINDING_POSITIVE, TESS_POLYGONS, vertices_per_group, vertexSize, 0)) { + if (tessTesselate(tesselator, TESS_WINDING_ODD, TESS_POLYGONS, vertices_per_group, vertexSize, 0)) { const TESSreal *vertices = tessGetVertices(tesselator); const size_t vertex_count = tessGetVertexCount(tesselator); TESSindex *vertex_indices = const_cast(tessGetVertexIndices(tesselator)); From 317be3470827ab278e930240b71fefee3fe87c02 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 24 Apr 2015 15:29:34 -0500 Subject: [PATCH 011/373] #1225 - Removing unavailable block on MGLMapView.initWithFrame --- include/mbgl/ios/MGLMapView.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index eb9a770dc..e6aaee9a0 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -38,8 +38,6 @@ IB_DESIGNABLE * @return An initialized map view, or `nil` if the map view was unable to be initialized. */ - (instancetype)initWithFrame:(CGRect)frame accessToken:(NSString *)accessToken styleURL:(NSURL *)styleURL; -- (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("Instantiating an MGLMapView requires setting a style and/or an access token."))); - #pragma mark - Authorizing Access /** @name Authorizing Access */ From 591c63286b6471a6c769eb17d8e1b16c698a4e11 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 24 Apr 2015 15:41:21 -0500 Subject: [PATCH 012/373] #1225 - Converting id to instancetype --- include/mbgl/ios/MapboxGL.h | 2 +- platform/ios/MapboxGL.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index 4e5ff09b2..8470591d5 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -5,7 +5,7 @@ @interface MapboxGL : NSObject -+ (id) sharedInstanceWithAccessToken:(NSString *)token; ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token; + (NSString *) getAccessToken; @end \ No newline at end of file diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m index 97ac8f1d5..0c8812821 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MapboxGL.m @@ -17,7 +17,7 @@ static MapboxGL *_sharedManager; // Can be called from any thread. Called implicitly from any // public class convenience methods. // -+ (id) sharedInstanceWithAccessToken:(NSString *)token { ++ (instancetype) sharedInstanceWithAccessToken:(NSString *)token { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { From f96046103f3800b95e80753f4b63435d4946fcd0 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 24 Apr 2015 16:09:50 -0500 Subject: [PATCH 013/373] #1225 - Starting Mapbox Events at shared instance setup time --- platform/ios/MapboxGL.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/ios/MapboxGL.m b/platform/ios/MapboxGL.m index 0c8812821..7c542cb36 100644 --- a/platform/ios/MapboxGL.m +++ b/platform/ios/MapboxGL.m @@ -2,6 +2,7 @@ #import "MapboxGL.h" #import "NSProcessInfo+MGLAdditions.h" +#import "MGLMapboxEvents.h" @interface MapboxGL() @@ -24,6 +25,7 @@ static MapboxGL *_sharedManager; void (^setupBlock)() = ^{ _sharedManager = [[self alloc] init]; _sharedManager.accessToken = token; + [MGLMapboxEvents setToken:token]; }; if ( ! [[NSThread currentThread] isMainThread]) { dispatch_sync(dispatch_get_main_queue(), ^{ From ad1cc3f1ad62c75409617e22c14e2985c43092b6 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sat, 25 Apr 2015 10:25:47 -0700 Subject: [PATCH 014/373] fix SSL pinning for apps including the framework Made it clearer when we are referring to the app bundle and when we need to get the framework bundle for resources such as pinned certificates. --- platform/ios/MGLMapboxEvents.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index ee1ae82e7..554956f31 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -111,13 +111,13 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; if (self) { // Put Settings bundle into memory - NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; - if(!settingsBundle) { + NSString *appSettingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; + if(!appSettingsBundle) { NSLog(@"Could not find Settings.bundle"); } else { // Dynamic Settings.bundle loading based on: // http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the - NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]]; + NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[appSettingsBundle stringByAppendingPathComponent:@"Root.plist"]]; NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"]; NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]]; for(NSDictionary *prefSpecification in preferences) { @@ -143,7 +143,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; NSArray *bundles = [NSBundle allFrameworks]; for (int lc = 0; lc < bundles.count; lc++) { NSBundle *b = [bundles objectAtIndex:lc]; - cerPath = [[NSBundle mainBundle] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"]; + cerPath = [[NSBundle bundleForClass:[MGLMapboxEvents class]] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"]; if (cerPath != nil) { break; } From 86e90da6d506dc89c315a6ea407df89eae0b4729 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 10:55:12 -0400 Subject: [PATCH 015/373] #1346 - Removing allFrameworks iteration search for the bundle as it's not needed now --- platform/ios/MGLMapboxEvents.m | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 554956f31..b32e13988 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -140,14 +140,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; // Load Local Copy of Server's Public Key NSString *cerPath = nil; - NSArray *bundles = [NSBundle allFrameworks]; - for (int lc = 0; lc < bundles.count; lc++) { - NSBundle *b = [bundles objectAtIndex:lc]; - cerPath = [[NSBundle bundleForClass:[MGLMapboxEvents class]] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"]; - if (cerPath != nil) { - break; - } - } + cerPath = [[NSBundle bundleForClass:[MGLMapboxEvents class]] pathForResource:@"api_mapbox_com-geotrust" ofType:@"der"]; if (cerPath != nil) { _geoTrustCert = [NSData dataWithContentsOfFile:cerPath]; } From 50fecb916dc466d49b868602648c862e525d9ec7 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 11:43:23 -0400 Subject: [PATCH 016/373] #1345 - Adding app build number to user agent. Updating gl test app build number to be different from build version. --- include/mbgl/ios/MGLMapboxEvents.h | 1 + ios/app/app-info.plist | 2 +- platform/ios/MGLMapView.mm | 2 ++ platform/ios/MGLMapboxEvents.m | 12 ++++++++++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/mbgl/ios/MGLMapboxEvents.h b/include/mbgl/ios/MGLMapboxEvents.h index 7a4c45fe1..c6cd13308 100644 --- a/include/mbgl/ios/MGLMapboxEvents.h +++ b/include/mbgl/ios/MGLMapboxEvents.h @@ -32,6 +32,7 @@ extern NSString *const MGLEventGestureRotateStart; + (void) setToken:(NSString *)token; + (void) setAppName:(NSString *)appName; + (void) setAppVersion:(NSString *)appVersion; ++ (void) setAppBuildNumber:(NSString *)appBuildNumber; + (void) pauseMetricsCollection; + (void) resumeMetricsCollection; diff --git a/ios/app/app-info.plist b/ios/app/app-info.plist index cd74f5839..fd03e7324 100644 --- a/ios/app/app-info.plist +++ b/ios/app/app-info.plist @@ -21,7 +21,7 @@ CFBundleSignature MBGL CFBundleVersion - 0.0.2 + 0.0.3 LSRequiresIPhoneOS NSHumanReadableCopyright diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index f9ed77041..b61679a7d 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -223,8 +223,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // metrics: initial setup NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; + NSString *appBuildNumber = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; if (appName != nil) [MGLMapboxEvents setAppName:appName]; if (appVersion != nil) [MGLMapboxEvents setAppVersion:appVersion]; + if (appBuildNumber != nil) [MGLMapboxEvents setAppBuildNumber:appBuildNumber]; // create GL view // diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index b32e13988..b714c927d 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -62,6 +62,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; @property (atomic) NSString *token; @property (atomic) NSString *appName; @property (atomic) NSString *appVersion; +@property (atomic) NSString *appBuildNumber; @property (atomic) NSString *instanceID; @property (atomic) NSString *advertiserId; @property (atomic) NSString *vendorId; @@ -247,6 +248,13 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; [MGLMapboxEvents sharedManager].appVersion = appVersion; } +// Must be called from the main thread. +// ++ (void) setAppBuildNumber:(NSString *)appBuildNumber { + assert([[NSThread currentThread] isMainThread]); + [MGLMapboxEvents sharedManager].appBuildNumber = appBuildNumber; +} + // Must be called from the main thread. // + (void) pauseMetricsCollection { @@ -455,8 +463,8 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; // Can be called from any thread. // - (NSString *) getUserAgent { - if (self.appName != nil && self.appVersion != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) { - self.userAgent = [NSString stringWithFormat:@"%@/%@ %@", self.appName, self.appVersion, self.userAgent]; + if (self.appName != nil && self.appVersion != nil && self.appBuildNumber != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) { + self.userAgent = [NSString stringWithFormat:@"%@/%@-%@ %@", self.appName, self.appVersion, self.appBuildNumber, self.userAgent]; } return self.userAgent; } From cde989093baaf8fac2c4287fd462cf419abf1052 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 12:22:05 -0400 Subject: [PATCH 017/373] #1307 - Adding digicert to sdks and ssl handshaking check --- platform/ios/MGLMapboxEvents.m | 22 ++++++++++++++++++ .../ios/resources/api_mapbox_com-digicert.der | Bin 0 -> 2077 bytes 2 files changed, 22 insertions(+) create mode 100644 platform/ios/resources/api_mapbox_com-digicert.der diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index b32e13988..42c1dc07c 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -74,6 +74,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; @property (atomic) NSDateFormatter *rfc3339DateFormatter; @property (atomic) CGFloat scale; @property (atomic) NSURLSession *session; +@property (atomic) NSData *digicertCert; @property (atomic) NSData *geoTrustCert; @@ -145,6 +146,12 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; _geoTrustCert = [NSData dataWithContentsOfFile:cerPath]; } + cerPath = nil; + cerPath = [[NSBundle bundleForClass:[MGLMapboxEvents class]] pathForResource:@"api_mapbox_com-digicert" ofType:@"der"]; + if (cerPath != nil) { + _digicertCert = [NSData dataWithContentsOfFile:cerPath]; + } + // Events Control _eventQueue = [[NSMutableArray alloc] init]; _flushAt = 20; @@ -679,6 +686,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; long numKeys = SecTrustGetCertificateCount(serverTrust); BOOL found = false; + // Try GeoTrust Cert First for (int lc = 0; lc < numKeys; lc++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); @@ -692,6 +700,20 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; } } + // Fallback to Digicert Cert + for (int lc = 0; lc < numKeys; lc++) { + SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); + NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); + + // Compare Remote Key With Local Version + if ([remoteCertificateData isEqualToData:_digicertCert]) { + // Found the certificate; continue connecting + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + found = true; + break; + } + } + if (!found) { // The certificate wasn't found in the certificate chain; cancel the connection completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); diff --git a/platform/ios/resources/api_mapbox_com-digicert.der b/platform/ios/resources/api_mapbox_com-digicert.der new file mode 100644 index 0000000000000000000000000000000000000000..d84cee390869435b9b0672232b5597f347b67faf GIT binary patch literal 2077 zcma)7Yfuwc6yDuz0to~H8v&I^6tp5G+zlWvm64#*3JRhi_!t8TAsRwVLV^k+Tg3;W zw#Z-|R0PBq)QYGm7=-ctKoq5eqG<75-++RMb~g$I@ke(iGkd;s?m6H6?%pqeFdhmB zBRHRizzD)&??_&K^*|G^`OTg;?T(vf0ycv=HX|tGJsXBi=nzQ4O#qWYn~gFsWOg_{ z1YlIa!b}5YQkhVq((ry##NtDNH3ges9Gy{%tl4(U632%l8Op7+D9ezr5RjYEJo!$HPVL zF=b{;bJUJ|1Mv3=-ANs3#I4Z3qjc-ihb{NlHs7V+p6>nh(1~o;u{(-Zs3WeVd6)g= z4$0_srzFDMK)VMGkM7oSb}`=u&o$a`!8)X8j^F1toU^~6s`^Hu5}vz_b8xdFB-Q_N zWc1DsW_M{#P1pV~tVHS7bj+s_MGl7I`i z8jaG|%`H|XcOP)u-PG|SfvZI8sy5tYS1HaXYX-0K_&=)xsIffM5BLBt26JIX5S-B? zM_@1(jOitZz*e>t7d1)dTjy~ThK7UmwY{Y-QYnSE7A z#+2U8iYQN04=8l&^)$-TdL8XQL;K=q!bzkE8iQNdVU*|ype|_|gJp21#-#{~pah&q z{uaYBNDCDmXKpUHnZsREi4|OyDp}(_x1wFcTPj+0SIo|{n>i2!2S3%FvxFd&22BN% zkrB|NL;q}$;(k?`f(F-9RZYnDnt)r?x}CbzqwI@O-Jb&$qKlDnLYj?f*nZj|w z4ii4DSf7xUXdxXG!DVc7`>XbOL&yD-fn^iVP0=2&`rTsQ zsaIRJ&Td>+f9K2G^H&XXgTNHB>$}h8QK=Q)_Dey!zwl|L!vbt zEm^V=Ef9MpFb_dY8$V=car~fq<6wl*rRcZY;DoL zD^;c4$+N=D+I~7TV&Bg`(a*e_UlV>-tHMkg{@n4&(y>_Z;cY>)^Q;Bsl^^b%)_*pU zwZ572AVr$jm1+uAPA492yB6x}du++CAH>6UPA=GJW2?7ZWRvkPMYQPf zVuxw-)ExH{HJ=XpuBoO83pmVWqi@gf7OI+FIH#Puw`o=VEQ|I!MBuC}D`|SX^ky7; z%z@n{`X!l9dKxuxRYPd3jx+bguSR-B6s(>ZaJV{tbGB{S4-cP|C7qPkdyh!+vAw6N zZ%kc(ttBOGid)X;il(DjcD41L=yGYkR}YdC=bT&?5GdO2r0qO$&t2bA5qI`q0a@|y literal 0 HcmV?d00001 From c9e5435035e19c008df61af152a70d289cdc948b Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 16:14:14 -0400 Subject: [PATCH 018/373] #1307 - Optimizing fallback to digicert check strategy --- platform/ios/MGLMapboxEvents.m | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 87a6ccc6a..fa2a27f78 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -708,23 +708,25 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; } } - // Fallback to Digicert Cert - for (int lc = 0; lc < numKeys; lc++) { - SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); - NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); - - // Compare Remote Key With Local Version - if ([remoteCertificateData isEqualToData:_digicertCert]) { - // Found the certificate; continue connecting - completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); - found = true; - break; - } - } - if (!found) { - // The certificate wasn't found in the certificate chain; cancel the connection - completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + // Fallback to Digicert Cert + for (int lc = 0; lc < numKeys; lc++) { + SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, lc); + NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate)); + + // Compare Remote Key With Local Version + if ([remoteCertificateData isEqualToData:_digicertCert]) { + // Found the certificate; continue connecting + completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + found = true; + break; + } + } + + if (!found) { + // The certificate wasn't found in GeoTrust nor Digicert. Cancel the connection. + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } } } else From 5092d7259909eee85e518bdc996ab06307bc7bad Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 17:37:39 -0400 Subject: [PATCH 019/373] #1352 - Adding start / stop visit monitoring infrastructure and integrating it with pause / resume metrics api --- include/mbgl/ios/MGLMetricsLocationManager.h | 2 ++ platform/ios/MGLMapboxEvents.m | 2 ++ platform/ios/MGLMetricsLocationManager.m | 15 +++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/include/mbgl/ios/MGLMetricsLocationManager.h b/include/mbgl/ios/MGLMetricsLocationManager.h index 5f3b56818..da5cffbcd 100644 --- a/include/mbgl/ios/MGLMetricsLocationManager.h +++ b/include/mbgl/ios/MGLMetricsLocationManager.h @@ -7,5 +7,7 @@ + (instancetype)sharedManager; + (void) startUpdatingLocation; + (void) stopUpdatingLocation; ++ (void) startMonitoringVisits; ++ (void) stopMonitoringVisits; @end diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 87a6ccc6a..5e4016bb8 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -271,6 +271,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; } [MGLMapboxEvents sharedManager].isPaused = YES; [MGLMetricsLocationManager stopUpdatingLocation]; + [MGLMetricsLocationManager stopMonitoringVisits]; } // Must be called from the main thread. @@ -282,6 +283,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; } [MGLMapboxEvents sharedManager].isPaused = NO; [MGLMetricsLocationManager startUpdatingLocation]; + [MGLMetricsLocationManager startMonitoringVisits]; } // Can be called from any thread. Can be called rapidly from diff --git a/platform/ios/MGLMetricsLocationManager.m b/platform/ios/MGLMetricsLocationManager.m index af9b0a71b..eea137f69 100644 --- a/platform/ios/MGLMetricsLocationManager.m +++ b/platform/ios/MGLMetricsLocationManager.m @@ -37,6 +37,18 @@ [[MGLMetricsLocationManager sharedManager].locationManager stopUpdatingLocation]; } ++ (void) startMonitoringVisits { + if ([[MGLMetricsLocationManager sharedManager].locationManager respondsToSelector:@selector(startMonitoringVisits)]) { + [[MGLMetricsLocationManager sharedManager].locationManager startMonitoringVisits]; + } +} + ++ (void) stopMonitoringVisits { + if ([[MGLMetricsLocationManager sharedManager].locationManager respondsToSelector:@selector(stopMonitoringVisits)]) { + [[MGLMetricsLocationManager sharedManager].locationManager stopMonitoringVisits]; + } +} + #pragma mark CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { // Iterate through locations to pass all data @@ -65,10 +77,12 @@ case kCLAuthorizationStatusDenied: newStatus = @"User Explcitly Denied"; [MGLMetricsLocationManager stopUpdatingLocation]; + [MGLMetricsLocationManager stopMonitoringVisits]; break; case kCLAuthorizationStatusAuthorized: newStatus = @"User Has Authorized / Authorized Always"; [MGLMetricsLocationManager startUpdatingLocation]; + [MGLMetricsLocationManager startMonitoringVisits]; break; // case kCLAuthorizationStatusAuthorizedAlways: // newStatus = @"Not Determined"; @@ -76,6 +90,7 @@ case kCLAuthorizationStatusAuthorizedWhenInUse: newStatus = @"User Has Authorized When In Use Only"; [MGLMetricsLocationManager startUpdatingLocation]; + [MGLMetricsLocationManager startMonitoringVisits]; break; default: newStatus = @"Unknown"; From 16bcdb10b840b9063acd1894aba3cf395cd90bf2 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 18:00:31 -0400 Subject: [PATCH 020/373] #1352 - Adding visit event with data attributes --- include/mbgl/ios/MGLMapboxEvents.h | 3 +++ platform/ios/MGLMapboxEvents.m | 3 +++ platform/ios/MGLMetricsLocationManager.m | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/include/mbgl/ios/MGLMapboxEvents.h b/include/mbgl/ios/MGLMapboxEvents.h index c6cd13308..c70c7cb33 100644 --- a/include/mbgl/ios/MGLMapboxEvents.h +++ b/include/mbgl/ios/MGLMapboxEvents.h @@ -4,6 +4,7 @@ extern NSString *const MGLEventTypeMapLoad; extern NSString *const MGLEventTypeMapTap; extern NSString *const MGLEventTypeMapDragEnd; extern NSString *const MGLEventTypeLocation; +extern NSString *const MGLEventTypeVisit; extern NSString *const MGLEventKeyLatitude; extern NSString *const MGLEventKeyLongitude; @@ -16,6 +17,8 @@ extern NSString *const MGLEventKeyVerticalAccuracy; extern NSString *const MGLEventKeyPushEnabled; extern NSString *const MGLEventKeyEmailEnabled; extern NSString *const MGLEventKeyGestureID; +extern NSString *const MGLEventKeyArrivalDate; +extern NSString *const MGLEventKeyDepartureDate; extern NSString *const MGLEventGestureSingleTap; extern NSString *const MGLEventGestureDoubleTap; diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 5e4016bb8..5355204ff 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -17,6 +17,7 @@ NSString *const MGLEventTypeMapLoad = @"map.load"; NSString *const MGLEventTypeMapTap = @"map.click"; NSString *const MGLEventTypeMapDragEnd = @"map.dragend"; NSString *const MGLEventTypeLocation = @"location"; +NSString *const MGLEventTypeVisit = @"visit"; NSString *const MGLEventKeyLatitude = @"lat"; NSString *const MGLEventKeyLongitude = @"lng"; @@ -29,6 +30,8 @@ NSString *const MGLEventKeyVerticalAccuracy = @"verticalAccuracy"; NSString *const MGLEventKeyPushEnabled = @"enabled.push"; NSString *const MGLEventKeyEmailEnabled = @"enabled.email"; NSString *const MGLEventKeyGestureID = @"gesture"; +NSString *const MGLEventKeyArrivalDate = @"arrivalDate"; +NSString *const MGLEventKeyDepartureDate = @"departureDate"; NSString *const MGLEventGestureSingleTap = @"SingleTap"; NSString *const MGLEventGestureDoubleTap = @"DoubleTap"; diff --git a/platform/ios/MGLMetricsLocationManager.m b/platform/ios/MGLMetricsLocationManager.m index eea137f69..348c4e5ad 100644 --- a/platform/ios/MGLMetricsLocationManager.m +++ b/platform/ios/MGLMetricsLocationManager.m @@ -6,6 +6,7 @@ @interface MGLMetricsLocationManager() @property (nonatomic) CLLocationManager *locationManager; +@property (atomic) NSDateFormatter *rfc3339DateFormatter; @end @@ -16,6 +17,15 @@ _locationManager = [[CLLocationManager alloc] init]; _locationManager.distanceFilter = 10; [_locationManager setDelegate:self]; + + _rfc3339DateFormatter = [[NSDateFormatter alloc] init]; + NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + + [_rfc3339DateFormatter setLocale:enUSPOSIXLocale]; + [_rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"]; + // Clear Any System TimeZone Cache + [NSTimeZone resetSystemTimeZone]; + [_rfc3339DateFormatter setTimeZone:[NSTimeZone systemTimeZone]]; } return self; } @@ -65,6 +75,16 @@ } } +- (void)locationManager:(CLLocationManager *)manager didVisit:(CLVisit *)visit { + [MGLMapboxEvents pushEvent:MGLEventTypeVisit withAttributes:@{ + MGLEventKeyLatitude: @(visit.coordinate.latitude), + MGLEventKeyLongitude: @(visit.coordinate.longitude), + MGLEventKeyHorizontalAccuracy: @(visit.horizontalAccuracy), + MGLEventKeyArrivalDate: [_rfc3339DateFormatter stringFromDate:visit.arrivalDate], + MGLEventKeyDepartureDate: [_rfc3339DateFormatter stringFromDate:visit.departureDate], + }]; +} + - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { NSString *newStatus = nil; switch (status) { From 2b4969b5dc487479154837ba3ab13fab10efc0e1 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 18:44:51 -0400 Subject: [PATCH 021/373] #1352 - Adding date checker to arrival and departure date to make arrival / departure determination easier --- platform/ios/MGLMetricsLocationManager.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/ios/MGLMetricsLocationManager.m b/platform/ios/MGLMetricsLocationManager.m index 348c4e5ad..b64fc44c1 100644 --- a/platform/ios/MGLMetricsLocationManager.m +++ b/platform/ios/MGLMetricsLocationManager.m @@ -80,8 +80,8 @@ MGLEventKeyLatitude: @(visit.coordinate.latitude), MGLEventKeyLongitude: @(visit.coordinate.longitude), MGLEventKeyHorizontalAccuracy: @(visit.horizontalAccuracy), - MGLEventKeyArrivalDate: [_rfc3339DateFormatter stringFromDate:visit.arrivalDate], - MGLEventKeyDepartureDate: [_rfc3339DateFormatter stringFromDate:visit.departureDate], + MGLEventKeyArrivalDate: [[NSDate distantPast] isEqualToDate:visit.arrivalDate] ? [NSNull null] : [_rfc3339DateFormatter stringFromDate:visit.arrivalDate], + MGLEventKeyDepartureDate: [[NSDate distantFuture] isEqualToDate:visit.departureDate] ? [NSNull null] : [_rfc3339DateFormatter stringFromDate:visit.departureDate] }]; } From 5ffa52cab5556639a327471e1927787af6a18231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Mon, 27 Apr 2015 15:52:30 -0700 Subject: [PATCH 022/373] Automatically find view controller for layout guides Find the managing view controller by traversing the responder chain. --- include/mbgl/ios/MGLMapView.h | 5 ----- ios/app/MBXViewController.mm | 1 - platform/ios/MGLMapView.mm | 42 +++++++++++++++++++---------------- test/ios/MGLTViewController.m | 1 - 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 8717b5e8a..88d75088b 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -46,11 +46,6 @@ IB_DESIGNABLE /** @name Managing Constraints */ -/** A view controller whose top and bottom layout guides to use for proper setup of constraints in the map view internals. -* -* Certain components of the map view, such as the heading compass and the data attribution button, need to be aware of the view controller layout in order to avoid positioning content under a top navigation bar or a bottom toolbar. */ -@property (nonatomic, weak) IBOutlet UIViewController *viewControllerForLayoutGuides; - #pragma mark - Accessing Map Properties /** @name Accessing Map Properties */ diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 13235beb0..98c8e016d 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -67,7 +67,6 @@ mbgl::Settings_NSUserDefaults *settings = nullptr; self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.mapView.viewControllerForLayoutGuides = self; self.mapView.showsUserLocation = YES; self.mapView.delegate = self; [self.view addSubview:self.mapView]; diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index b61679a7d..d90f99e0e 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -323,8 +323,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [container addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleCompassTapGesture:)]]; [self addSubview:container]; - self.viewControllerForLayoutGuides = nil; - // setup interaction // _pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; @@ -476,15 +474,22 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [self setNeedsUpdateConstraints]; } -- (void)setViewControllerForLayoutGuides:(UIViewController *)viewController +- (UIViewController *)viewControllerForLayoutGuides { - _viewControllerForLayoutGuides = viewController; - - [self.compass.superview removeConstraints:self.compass.superview.constraints]; - [self.logoBug removeConstraints:self.logoBug.constraints]; - [self.attributionButton removeConstraints:self.attributionButton.constraints]; - - [self setNeedsUpdateConstraints]; + // Per -[UIResponder nextResponder] documentation, a UIView’s next responder + // is its managing UIViewController if applicable, or otherwise its + // superview. UIWindow’s next responder is UIApplication, which has no next + // responder. + UIResponder *laterResponder = self; + while ([laterResponder isKindOfClass:[UIView class]]) + { + laterResponder = laterResponder.nextResponder; + } + if ([laterResponder isKindOfClass:[UIViewController class]]) + { + return (UIViewController *)laterResponder; + } + return nil; } - (void)updateConstraints @@ -493,21 +498,20 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // views so they don't underlap navigation or tool bars. If we don't have a reference, apply // constraints against ourself to maintain (albeit less ideal) placement of the subviews. // - UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? - self.viewControllerForLayoutGuides.view : - self); + UIViewController *viewController = self.viewControllerForLayoutGuides; + UIView *constraintParentView = (viewController.view ? viewController.view : self); // compass // UIView *compassContainer = self.compass.superview; - if (self.viewControllerForLayoutGuides) + if (viewController) { [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:compassContainer attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual - toItem:self.viewControllerForLayoutGuides.topLayoutGuide + toItem:viewController.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1 constant:5]]; @@ -550,10 +554,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // logo bug // - if (self.viewControllerForLayoutGuides) + if (viewController) { [constraintParentView addConstraint: - [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + [NSLayoutConstraint constraintWithItem:viewController.bottomLayoutGuide attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.logoBug @@ -581,10 +585,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // attribution button // - if (self.viewControllerForLayoutGuides) + if (viewController) { [constraintParentView addConstraint: - [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + [NSLayoutConstraint constraintWithItem:viewController.bottomLayoutGuide attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.attributionButton diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m index e8b500b43..bdce2202d 100644 --- a/test/ios/MGLTViewController.m +++ b/test/ios/MGLTViewController.m @@ -12,7 +12,6 @@ _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:@"pk.eyJ1IjoianVzdGluIiwiYSI6Ik9RX3RRQzAifQ.dmOg_BAp1ywuDZMM7YsXRg"]; - _mapView.viewControllerForLayoutGuides = self; _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview:_mapView]; From 2407ab6c9bd8aec1cb313b03e81e3b4078f6be22 Mon Sep 17 00:00:00 2001 From: Peter Liu Date: Mon, 27 Apr 2015 16:26:38 -0700 Subject: [PATCH 023/373] update emerald style and sprite assets --- styles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/styles b/styles index 0ba580207..161c28951 160000 --- a/styles +++ b/styles @@ -1 +1 @@ -Subproject commit 0ba580207b4e915530ee4efc20cb1ac0d5575f49 +Subproject commit 161c289517d945af94bf1c66aa68acc8e9d46776 From 3040b6462e70fbd17c297f52966f23d3161282a5 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 21:19:45 -0400 Subject: [PATCH 024/373] #1345 - Changing -buildNumber to /buildNumber --- platform/ios/MGLMapboxEvents.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index fa2a27f78..fdc50ab94 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -471,7 +471,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; // - (NSString *) getUserAgent { if (self.appName != nil && self.appVersion != nil && self.appBuildNumber != nil && ([self.userAgent rangeOfString:self.appName].location == NSNotFound)) { - self.userAgent = [NSString stringWithFormat:@"%@/%@-%@ %@", self.appName, self.appVersion, self.appBuildNumber, self.userAgent]; + self.userAgent = [NSString stringWithFormat:@"%@/%@/%@ %@", self.appName, self.appVersion, self.appBuildNumber, self.userAgent]; } return self.userAgent; } From 56c82837a4195810c106c1bec8607323e7652112 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Mon, 27 Apr 2015 21:49:26 -0400 Subject: [PATCH 025/373] bump podspec version to 0.2.16 --- ios/MapboxGL.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/MapboxGL.podspec b/ios/MapboxGL.podspec index 57de3f6f3..19f920326 100644 --- a/ios/MapboxGL.podspec +++ b/ios/MapboxGL.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |m| m.name = 'MapboxGL' - m.version = '0.2.15' + m.version = '0.2.16' m.summary = 'Open source vector map solution for iOS with full styling capabilities.' m.description = 'Open source OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa bindings.' From f6ad59c33a3d1a42d9e18b927166546ac4ef3bb0 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Mon, 27 Apr 2015 21:50:13 -0400 Subject: [PATCH 026/373] [publish ios-v0.2.16] From 2b633cc51cd44be3f0224f0b105b18f0a3d7d657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 16 Apr 2015 16:46:12 +0200 Subject: [PATCH 027/373] build on Travis' sudo: false infrastructure --- .mason | 2 +- .travis.yml | 156 +++++++++--------- Makefile | 21 ++- README.md | 2 +- android/scripts/build-debug.sh | 8 - android/scripts/build-release.sh | 8 - android/scripts/common.sh | 40 ----- android/scripts/run-build.sh | 85 ---------- config/defaults.mk | 14 +- configure | 3 +- docker/linux/test.sh | 26 --- platform/default/asset_request_fs.cpp | 2 +- platform/default/asset_request_zip.cpp | 2 +- scripts/android/install.sh | 15 ++ scripts/android/run.sh | 61 +++++++ scripts/android/toolchain.sh | 26 +++ scripts/android_env.sh | 25 --- scripts/flags.sh | 32 ---- scripts/install_node.sh | 4 - scripts/{ios_travis => ios}/add-key.sh | 8 +- .../after_failure.sh} | 0 scripts/{ios_travis => ios}/apple.crt | Bin scripts/ios/install.sh | 15 ++ scripts/{ios_travis => ios}/ios-dist.cer.enc | 0 scripts/{ios_travis => ios}/ios-dist.p12.enc | 0 .../ios-in-house.mobileprovision.enc | 0 scripts/{package_ios.sh => ios/package.sh} | 0 scripts/{publish_ios.sh => ios/publish.sh} | 0 scripts/{ios_travis => ios}/remove-key.sh | 0 scripts/ios/run.sh | 35 ++++ scripts/linux/install.sh | 13 ++ scripts/linux/run.sh | 75 +++++++++ scripts/local_mason.sh | 5 - scripts/npm_install.sh | 8 - scripts/osx/install.sh | 13 ++ scripts/osx/run.sh | 27 +++ scripts/travis_before_install.sh | 53 ------ scripts/travis_helper.sh | 28 ++-- scripts/travis_script.sh | 71 -------- scripts/xcpretty.sh | 3 + src/mbgl/storage/default_file_source.cpp | 2 +- src/mbgl/style/style_parser.cpp | 1 + test/test.gypi | 3 + 43 files changed, 419 insertions(+), 473 deletions(-) delete mode 100755 android/scripts/build-debug.sh delete mode 100755 android/scripts/build-release.sh delete mode 100755 android/scripts/common.sh delete mode 100755 android/scripts/run-build.sh delete mode 100755 docker/linux/test.sh create mode 100755 scripts/android/install.sh create mode 100755 scripts/android/run.sh create mode 100755 scripts/android/toolchain.sh delete mode 100755 scripts/android_env.sh delete mode 100755 scripts/flags.sh delete mode 100755 scripts/install_node.sh rename scripts/{ios_travis => ios}/add-key.sh (61%) rename scripts/{ios_travis/upload_screenshots.sh => ios/after_failure.sh} (100%) rename scripts/{ios_travis => ios}/apple.crt (100%) create mode 100755 scripts/ios/install.sh rename scripts/{ios_travis => ios}/ios-dist.cer.enc (100%) rename scripts/{ios_travis => ios}/ios-dist.p12.enc (100%) rename scripts/{ios_travis => ios}/ios-in-house.mobileprovision.enc (100%) rename scripts/{package_ios.sh => ios/package.sh} (100%) rename scripts/{publish_ios.sh => ios/publish.sh} (100%) rename scripts/{ios_travis => ios}/remove-key.sh (100%) create mode 100755 scripts/ios/run.sh create mode 100755 scripts/linux/install.sh create mode 100755 scripts/linux/run.sh delete mode 100755 scripts/local_mason.sh delete mode 100755 scripts/npm_install.sh create mode 100755 scripts/osx/install.sh create mode 100755 scripts/osx/run.sh delete mode 100755 scripts/travis_before_install.sh delete mode 100755 scripts/travis_script.sh create mode 100755 scripts/xcpretty.sh diff --git a/.mason b/.mason index 03869fd11..c43967404 160000 --- a/.mason +++ b/.mason @@ -1 +1 @@ -Subproject commit 03869fd11e4bc619d3ba7e4f8a1f00d4612c90ea +Subproject commit c43967404c84d020d63f6aba450d97770dfeaebb diff --git a/.travis.yml b/.travis.yml index 71936b872..82190742e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,100 +1,106 @@ -language: cpp +language: android + +sudo: false + +addons: + apt: + sources: + - boost-latest + - ubuntu-toolchain-r-test + packages: + - gdb # for printing stack traces from core dumps + - gcc-4.8 + - g++-4.8 + - llvm-3.4 + - xutils-dev + - libxxf86vm-dev + - x11proto-xf86vidmode-dev + - mesa-utils # for glxinfo + - libboost-dev + - libboost-program-options-dev + - lib32stdc++6 # for Gradle's aapt + - lib32z1 # for Gradle's aapt matrix: exclude: - os: linux include: - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v7 TESTMUNK=yes - compiler: clang + env: FLAVOR=linux CXX=g++-4.8 BUILDTYPE=Release - os: linux - env: CONFIG=debug MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v7 TESTMUNK=no - compiler: clang + env: FLAVOR=linux CXX=clang++ BUILDTYPE=Debug - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v5 TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=arm-v8 TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=x86 TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=mips TESTMUNK=no - compiler: clang - - os: linux - env: CONFIG=release MASON_PLATFORM=android MASON_ANDROID_ABI=mips-64 TESTMUNK=no - compiler: clang - - os: linux - env: BUILDTYPE=Release JOBS=16 - compiler: clang - - os: linux - env: BUILDTYPE=Debug JOBS=16 - compiler: clang - - os: linux - env: BUILDTYPE=Release JOBS=8 - compiler: gcc + env: FLAVOR=linux CXX=clang++ BUILDTYPE=Release - os: osx - env: BUILDTYPE=Debug JOBS=8 MASON_PLATFORM=osx - compiler: clang + env: FLAVOR=osx BUILDTYPE=Debug - os: osx - env: BUILDTYPE=Release JOBS=8 MASON_PLATFORM=ios - compiler: clang + env: FLAVOR=ios BUILDTYPE=Release + - os: linux + env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Release + android: + components: + - build-tools-22.0.0 + - android-22 + - extra + - os: linux + env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Debug + android: + components: + - build-tools-22.0.0 + - android-22 + - extra + - os: linux + env: FLAVOR=android ANDROID_ABI=arm-v8 BUILDTYPE=Release + android: + components: + - build-tools-22.0.0 + - android-22 + - extra + - os: linux + env: FLAVOR=android ANDROID_ABI=x86 BUILDTYPE=Release + android: + components: + - build-tools-22.0.0 + - android-22 + - extra + - os: linux + env: FLAVOR=android ANDROID_ABI=mips BUILDTYPE=Release + android: + components: + - build-tools-22.0.0 + - android-22 + - extra env: global: - - secure: "MZHblLZXG/jWf2w0ZFlxCLDwx2qtGgRDODQyg1BR7JIuMz6AtWv8XR/sUczWLbiABCL0a/NzJF1g4v2pI7X69IntcjOdIABBgTh7++6+1TJ0Kp8viEltb55nQG3lHy/R6fOaI7Pj9tuCX0PCRtGA5C/fGnodLGEjy3RVOJ09ln0=" - - secure: "KaSQbhgjtV7ZCkesHmvrNsbQVjk5SPfGKB1VkWenRGYhLF45HpSRNwSxMQddZ566Pg7qIFgF1iWl/B0QW3B6AWL5WmzQ5AOJgwS876pNIc/UT7ubMPtgAtjpvw1bQvQP3B8MrB+3OE5c6tD+a3LhR9krV//dOsfErR5Yy+3Mbkc=" - - ANDROID_BUILD_INSTANCE_PROFILE: arn:aws:iam::234858372212:instance-profile/android-gl-build/travis/instance-profile/travis-mapbox-gl-native-AndroidInstanceProfile-13EA815DD8IQ9 - - secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I=" - - secure: "CHBiUM60TolDbQnn+4IRA/tvOKwKs3g9EDvv8YHSJMg3FuHmjKQkprBasvxf3hnTXg4WLZEubmeDcyJ6RRzPP5mMSr/hksYl0pSjj/6TUecE5fHPVVeN7txVqkpOBf9i45Y+iBUQMjBb1NnDK3pHXxpnAs1Q/pe7vReErj4GF1U=" - - LD_LIBRARY_PATH: '/usr/local/lib' - - TERM: dumb - # begin iOS code signing - - secure: "I6Iu75X1E+js5tzijtKi1EGtIuBcA4/25nDYe0svV4HAtujY71ZJZ4eB6355CKhFXpLXrF3i7eKVX3v+zWS0QROPEWacgsqsvNg+Ba9cnznW/faUSOYekCfhzWd/6reYDM7KzKAQwSUHLk9JIWK/kkmi4r+vVJK7h+tjPllK5YA=" - - IOS_APP_NAME="Mapbox GL" - - 'IOS_DEVELOPER_NAME="iPhone Distribution: Mapbox, Inc."' - - IOS_PROFILE_NAME="ios-in-house" - - secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA=" - # end iOS code signing - - KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/screenshots" - -before_install: -- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service mysql stop; fi -- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo service postgresql stop; fi -- source ./scripts/local_mason.sh -- source ./scripts/travis_helper.sh -- source ./scripts/install_node.sh -- source ./scripts/flags.sh -- ./scripts/travis_before_install.sh -- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib; fi -- if [[ ${TRAVIS_OS_NAME} == "linux" && ${MASON_PLATFORM} != "android" ]]; then glxinfo; fi -- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then mkdir -p ${KIF_SCREENSHOTS}; fi + - TERM: dumb + # AWS + - secure: "MZHblLZXG/jWf2w0ZFlxCLDwx2qtGgRDODQyg1BR7JIuMz6AtWv8XR/sUczWLbiABCL0a/NzJF1g4v2pI7X69IntcjOdIABBgTh7++6+1TJ0Kp8viEltb55nQG3lHy/R6fOaI7Pj9tuCX0PCRtGA5C/fGnodLGEjy3RVOJ09ln0=" + - secure: "KaSQbhgjtV7ZCkesHmvrNsbQVjk5SPfGKB1VkWenRGYhLF45HpSRNwSxMQddZ566Pg7qIFgF1iWl/B0QW3B6AWL5WmzQ5AOJgwS876pNIc/UT7ubMPtgAtjpvw1bQvQP3B8MrB+3OE5c6tD+a3LhR9krV//dOsfErR5Yy+3Mbkc=" + # Access Token + - secure: "RiBIBfVhhaMjU5ksuwJO3shdvG9FpinBjdSv4co9jg9171SR8edNriedHjVKSIeBhSGNmZmX+twS3dJS/By6tl/LKh9sTynA+ZAYYljkE7jn881B/gMrlYvdAA6og5KvkhV1/0iJWlhuZrMTkhpDR200iLgg3EWBhWjltzmDW/I=" + # Testmunk + - secure: "CHBiUM60TolDbQnn+4IRA/tvOKwKs3g9EDvv8YHSJMg3FuHmjKQkprBasvxf3hnTXg4WLZEubmeDcyJ6RRzPP5mMSr/hksYl0pSjj/6TUecE5fHPVVeN7txVqkpOBf9i45Y+iBUQMjBb1NnDK3pHXxpnAs1Q/pe7vReErj4GF1U=" + # iOS code signing + - secure: "I6Iu75X1E+js5tzijtKi1EGtIuBcA4/25nDYe0svV4HAtujY71ZJZ4eB6355CKhFXpLXrF3i7eKVX3v+zWS0QROPEWacgsqsvNg+Ba9cnznW/faUSOYekCfhzWd/6reYDM7KzKAQwSUHLk9JIWK/kkmi4r+vVJK7h+tjPllK5YA=" + - IOS_APP_NAME="Mapbox GL" + - 'IOS_DEVELOPER_NAME="iPhone Distribution: Mapbox, Inc."' + - IOS_PROFILE_NAME="ios-in-house" + - secure: "nQqSM8rd7OHtV4MqmNqVnkrVHqxKqQsaWRYk4/nPdhbeVWtTtkk0df711LrF1TUtbEPEewHxYUvTZ/UXmwJNeoKdzTHavI8hnatRkgjyxGERPn1il1Otelht9I+LQQHf+plrpRjVWBrNIW0Zox1B3cqn6d3NglpbXrEQ2EjYGNA=" + - KIF_SCREENSHOTS="${TRAVIS_BUILD_DIR}/screenshots" install: -- ulimit -c - -before_script: - # Set the core file limit to unlimited so a core file is generated upon crash - - ulimit -c unlimited -S - # begin iOS code signing - - openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-in-house.mobileprovision.enc -d -a -out scripts/ios_travis/ios-in-house.mobileprovision - - openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-dist.cer.enc -d -a -out scripts/ios_travis/ios-dist.cer - - openssl aes-256-cbc -k "$IOS_ENCRYPTION_SECRET" -in scripts/ios_travis/ios-dist.p12.enc -d -a -out scripts/ios_travis/ios-dist.p12 - - ./scripts/ios_travis/add-key.sh - # end iOS code signing +- ./scripts/${FLAVOR}/install.sh script: -- ./scripts/travis_script.sh - -after_script: -- ./scripts/ios_travis/remove-key.sh +- ./scripts/${FLAVOR}/run.sh after_failure: -- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then ./scripts/ios_travis/upload_screenshots.sh; fi +- if [ -f scripts/${FLAVOR}/run.sh ]; then /scripts/${FLAVOR}/after_failure.sh; fi notifications: slack: secure: HHQYr7sF8M1SzoWSqgKVYtwAgGdLLCyTMsQjFhEEQNYO92ZwURE5s03qWTGH5k8+4Yqn26yrXt3NztLC4JIOpcGervN2mSZyq4dZgFTcWEd61igw0qwSenlwvFfbE1ASK/KYCzfyn9MIfHN+ovwLoRxXZkPwinKDvl3DXjBaFNg= + git: submodules: false diff --git a/Makefile b/Makefile index 11eb5e530..66a7ecb65 100644 --- a/Makefile +++ b/Makefile @@ -31,8 +31,12 @@ config/%.gypi: configure styles/styles: git submodule update --init styles +ifeq ($(shell uname -s), Darwin) SMCalloutView: git submodule update --init platform/ios/vendor/SMCalloutView +else +SMCalloutView: +endif KIF: git submodule update --init test/ios/KIF @@ -71,8 +75,9 @@ test-%: test ./scripts/run_tests.sh "build/$(HOST)/$(BUILDTYPE)/test" --gtest_filter=$* .PHONY: xtest +xtest: XCPRETTY := $(shell ./scripts/xcpretty.sh) xtest: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) $(XCPRETTY) xtest-%: xtest ./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$* @@ -91,8 +96,9 @@ run-osx: osx xosx-proj: Xcode/project open ./build/osx/gyp/project.xcodeproj +xosx: XCPRETTY := $(shell ./scripts/xcpretty.sh) xosx: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) $(XCPRETTY) run-xosx: xosx "gyp/build/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" @@ -112,14 +118,16 @@ Xcode/ios: ios/app/mapboxgl-app.gyp config/ios.gypi styles/styles SMCalloutView ios-proj: Xcode/ios open ./build/ios/ios/app/mapboxgl-app.xcodeproj +ios: XCPRETTY := $(shell ./scripts/xcpretty.sh) ios: Xcode/ios - xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) + xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) $(XCPRETTY) +isim: XCPRETTY := $(shell ./scripts/xcpretty.sh) isim: Xcode/ios - xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) + xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) $(XCPRETTY) ipackage: clean Xcode/ios - ./scripts/package_ios.sh + ./scripts/ios/package.sh itest: ipackage KIF ./scripts/test_ios.sh @@ -138,8 +146,9 @@ run-linux: linux (cd build/$(HOST)/$(BUILDTYPE) && ./mapbox-gl) .PHONY: xlinux run-xlinux +xlinux: XCPRETTY := $(shell ./scripts/xcpretty.sh) xlinux: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) $(XCPRETTY) run-xlinux: xlinux "gyp/build/$(BUILDTYPE)/mapbox-gl" diff --git a/README.md b/README.md index a44b13861..d2ded1be0 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Target OS X: 10.9+ If you merely want to install the library for iOS and try it out as an Objective-C consumer: 0. Use [Homebrew](http://brew.sh/) to install Boost headers: `brew install boost`. -1. Run `./scripts/package_ios.sh`. The packaging script will produce the statically-linked `libMapboxGL.a`, `MapboxGL.bundle` for resources, and a `Headers` folder. +1. Run `./scripts/ios/package.sh`. The packaging script will produce the statically-linked `libMapboxGL.a`, `MapboxGL.bundle` for resources, and a `Headers` folder. 2. Copy the contents of `build/ios/pkg/static` into your project. It should happen automatically, but ensure that: - `Headers` is in your *Header Search Paths* (`HEADER_SEARCH_PATHS`) build setting. - `MapboxGL.bundle` is in your target's *Copy Bundle Resources* build phase. diff --git a/android/scripts/build-debug.sh b/android/scripts/build-debug.sh deleted file mode 100755 index 450820a11..000000000 --- a/android/scripts/build-debug.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -export BUILDTYPE=Debug - -./android/scripts/common.sh $1 diff --git a/android/scripts/build-release.sh b/android/scripts/build-release.sh deleted file mode 100755 index 73c7fab81..000000000 --- a/android/scripts/build-release.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -export BUILDTYPE=Release - -./android/scripts/common.sh $1 diff --git a/android/scripts/common.sh b/android/scripts/common.sh deleted file mode 100755 index 0d610909b..000000000 --- a/android/scripts/common.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -NAME=$1 - -case `uname -s` in - 'Darwin') export JOBS=`sysctl -n hw.ncpu` ;; - 'Linux') export JOBS=`nproc` ;; - *) export JOBS=1 ;; -esac - - -export CC=clang CXX=clang++ -export MASON_PLATFORM=android - -mkdir -p ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/ -echo "${MAPBOX_ACCESS_TOKEN}" >> ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/token.txt - -make android -j$JOBS BUILDTYPE=$BUILDTYPE JOBS=$JOBS - -S3_PREFIX=s3://mapbox/mapbox-gl-native/android/build/${NAME} -APK_OUTPUTS=./android/java/MapboxGLAndroidSDKTestApp/build/outputs/apk - -# Upload the shared object. -aws s3 cp \ - ./build/android-${ANDROID_ABI}/${BUILDTYPE}/lib.target/libmapbox-gl.so \ - ${S3_PREFIX}/libmapbox-gl.so - -# Upload either the debug or the release build -if [ ${BUILDTYPE} == "Debug" ] ; then - aws s3 cp \ - ${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-debug.apk \ - ${S3_PREFIX}/MapboxGLAndroidSDKTestApp-debug.apk -elif [ ${BUILDTYPE} == "Release" ] ; then - aws s3 cp \ - ${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-release-unsigned.apk \ - ${S3_PREFIX}/MapboxGLAndroidSDKTestApp-release-unsigned.apk -fi diff --git a/android/scripts/run-build.sh b/android/scripts/run-build.sh deleted file mode 100755 index 9fa15a02b..000000000 --- a/android/scripts/run-build.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -cwd=$(pwd) - -region="us-east-1" -region_ami="ami-022e0c6a" -sleep=10 -instance_name="android-gl-build-$TRAVIS_REPO_SLUG-$TRAVIS_JOB_NUMBER" -echo $ami_name - -NAME=$TRAVIS_JOB_ID - -user_data="#!/bin/bash - cd /android - git clone git://github.com/mapbox/mapbox-gl-native.git - - pushd mapbox-gl-native - if [[ $TRAVIS_PULL_REQUEST == 'false' ]]; then - git checkout $TRAVIS_COMMIT - else - git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge: - git checkout FETCH_HEAD - fi - git submodule update --init --recursive - - export ANDROID_NDK_PATH=/android/android-ndk-r10d - export JAVA_HOME=/android/jdk1.7.0_71 - export ANDROID_HOME=/android/android-sdk-linux - export PATH=\$PATH:/android/jdk1.7.0_71/bin - export MAPBOX_ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN - export TESTMUNK_KEY=$TESTMUNK_KEY - export TESTMUNK=$TESTMUNK - export MASON_ANDROID_ABI=$MASON_ANDROID_ABI - export ANDROID_ABI=$MASON_ANDROID_ABI - - if ./android/scripts/build-$CONFIG.sh $NAME &>../build.log; then - echo 'ANDROID BUILD PASSED' - else - echo 'ANDROID BUILD FAILED' - fi - popd - - aws s3 cp --region us-east-1 build.log s3://mapbox/mapbox-gl-native/android/build/${NAME}/build-log.txt - shutdown -P now" - -id=$(aws ec2 run-instances \ - --region $region \ - --image-id $region_ami \ - --count 1 \ - --instance-type m3.large \ - --iam-instance-profile Arn="$ANDROID_BUILD_INSTANCE_PROFILE" \ - --instance-initiated-shutdown-behavior terminate \ - --user-data "$user_data" | jq -r '.Instances[0].InstanceId') - -echo "Instance: $region $id" - -sleep 10 - -result=$(aws ec2 create-tags --region $region --resources $id --tags "Key=Name,Value=$instance_name") - -instance_status_terminated=$(aws ec2 describe-instances --region $region --instance-id $id | jq -r '.Reservations[0].Instances[0].State.Name') - -until [ "$instance_status_terminated" = "terminated" ]; do - instance_status_terminated=$(aws ec2 describe-instances --region $region --instance-id $id | jq -r '.Reservations[0].Instances[0].State.Name') - echo "Instance terminating status $region $id: $instance_status_terminated" - sleep $sleep -done - -echo "Build finished" - -output=$(aws ec2 get-console-output --region $region --instance-id $id | jq -r '.Output') - -aws s3 cp --region $region s3://mapbox/mapbox-gl-native/android/build/${NAME}/build-log.txt build.log -cat build.log - -if [[ $output == *"ANDROID BUILD PASSED"* ]]; then - echo "ANDROID BUILD PASSED" - exit 0 -else - echo "ANDROID BUILD FAILED" - exit 1 -fi diff --git a/config/defaults.mk b/config/defaults.mk index 2aa11ccbe..1449bf8e1 100644 --- a/config/defaults.mk +++ b/config/defaults.mk @@ -31,32 +31,32 @@ LIBS_linux += -Dcache_lib=$(word 1,$(CACHE) sqlite) LIBS_linux += --depth=. -Goutput_dir=. ANDROID_ABIS += android-lib-arm-v8 -ENV_android-arm-v8 = $(shell MASON_ANDROID_ABI=arm-v8 ./scripts/android_env.sh) +ENV_android-arm-v8 = $(shell MASON_ANDROID_ABI=arm-v8 ./scripts/android/toolchain.sh) CONFIG_android-arm-v8 = -Dhost=android -Iconfig/android-arm-v8.gypi ANDROID_ABIS += android-lib-arm-v7 -ENV_android-arm-v7 = $(shell MASON_ANDROID_ABI=arm-v7 ./scripts/android_env.sh) +ENV_android-arm-v7 = $(shell MASON_ANDROID_ABI=arm-v7 ./scripts/android/toolchain.sh) CONFIG_android-arm-v7 = -Dhost=android -Iconfig/android-arm-v7.gypi ANDROID_ABIS += android-lib-arm-v5 -ENV_android-arm-v5 = $(shell MASON_ANDROID_ABI=arm-v5 ./scripts/android_env.sh) +ENV_android-arm-v5 = $(shell MASON_ANDROID_ABI=arm-v5 ./scripts/android/toolchain.sh) CONFIG_android-arm-v5 = -Dhost=android -Iconfig/android-arm-v5.gypi ANDROID_ABIS += android-lib-x86 -ENV_android-x86 = $(shell MASON_ANDROID_ABI=x86 ./scripts/android_env.sh) +ENV_android-x86 = $(shell MASON_ANDROID_ABI=x86 ./scripts/android/toolchain.sh) CONFIG_android-x86 = -Dhost=android -Iconfig/android-x86.gypi # OpenSSL build is incomplete. # ANDROID_ABIS += android-lib-x86-64 -# ENV_android-x86-64 = $(shell MASON_ANDROID_ABI=x86-64 ./scripts/android_env.sh) +# ENV_android-x86-64 = $(shell MASON_ANDROID_ABI=x86-64 ./scripts/android/toolchain.sh) # CONFIG_android-x86-64 = -Dhost=android -Iconfig/android-x86-64.gypi ANDROID_ABIS += android-lib-mips -ENV_android-mips = $(shell MASON_ANDROID_ABI=mips ./scripts/android_env.sh) +ENV_android-mips = $(shell MASON_ANDROID_ABI=mips ./scripts/android/toolchain.sh) CONFIG_android-mips = -Dhost=android -Iconfig/android-mips.gypi ANDROID_ABIS += android-lib-mips-64 -ENV_android-mips-64 = $(shell MASON_ANDROID_ABI=mips-64 ./scripts/android_env.sh) +ENV_android-mips-64 = $(shell MASON_ANDROID_ABI=mips-64 ./scripts/android/toolchain.sh) CONFIG_android-mips-64 = -Dhost=android -Iconfig/android-mips-64.gypi LIBS_android = -Dheadless_lib=none diff --git a/configure b/configure index 1d68f5e54..a37000a1b 100755 --- a/configure +++ b/configure @@ -15,7 +15,8 @@ function finish { trap finish EXIT # Install mason -. ./scripts/local_mason.sh +git submodule update --init .mason +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" case ${MASON_PLATFORM} in 'ios') diff --git a/docker/linux/test.sh b/docker/linux/test.sh deleted file mode 100755 index 9ef9bf51f..000000000 --- a/docker/linux/test.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -export TRAVIS_OS_NAME=linux - -cd build - -source ./scripts/local_mason.sh -mason install mesa 10.4.3 -export LD_LIBRARY_PATH=`mason prefix mesa 10.4.3`/lib - -export DISPLAY=:99.0 -Xvfb :99 -ac -screen 0 1024x768x24 & - -if [[ ${CXX} == "g++" ]]; then - export CXX="g++-4.8" - export CC="gcc-4.8" -fi - -source ./scripts/install_node.sh - -make linux -j`nproc` -make test-* -j`nproc` -./scripts/compare_images.sh diff --git a/platform/default/asset_request_fs.cpp b/platform/default/asset_request_fs.cpp index a7d813b72..08b336ad3 100644 --- a/platform/default/asset_request_fs.cpp +++ b/platform/default/asset_request_fs.cpp @@ -7,9 +7,9 @@ #include #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" #ifndef __clang__ #pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#pragma GCC diagnostic ignored "-Wshadow" #endif #include #pragma GCC diagnostic pop diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp index 22d426c76..f66ca619b 100644 --- a/platform/default/asset_request_zip.cpp +++ b/platform/default/asset_request_zip.cpp @@ -8,9 +8,9 @@ #include "uv_zip.h" #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" #ifndef __clang__ #pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#pragma GCC diagnostic ignored "-Wshadow" #endif #include #pragma GCC diagnostic pop diff --git a/scripts/android/install.sh b/scripts/android/install.sh new file mode 100755 index 000000000..656465cf2 --- /dev/null +++ b/scripts/android/install.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +source ./scripts/travis_helper.sh + +mapbox_time "checkout_mason" \ +git submodule update --init .mason + +export MASON_PLATFORM=android +export MASON_ANDROID_ABI=${ANDROID_ABI} + +mapbox_time "android_toolchain" \ +./scripts/android/toolchain.sh diff --git a/scripts/android/run.sh b/scripts/android/run.sh new file mode 100755 index 000000000..7a909ffe3 --- /dev/null +++ b/scripts/android/run.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +BUILDTYPE=${BUILDTYPE:-Release} +TESTMUNK=${TESTMUNK:-no} +export HOST=android +export MASON_PLATFORM=android +export MASON_ANDROID_ABI=${ANDROID_ABI:-arm-v7} + +source ./scripts/travis_helper.sh + +# Add Mason to PATH +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +################################################################################ +# Build +################################################################################ + +mapbox_time "checkout_styles" \ +git submodule update --init styles + +mkdir -p ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw +echo "${MAPBOX_ACCESS_TOKEN}" > ./android/java/MapboxGLAndroidSDKTestApp/src/main/res/raw/token.txt + +mapbox_time "compile_library" \ +make android-lib -j${JOBS} BUILDTYPE=${BUILDTYPE} + +mapbox_time "build_apk" \ +make android -j${JOBS} BUILDTYPE=${BUILDTYPE} + +################################################################################ +# Deploy +################################################################################ + +if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then + # Install and add awscli to PATH for uploading the results + mapbox_time "install_awscli" \ + pip install --user awscli + export PATH="`python -m site --user-base`/bin:${PATH}" + + mapbox_time_start "deploy_results" + echo "Deploying results..." + + S3_PREFIX=s3://mapbox/mapbox-gl-native/android/build/${TRAVIS_JOB_NUMBER} + APK_OUTPUTS=./android/java/MapboxGLAndroidSDKTestApp/build/outputs/apk + + # Upload either the debug or the release build + if [ ${BUILDTYPE} == "Debug" ] ; then + aws s3 cp \ + ${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-debug.apk \ + ${S3_PREFIX}/MapboxGLAndroidSDKTestApp-debug.apk + elif [ ${BUILDTYPE} == "Release" ] ; then + aws s3 cp \ + ${APK_OUTPUTS}/MapboxGLAndroidSDKTestApp-release-unsigned.apk \ + ${S3_PREFIX}/MapboxGLAndroidSDKTestApp-release-unsigned.apk + fi + + mapbox_time_finish +fi diff --git a/scripts/android/toolchain.sh b/scripts/android/toolchain.sh new file mode 100755 index 000000000..67cd0aa47 --- /dev/null +++ b/scripts/android/toolchain.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +export MASON_PLATFORM=android +export MASON_ANDROID_ABI=${MASON_ANDROID_ABI:-arm-v7} +export PATH="`pwd`/.mason:${PATH}" +export MASON_DIR="`pwd`/.mason" + +export PATH=`mason env PATH` + +echo MASON_PLATFORM=\"${MASON_PLATFORM}\" +echo MASON_ANDROID_ABI=\"${MASON_ANDROID_ABI}\" +echo CXX=\"`which $(mason env CXX)`\" +echo CC=\"`which $(mason env CC)`\" +echo LD=\"`which $(mason env LD)`\" +echo LINK=\"`which $(mason env CXX)`\" +echo AR=\"`which $(mason env AR)`\" +echo RANLIB=\"`which $(mason env RANLIB)`\" +echo STRIP=\"`which $(mason env STRIP)`\" +echo LDFLAGS=\"`mason env LDFLAGS` \${LDFLAGS:-}\" +echo CFLAGS=\"`mason env CFLAGS` \${CFLAGS:-}\" +echo CXXFLAGS=\"`mason env CXXFLAGS` \${CXXFLAGS:-}\" +echo CPPFLAGS=\"`mason env CPPFLAGS` \${CPPFLAGS:-}\" +echo JNIDIR=\"`mason env JNIDIR`\" diff --git a/scripts/android_env.sh b/scripts/android_env.sh deleted file mode 100755 index 93b1452a5..000000000 --- a/scripts/android_env.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -./scripts/local_mason.sh - -export MASON_PLATFORM=android - -export PATH=`.mason/mason env PATH` - -echo MASON_PLATFORM=\"android\" -echo MASON_ANDROID_ABI=\"${MASON_ANDROID_ABI}\" - -echo CXX=\"`which $(.mason/mason env CXX)`\" -echo CC=\"`which $(.mason/mason env CC)`\" -echo LD=\"`which $(.mason/mason env LD)`\" -echo LINK=\"`which $(.mason/mason env CXX)`\" -echo AR=\"`which $(.mason/mason env AR)`\" -echo RANLIB=\"`which $(.mason/mason env RANLIB)`\" -echo STRIP=\"`which $(.mason/mason env STRIP)`\" -echo LDFLAGS=\"`.mason/mason env LDFLAGS` ${LDFLAGS}\" -echo CFLAGS=\"`.mason/mason env CFLAGS` ${CFLAGS}\" -echo CPPFLAGS=\"`.mason/mason env CPPFLAGS` ${CPPFLAGS}\" -echo JNIDIR=\"`.mason/mason env JNIDIR`\" diff --git a/scripts/flags.sh b/scripts/flags.sh deleted file mode 100755 index 10cc88e5c..000000000 --- a/scripts/flags.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then - export DISPLAY=:99.0 - - if [[ ${MASON_PLATFORM} != "android" ]]; then - sh -e /etc/init.d/xvfb start - fi - - # use g++ that supports c++11 - if [[ ${CXX} == "g++" ]]; then - export CXX="g++-4.8" - export CC="gcc-4.8" - fi - - # If building in debug then turn on sanitizers. - # They should both work with latest g++/clang++ - # but it's not worth a standalone matrix so here - # we just test address->gcc and thread->clang for - # some limited coverage - # if [[ ${BUILDTYPE} == "Debug" ]]; then - # if [[ ${CXX} == "g++" ]]; then - # export CXXFLAGS="-fsanitize=address -g ${CXXFLAGS}" - # export CFLAGS="-fsanitize=address -g ${CFLAGS}" - # export LDFLAGS="-fsanitize=address ${LDFLAGS}" - # elif [[ ${CXX} == "clang++" ]]; then - # export CXXFLAGS="-fsanitize=thread -g -fPIC ${CXXFLAGS}" - # export CFLAGS="-fsanitize=thread -g ${CFLAGS}" - # export LDFLAGS="-fsanitize=thread -pie ${LDFLAGS}" - # fi - # fi -fi diff --git a/scripts/install_node.sh b/scripts/install_node.sh deleted file mode 100755 index ecb5b8835..000000000 --- a/scripts/install_node.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -mason install node 0.10.35 -export PATH="`mason prefix node 0.10.35`/bin":"$PATH" diff --git a/scripts/ios_travis/add-key.sh b/scripts/ios/add-key.sh similarity index 61% rename from scripts/ios_travis/add-key.sh rename to scripts/ios/add-key.sh index b58144530..fe963d38e 100755 --- a/scripts/ios_travis/add-key.sh +++ b/scripts/ios/add-key.sh @@ -16,10 +16,10 @@ security unlock-keychain -p travis ios-build.keychain security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain # Add certificates to keychain and allow codesign to access them -security import ./scripts/ios_travis/apple.crt -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign -security import ./scripts/ios_travis/ios-dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign -security import ./scripts/ios_travis/ios-dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $IOS_KEY_PASSWORD -T /usr/bin/codesign +security import ./scripts/ios/apple.crt -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign +security import ./scripts/ios/ios-dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign +security import ./scripts/ios/ios-dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $IOS_KEY_PASSWORD -T /usr/bin/codesign # Put the provisioning profile in place mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles -cp "./scripts/ios_travis/$IOS_PROFILE_NAME.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/ +cp "./scripts/ios/$IOS_PROFILE_NAME.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/ diff --git a/scripts/ios_travis/upload_screenshots.sh b/scripts/ios/after_failure.sh similarity index 100% rename from scripts/ios_travis/upload_screenshots.sh rename to scripts/ios/after_failure.sh diff --git a/scripts/ios_travis/apple.crt b/scripts/ios/apple.crt similarity index 100% rename from scripts/ios_travis/apple.crt rename to scripts/ios/apple.crt diff --git a/scripts/ios/install.sh b/scripts/ios/install.sh new file mode 100755 index 000000000..9e649e450 --- /dev/null +++ b/scripts/ios/install.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +source ./scripts/travis_helper.sh + +mapbox_time "checkout_mason" \ +git submodule update --init .mason +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +mapbox_time "install_xcpretty" \ +gem install xcpretty --no-rdoc --no-ri --no-document --quiet + +mkdir -p ${KIF_SCREENSHOTS} diff --git a/scripts/ios_travis/ios-dist.cer.enc b/scripts/ios/ios-dist.cer.enc similarity index 100% rename from scripts/ios_travis/ios-dist.cer.enc rename to scripts/ios/ios-dist.cer.enc diff --git a/scripts/ios_travis/ios-dist.p12.enc b/scripts/ios/ios-dist.p12.enc similarity index 100% rename from scripts/ios_travis/ios-dist.p12.enc rename to scripts/ios/ios-dist.p12.enc diff --git a/scripts/ios_travis/ios-in-house.mobileprovision.enc b/scripts/ios/ios-in-house.mobileprovision.enc similarity index 100% rename from scripts/ios_travis/ios-in-house.mobileprovision.enc rename to scripts/ios/ios-in-house.mobileprovision.enc diff --git a/scripts/package_ios.sh b/scripts/ios/package.sh similarity index 100% rename from scripts/package_ios.sh rename to scripts/ios/package.sh diff --git a/scripts/publish_ios.sh b/scripts/ios/publish.sh similarity index 100% rename from scripts/publish_ios.sh rename to scripts/ios/publish.sh diff --git a/scripts/ios_travis/remove-key.sh b/scripts/ios/remove-key.sh similarity index 100% rename from scripts/ios_travis/remove-key.sh rename to scripts/ios/remove-key.sh diff --git a/scripts/ios/run.sh b/scripts/ios/run.sh new file mode 100755 index 000000000..abb4c2cb0 --- /dev/null +++ b/scripts/ios/run.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -u + +BUILDTYPE=${BUILDTYPE:-Release} + +source ./scripts/travis_helper.sh + +# Add Mason to PATH +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +PUBLISH_TAG=($(git show -s --format=%B | sed -n 's/.*\[publish \([a-z]\{1,\}\)-v\([0-9.]\{1,\}\)\].*/\1 \2/p')) +PUBLISH_PLATFORM=${PUBLISH_TAG[0],-} +PUBLISH_VERSION=${PUBLISH_TAG[1],-} + + +################################################################################ +# Build +################################################################################ + +if [[ ${PUBLISH_PLATFORM} = 'ios' ]]; then + # build & package iOS + mapbox_time "package_ios" \ + make ipackage + + # publish iOS build + mapbox_time "deploy_ios" \ + ./scripts/publish_ios.sh "${PUBLISH_VERSION}" +else + # build & test iOS + mapbox_time "run_ios_tests" \ + make itest +fi diff --git a/scripts/linux/install.sh b/scripts/linux/install.sh new file mode 100755 index 000000000..a6ffacf5f --- /dev/null +++ b/scripts/linux/install.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +source ./scripts/travis_helper.sh + +mapbox_time "checkout_mason" \ +git submodule update --init .mason +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +mapbox_time "install_mesa" \ +mason install mesa 10.4.3 diff --git a/scripts/linux/run.sh b/scripts/linux/run.sh new file mode 100755 index 000000000..c4731b97e --- /dev/null +++ b/scripts/linux/run.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +BUILDTYPE=${BUILDTYPE:-Release} + +source ./scripts/travis_helper.sh + +# Add Mason to PATH +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +# Set the core file limit to unlimited so a core file is generated upon crash +ulimit -c unlimited -S + +################################################################################ +# X Server setup +################################################################################ + +# Start the mock X server +if [ -f /etc/init.d/xvfb ] ; then + mapbox_time "start_xvfb" \ + sh -e /etc/init.d/xvfb start + sleep 2 # sometimes, xvfb takes some time to start up +fi + +# Make sure we're connecting to xvfb +export DISPLAY=:99.0 + +# Make sure we're loading the 10.4.3 libs we installed manually +export LD_LIBRARY_PATH="`mason prefix mesa 10.4.3`/lib:${LD_LIBRARY_PATH:-}" + +mapbox_time "glxinfo" \ +glxinfo + +################################################################################ +# Build +################################################################################ + +mapbox_time "checkout_styles" \ +git submodule update --init styles + +mapbox_time "compile_program" \ +make linux -j${JOBS} BUILDTYPE=${BUILDTYPE} + +mapbox_time "compile_tests" \ +make test -j${JOBS} BUILDTYPE=${BUILDTYPE} + +################################################################################ +# Test +################################################################################ + +mapbox_time "checkout_test_suite" \ +git submodule update --init test/suite + +mapbox_time "run_tests" \ +make test-* BUILDTYPE=${BUILDTYPE} + +mapbox_time "compare_results" \ +./scripts/compare_images.sh + +################################################################################ +# Deploy +################################################################################ + +if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then + # Install and add awscli to PATH for uploading the results + mapbox_time "install_awscli" \ + pip install --user awscli + export PATH="`python -m site --user-base`/bin:${PATH}" + + mapbox_time_start "deploy_results" + (cd ./test/suite/ && ./bin/deploy_results.sh) + mapbox_time_finish +fi diff --git a/scripts/local_mason.sh b/scripts/local_mason.sh deleted file mode 100755 index 2d8687a28..000000000 --- a/scripts/local_mason.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -git submodule update --init .mason -PATH=`pwd`/.mason:$PATH -export MASON_DIR=`pwd`/.mason diff --git a/scripts/npm_install.sh b/scripts/npm_install.sh deleted file mode 100755 index 7437af961..000000000 --- a/scripts/npm_install.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -cd bin -$1 install --clang=1 -cd ../ diff --git a/scripts/osx/install.sh b/scripts/osx/install.sh new file mode 100755 index 000000000..1994d371d --- /dev/null +++ b/scripts/osx/install.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +source ./scripts/travis_helper.sh + +mapbox_time "checkout_mason" \ +git submodule update --init .mason +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +mapbox_time "install_xcpretty" \ +gem install xcpretty --no-rdoc --no-ri --no-document --quiet diff --git a/scripts/osx/run.sh b/scripts/osx/run.sh new file mode 100755 index 000000000..b84ed04c2 --- /dev/null +++ b/scripts/osx/run.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail + +BUILDTYPE=${BUILDTYPE:-Release} + +source ./scripts/travis_helper.sh + +# Add Mason to PATH +export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason" + +# Set the core file limit to unlimited so a core file is generated upon crash +ulimit -c unlimited -S + +################################################################################ +# Build +################################################################################ + +mapbox_time "checkout_styles" \ +git submodule update --init styles + +mapbox_time "compile_program" \ +make xosx -j${JOBS} BUILDTYPE=${BUILDTYPE} + +mapbox_time "compile_tests" \ +make xtest -j${JOBS} BUILDTYPE=${BUILDTYPE} diff --git a/scripts/travis_before_install.sh b/scripts/travis_before_install.sh deleted file mode 100755 index f837e7416..000000000 --- a/scripts/travis_before_install.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then - # - # install Linux dependencies - # - if [[ `lsb_release -r` =~ "12.04" ]]; then - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test - fi - sudo add-apt-repository --yes ppa:boost-latest/ppa - - mapbox_time "apt_update" \ - sudo apt-get update -y - - mapbox_time "install_gcc" \ - sudo apt-get -y install gcc-4.8 g++-4.8 - - mapbox_time "install_build_tools" \ - sudo apt-get -y install git build-essential zlib1g-dev automake gdb \ - libtool xutils-dev make cmake pkg-config python-pip \ - libboost1.55-dev libcurl4-openssl-dev \ - libpng-dev libsqlite3-dev - - if [[ ${MASON_PLATFORM} != "android" ]]; then - mapbox_time "install_opengl" \ - sudo apt-get -y install mesa-utils libxi-dev x11proto-randr-dev \ - x11proto-xext-dev libxrandr-dev \ - x11proto-xf86vidmode-dev libxxf86vm-dev \ - libxcursor-dev libxinerama-dev \ - llvm-3.4 # required for mesa - - mapbox_time "install_mesa" \ - mason install mesa 10.4.3 - fi - - mapbox_time "install_awscli" \ - sudo pip install awscli -elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then - # - # install OS X dependencies - # - mapbox_time "install_build_tools" \ - brew install git - - mapbox_time "install_awscli" \ - sudo pip install awscli - - mapbox_time "install_xcpretty" \ - gem install xcpretty --no-rdoc --no-ri --no-document --quiet -fi diff --git a/scripts/travis_helper.sh b/scripts/travis_helper.sh index c42ce215e..5e7dd46f4 100755 --- a/scripts/travis_helper.sh +++ b/scripts/travis_helper.sh @@ -1,13 +1,21 @@ #!/usr/bin/env bash +case `uname -s` in + 'Darwin') JOBS=$((`sysctl -n hw.ncpu` + 2)) ;; + 'Linux') JOBS=$((`nproc` + 2)) ;; + *) JOBS=2 ;; +esac + +ANSI_CLEAR="\e[0m" + function mapbox_time_start { local name=$1 mapbox_timer_name=$name - travis_fold start $name + mapbox_fold start $name mapbox_timer_id=$(printf %08x $(( RANDOM * RANDOM ))) - eval "mapbox_start_time_$mapbox_timer_id=$(travis_nanoseconds)" + eval "mapbox_start_time_$mapbox_timer_id=$(mapbox_nanoseconds)" echo -en "travis_time:start:$mapbox_timer_id\n" } @@ -16,11 +24,11 @@ function mapbox_time_finish { local timer_id=${2:-$mapbox_timer_id} local timer_start="mapbox_start_time_$timer_id" eval local start_time=\${$timer_start} - local end_time=$(travis_nanoseconds) + local end_time=$(mapbox_nanoseconds) local duration=$(($end_time-$start_time)) echo -en "travis_time:end:$timer_id:start=$start_time,finish=$end_time,duration=$duration\n" - travis_fold end $name + mapbox_fold end $name } function mapbox_time { @@ -32,13 +40,13 @@ function mapbox_time { mapbox_time_finish $name $timer_id } -if [[ "${TRAVIS_COMMIT:-false}" == false ]]; then -function travis_fold { +function mapbox_fold { local action=$1 local name=$2 echo -en "travis_fold:${action}:${name}\r${ANSI_CLEAR}" } -function travis_nanoseconds { + +function mapbox_nanoseconds { local cmd="date" local format="+%s%N" local os=$(uname) @@ -51,11 +59,11 @@ function travis_nanoseconds { $cmd -u $format } -fi +export JOBS export ANSI_CLEAR -export -f travis_fold -export -f travis_nanoseconds +export -f mapbox_fold +export -f mapbox_nanoseconds export -f mapbox_time export -f mapbox_time_start export -f mapbox_time_finish diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh deleted file mode 100755 index 093b31273..000000000 --- a/scripts/travis_script.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash - -COMMIT_MESSAGE=$(git show -s --format=%B $1 | tr -d '\n') -PUBLISH_TAG=$(echo "$COMMIT_MESSAGE" | grep -oE '\[publish [a-z0-9\.\-]+\]' | grep -oE '[a-z0-9\.\-]+' | tail -n1) -PUBLISH_PLATFORM=$(echo "$PUBLISH_TAG" | awk -F '-v' '{ print $1 }') -PUBLISH_VERSION=$(echo "$PUBLISH_TAG" | awk -F '-v' '{ print $2 }') - -set -e -set -o pipefail - -mapbox_time "checkout_styles" \ -git submodule update --init styles - -if [[ $MASON_PLATFORM == "android" ]]; then - ./android/scripts/run-build.sh - -elif [[ ${TRAVIS_OS_NAME} == "linux" ]]; then - # - # build & test Linux - # - mapbox_time "compile_program" \ - make linux -j$JOBS BUILDTYPE=${BUILDTYPE} - - mapbox_time "compile_tests" \ - make test -j$JOBS BUILDTYPE=${BUILDTYPE} - - mapbox_time "checkout_test_suite" \ - git submodule update --init test/suite - - mapbox_time "run_tests" \ - make test-* BUILDTYPE=${BUILDTYPE} - - mapbox_time "compare_results" \ - ./scripts/compare_images.sh - - if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then - mapbox_time_start "deploy_results" - (cd ./test/suite/ && ./bin/deploy_results.sh) - mapbox_time_finish - fi - -elif [[ ${TRAVIS_OS_NAME} == "osx" && ${MASON_PLATFORM} == "osx" ]]; then - # - # build OS X - # - mapbox_time "build_osx" \ - make xosx -j$JOBS - -elif [[ ${TRAVIS_OS_NAME} == "osx" && ${MASON_PLATFORM} == "ios" ]]; then - # - # conditionally publish or test - # - if [[ -n "$PUBLISH_TAG" ]]; then - # - # build & package iOS - # - mapbox_time "package_ios" - make ipackage - # - # publish iOS build - # - mapbox_time "deploy_ios" - ./scripts/publish_ios.sh "$PUBLISH_VERSION" - else - # - # build & test iOS - # - mapbox_time "run_ios_tests" - make itest - fi -fi diff --git a/scripts/xcpretty.sh b/scripts/xcpretty.sh new file mode 100755 index 000000000..c39f58822 --- /dev/null +++ b/scripts/xcpretty.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +FN=$(which xcpretty) ; [ ! -z ${FN} ] && echo "| ${FN}" diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 4055001fc..4cbc98fa5 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -13,9 +13,9 @@ #include #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" #ifndef __clang__ #pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#pragma GCC diagnostic ignored "-Wshadow" #endif #include #pragma GCC diagnostic pop diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index dc91c250c..da6630ef0 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -10,6 +10,7 @@ #include #pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" #ifndef __clang__ #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #endif diff --git a/test/test.gypi b/test/test.gypi index 40cd3d506..5c975d547 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -72,15 +72,18 @@ ], 'libraries': [ '<@(uv_static_libs)', + '<@(sqlite3_static_libs)', ], 'variables': { 'cflags_cc': [ '<@(uv_cflags)', '<@(opengl_cflags)', '<@(boost_cflags)', + '<@(sqlite3_cflags)', ], 'ldflags': [ '<@(uv_ldflags)', + '<@(sqlite3_ldflags)', ], }, 'conditions': [ From 8482df62e8f26c6265cdd12c23548241d2bf826f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 24 Apr 2015 14:51:41 +0200 Subject: [PATCH 028/373] use custom boost --- .travis.yml | 2 -- configure | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82190742e..0790f271b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,6 @@ addons: - libxxf86vm-dev - x11proto-xf86vidmode-dev - mesa-utils # for glxinfo - - libboost-dev - - libboost-program-options-dev - lib32stdc++6 # for Gradle's aapt - lib32z1 # for Gradle's aapt diff --git a/configure b/configure index a37000a1b..f49ea2189 100755 --- a/configure +++ b/configure @@ -45,7 +45,7 @@ case ${MASON_PLATFORM} in LIBCURL_VERSION=system LIBUV_VERSION=0.10.28 ZLIB_VERSION=system - BOOST_VERSION=system + BOOST_VERSION=1.57.0 NUNICODE_VERSION=1.5.1 LIBZIP_VERSION=0.11.2 ;; From 8758500ff646fa3b34d59277715c9420c94fc2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 24 Apr 2015 15:05:20 +0200 Subject: [PATCH 029/373] only install required deps --- .travis.yml | 69 +++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0790f271b..1013fe74f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,33 +2,28 @@ language: android sudo: false -addons: - apt: - sources: - - boost-latest - - ubuntu-toolchain-r-test - packages: - - gdb # for printing stack traces from core dumps - - gcc-4.8 - - g++-4.8 - - llvm-3.4 - - xutils-dev - - libxxf86vm-dev - - x11proto-xf86vidmode-dev - - mesa-utils # for glxinfo - - lib32stdc++6 # for Gradle's aapt - - lib32z1 # for Gradle's aapt - matrix: exclude: - os: linux include: - os: linux env: FLAVOR=linux CXX=g++-4.8 BUILDTYPE=Release + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'gdb', 'g++-4.8', 'gcc-4.8', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ] - os: linux env: FLAVOR=linux CXX=clang++ BUILDTYPE=Debug + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'gdb', 'libgcc-4.8-dev', 'libstdc++-4.8-dev', 'libstdc++6', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ] - os: linux env: FLAVOR=linux CXX=clang++ BUILDTYPE=Release + addons: + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'gdb', 'libgcc-4.8-dev', 'libstdc++-4.8-dev', 'libstdc++6', 'libllvm3.4', 'xutils-dev', 'libxxf86vm-dev', 'x11proto-xf86vidmode-dev', 'mesa-utils' ] - os: osx env: FLAVOR=osx BUILDTYPE=Debug - os: osx @@ -36,38 +31,38 @@ matrix: - os: linux env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Release android: - components: - - build-tools-22.0.0 - - android-22 - - extra + components: [ 'build-tools-22.0.0', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] - os: linux env: FLAVOR=android ANDROID_ABI=arm-v7 BUILDTYPE=Debug android: - components: - - build-tools-22.0.0 - - android-22 - - extra + components: [ 'build-tools-22.0.0', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] - os: linux env: FLAVOR=android ANDROID_ABI=arm-v8 BUILDTYPE=Release android: - components: - - build-tools-22.0.0 - - android-22 - - extra + components: [ 'build-tools-22.0.0', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] - os: linux env: FLAVOR=android ANDROID_ABI=x86 BUILDTYPE=Release android: - components: - - build-tools-22.0.0 - - android-22 - - extra + components: [ 'build-tools-22.0.0', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] - os: linux env: FLAVOR=android ANDROID_ABI=mips BUILDTYPE=Release android: - components: - - build-tools-22.0.0 - - android-22 - - extra + components: [ 'build-tools-22.0.0', 'android-22', 'extra' ] + addons: + apt: + packages: [ 'lib32stdc++6' ] env: global: From b0bf80e79c4516153da76be0e733ef76c8329f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 24 Apr 2015 15:23:21 +0200 Subject: [PATCH 030/373] correctly execute after_failure script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1013fe74f..a98045c50 100644 --- a/.travis.yml +++ b/.travis.yml @@ -89,7 +89,7 @@ script: - ./scripts/${FLAVOR}/run.sh after_failure: -- if [ -f scripts/${FLAVOR}/run.sh ]; then /scripts/${FLAVOR}/after_failure.sh; fi +- "[ -f scripts/${FLAVOR}/run.sh ] && scripts/${FLAVOR}/run.sh" notifications: slack: From fe85bcd73707fb832645f9fde18c288edd6f6dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 28 Apr 2015 11:11:33 +0200 Subject: [PATCH 031/373] bump up the number of concurrent jobs on iOS builds --- scripts/ios/package.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/ios/package.sh b/scripts/ios/package.sh index 07e568faa..e71925f80 100755 --- a/scripts/ios/package.sh +++ b/scripts/ios/package.sh @@ -4,6 +4,8 @@ set -e set -o pipefail set -u +source ./scripts/travis_helper.sh + NAME=MapboxGL OUTPUT=build/ios/pkg IOS_SDK_VERSION=`xcrun --sdk iphoneos --show-sdk-version` @@ -40,7 +42,7 @@ xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \ -project ./build/ios/mbgl.xcodeproj \ -configuration ${BUILDTYPE} \ -target everything \ - -jobs `sysctl -n hw.ncpu` | xcpretty -c + -jobs ${JOBS} | xcpretty -c step "Building iOS Simulator targets..." @@ -50,7 +52,7 @@ xcodebuild -sdk iphonesimulator${IOS_SDK_VERSION} \ -project ./build/ios/mbgl.xcodeproj \ -configuration ${BUILDTYPE} \ -target everything \ - -jobs `sysctl -n hw.ncpu` | xcpretty -c + -jobs ${JOBS} | xcpretty -c step "Building static library..." From 844b9b9149a17ebf251f88c06716aa3d52f152c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 28 Apr 2015 11:19:38 +0200 Subject: [PATCH 032/373] move ios_test.sh to ios folder --- Makefile | 2 +- scripts/{test_ios.sh => ios/test.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename scripts/{test_ios.sh => ios/test.sh} (100%) diff --git a/Makefile b/Makefile index 66a7ecb65..b87ceb0ac 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ ipackage: clean Xcode/ios ./scripts/ios/package.sh itest: ipackage KIF - ./scripts/test_ios.sh + ./scripts/ios/test.sh # Legacy name iproj: ios-proj diff --git a/scripts/test_ios.sh b/scripts/ios/test.sh similarity index 100% rename from scripts/test_ios.sh rename to scripts/ios/test.sh From 9a0005fdea5c7eb9107793305f475d233b0669c2 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 16 Apr 2015 12:24:14 -0700 Subject: [PATCH 033/373] Remove unnecessary moves / casts --- platform/default/sqlite_cache.cpp | 4 ++-- src/mbgl/storage/default_file_source.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/platform/default/sqlite_cache.cpp b/platform/default/sqlite_cache.cpp index a57e666e9..4450374a3 100644 --- a/platform/default/sqlite_cache.cpp +++ b/platform/default/sqlite_cache.cpp @@ -183,9 +183,9 @@ void SQLiteCache::put(const Resource &resource, std::shared_ptr // storing a new response or updating the currently stored response, potentially setting a new // expiry date. if (hint == Hint::Full) { - thread->invoke(&Impl::put, resource, std::move(response)); + thread->invoke(&Impl::put, resource, response); } else if (hint == Hint::Refresh) { - thread->invoke(&Impl::refresh, resource, int64_t(response->expires)); + thread->invoke(&Impl::refresh, resource, response->expires); } } diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 4cbc98fa5..208a529bc 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -60,7 +60,7 @@ Request* DefaultFileSource::request(const Resource& resource, // This function can be called from any thread. Make sure we're executing the actual call in the // file source loop by sending it over the queue. - thread->invoke(&Impl::add, std::move(req), thread->get()); + thread->invoke(&Impl::add, req, thread->get()); return req; } @@ -74,7 +74,7 @@ void DefaultFileSource::cancel(Request *req) { // This function can be called from any thread. Make sure we're executing the actual call in the // file source loop by sending it over the queue. - thread->invoke(&Impl::cancel, std::move(req)); + thread->invoke(&Impl::cancel, req); } void DefaultFileSource::abort(const Environment &env) { From f4adef18891dff33a8d4e7ba9e14cc02c17fb6cf Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 13 Apr 2015 14:37:57 -0700 Subject: [PATCH 034/373] =?UTF-8?q?pointer=20=E2=87=A2=20reference?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/darwin/http_request_nsurl.mm | 2 +- platform/default/asset_request_fs.cpp | 4 ++-- platform/default/asset_request_zip.cpp | 5 ++--- platform/default/http_request_curl.cpp | 2 +- src/mbgl/storage/asset_request.hpp | 2 +- src/mbgl/storage/default_file_source.cpp | 4 ++-- src/mbgl/storage/http_request.hpp | 2 +- src/mbgl/storage/shared_request_base.hpp | 14 +++++--------- 8 files changed, 15 insertions(+), 20 deletions(-) diff --git a/platform/darwin/http_request_nsurl.mm b/platform/darwin/http_request_nsurl.mm index 0fd4a4e8f..24b31ae0a 100644 --- a/platform/darwin/http_request_nsurl.mm +++ b/platform/darwin/http_request_nsurl.mm @@ -397,7 +397,7 @@ void HTTPRequestImpl::restart(uv_timer_t *timer, int) { // ------------------------------------------------------------------------------------------------- -HTTPRequest::HTTPRequest(DefaultFileSource::Impl *source, const Resource &resource) +HTTPRequest::HTTPRequest(DefaultFileSource::Impl &source, const Resource &resource) : SharedRequestBase(source, resource) { } diff --git a/platform/default/asset_request_fs.cpp b/platform/default/asset_request_fs.cpp index 08b336ad3..fbb739c5c 100644 --- a/platform/default/asset_request_fs.cpp +++ b/platform/default/asset_request_fs.cpp @@ -62,7 +62,7 @@ AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : re path = url.substr(8); } else { // This is a relative path. Prefix with the application root. - path = request->source->assetRoot + "/" + url.substr(8); + path = request->source.assetRoot + "/" + url.substr(8); } uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened); @@ -207,7 +207,7 @@ void AssetRequestImpl::cleanup(uv_fs_t *req) { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(DefaultFileSource::Impl *source_, const Resource &resource_) +AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_) : SharedRequestBase(source_, resource_) { assert(algo::starts_with(resource.url, "asset://")); } diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp index f66ca619b..ba91809f1 100644 --- a/platform/default/asset_request_zip.cpp +++ b/platform/default/asset_request_zip.cpp @@ -114,7 +114,7 @@ AssetRequestImpl::~AssetRequestImpl() { AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : context(*AssetZipContext::Get(loop)), request(request_), - root(request->source->assetRoot), + root(request->source.assetRoot), path(std::string { "assets/" } + request->resource.url.substr(8)) { auto zip = context.getHandle(root); if (zip) { @@ -129,7 +129,6 @@ void AssetRequestImpl::openZipArchive() { req->data = this; assert(request); - assert(request->source); // We're using uv_fs_open first to obtain a file descriptor. Then, uv_zip_fdopen will operate // on a read-only file. @@ -275,7 +274,7 @@ void AssetRequestImpl::cancel() { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(DefaultFileSource::Impl *source_, const Resource &resource_) +AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_) : SharedRequestBase(source_, resource_) { assert(algo::starts_with(resource.url, "asset://")); } diff --git a/platform/default/http_request_curl.cpp b/platform/default/http_request_curl.cpp index 1672c9cdb..a5de61104 100644 --- a/platform/default/http_request_curl.cpp +++ b/platform/default/http_request_curl.cpp @@ -722,7 +722,7 @@ void HTTPRequestImpl::handleResult(CURLcode code) { // ------------------------------------------------------------------------------------------------- -HTTPRequest::HTTPRequest(DefaultFileSource::Impl *source_, const Resource &resource_) +HTTPRequest::HTTPRequest(DefaultFileSource::Impl &source_, const Resource &resource_) : SharedRequestBase(source_, resource_) { } diff --git a/src/mbgl/storage/asset_request.hpp b/src/mbgl/storage/asset_request.hpp index 48d421c3b..22e63c1ad 100644 --- a/src/mbgl/storage/asset_request.hpp +++ b/src/mbgl/storage/asset_request.hpp @@ -7,7 +7,7 @@ namespace mbgl { class AssetRequest : public SharedRequestBase { public: - AssetRequest(DefaultFileSource::Impl *source, const Resource &resource); + AssetRequest(DefaultFileSource::Impl &source, const Resource &resource); void start(uv_loop_t *loop, std::shared_ptr response = nullptr); void cancel(); diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 208a529bc..cc48e8473 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -89,9 +89,9 @@ void DefaultFileSource::Impl::add(Request* req, uv_loop_t* loop) { if (!sharedRequest) { // There is no request for this URL yet. Create a new one and start it. if (algo::starts_with(resource.url, "asset://")) { - sharedRequest = new AssetRequest(this, resource); + sharedRequest = new AssetRequest(*this, resource); } else { - sharedRequest = new HTTPRequest(this, resource); + sharedRequest = new HTTPRequest(*this, resource); } const bool inserted = pending.emplace(resource, sharedRequest).second; diff --git a/src/mbgl/storage/http_request.hpp b/src/mbgl/storage/http_request.hpp index 54e9a77ef..6232bd22e 100644 --- a/src/mbgl/storage/http_request.hpp +++ b/src/mbgl/storage/http_request.hpp @@ -7,7 +7,7 @@ namespace mbgl { class HTTPRequest : public SharedRequestBase { public: - HTTPRequest(DefaultFileSource::Impl *source, const Resource &resource); + HTTPRequest(DefaultFileSource::Impl &source, const Resource &resource); void start(uv_loop_t *loop, std::shared_ptr response = nullptr); void cancel(); diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp index d7ed00264..8fc23b7bd 100644 --- a/src/mbgl/storage/shared_request_base.hpp +++ b/src/mbgl/storage/shared_request_base.hpp @@ -26,7 +26,7 @@ protected: MBGL_STORE_THREAD(tid) public: - SharedRequestBase(DefaultFileSource::Impl *source_, const Resource &resource_) + SharedRequestBase(DefaultFileSource::Impl &source_, const Resource &resource_) : resource(resource_), source(source_) {} virtual void start(uv_loop_t *loop, std::shared_ptr response = nullptr) = 0; @@ -35,9 +35,7 @@ public: void notify(std::shared_ptr response, FileCache::Hint hint) { MBGL_VERIFY_THREAD(tid); - if (source) { - source->notify(this, observers, response, hint); - } + source.notify(this, observers, response, hint); } void subscribe(Request *request) { @@ -53,10 +51,8 @@ public: if (abandoned()) { // There are no observers anymore. We are initiating cancelation. - if (source) { - // First, remove this SharedRequestBase from the source. - source->notify(this, observers, nullptr, FileCache::Hint::No); - } + // First, remove this SharedRequestBase from the source. + source.notify(this, observers, nullptr, FileCache::Hint::No); // Then, initiate cancelation of this request cancel(); @@ -95,7 +91,7 @@ public: const Resource resource; protected: - DefaultFileSource::Impl *source = nullptr; + DefaultFileSource::Impl &source; private: std::set observers; From 2a8ddc9f27faded12c3013283123427af607f02e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 16 Apr 2015 17:11:49 -0700 Subject: [PATCH 035/373] Keep observers encapsulated --- src/mbgl/storage/default_file_source.cpp | 14 +++----------- src/mbgl/storage/default_file_source_impl.hpp | 2 +- src/mbgl/storage/shared_request_base.hpp | 11 +++++++++-- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index cc48e8473..68a072f40 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -184,22 +184,14 @@ void DefaultFileSource::Impl::abort(const Environment& env) { } void DefaultFileSource::Impl::notify(SharedRequestBase *sharedRequest, - const std::set &observers, std::shared_ptr response, FileCache::Hint hint) { // First, remove the request, since it might be destructed at any point now. assert(find(sharedRequest->resource) == sharedRequest); pending.erase(sharedRequest->resource); - if (response) { - if (cache) { - // Store response in database - cache->put(sharedRequest->resource, response, hint); - } - - // Notify all observers. - for (auto req : observers) { - req->notify(response); - } + if (response && cache) { + // Store response in database + cache->put(sharedRequest->resource, response, hint); } } diff --git a/src/mbgl/storage/default_file_source_impl.hpp b/src/mbgl/storage/default_file_source_impl.hpp index 97210dc44..7a673b6ce 100644 --- a/src/mbgl/storage/default_file_source_impl.hpp +++ b/src/mbgl/storage/default_file_source_impl.hpp @@ -14,7 +14,7 @@ class DefaultFileSource::Impl { public: Impl(FileCache *cache, const std::string &root = ""); - void notify(SharedRequestBase *sharedRequest, const std::set &observers, + void notify(SharedRequestBase *sharedRequest, std::shared_ptr response, FileCache::Hint hint); SharedRequestBase *find(const Resource &resource); diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp index 8fc23b7bd..3cd33b2ed 100644 --- a/src/mbgl/storage/shared_request_base.hpp +++ b/src/mbgl/storage/shared_request_base.hpp @@ -35,7 +35,14 @@ public: void notify(std::shared_ptr response, FileCache::Hint hint) { MBGL_VERIFY_THREAD(tid); - source.notify(this, observers, response, hint); + source.notify(this, response, hint); + + if (response) { + // Notify all observers. + for (auto req : observers) { + req->notify(response); + } + } } void subscribe(Request *request) { @@ -52,7 +59,7 @@ public: if (abandoned()) { // There are no observers anymore. We are initiating cancelation. // First, remove this SharedRequestBase from the source. - source.notify(this, observers, nullptr, FileCache::Hint::No); + source.notify(this, nullptr, FileCache::Hint::No); // Then, initiate cancelation of this request cancel(); From ea73c99faa7f46c2c958644fd1300d1cf88701b0 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 16 Apr 2015 17:55:44 -0700 Subject: [PATCH 036/373] Assert that notify gets a response --- src/mbgl/storage/shared_request_base.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp index 3cd33b2ed..3fc0c5bfe 100644 --- a/src/mbgl/storage/shared_request_base.hpp +++ b/src/mbgl/storage/shared_request_base.hpp @@ -34,14 +34,13 @@ public: void notify(std::shared_ptr response, FileCache::Hint hint) { MBGL_VERIFY_THREAD(tid); + assert(response); source.notify(this, response, hint); - if (response) { - // Notify all observers. - for (auto req : observers) { - req->notify(response); - } + // Notify all observers. + for (auto req : observers) { + req->notify(response); } } From b61cc6433b50c9a8a5083c1c5051e5c3ce78b761 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 16 Apr 2015 17:57:41 -0700 Subject: [PATCH 037/373] Make subscribe and unsubscribe parallel --- src/mbgl/storage/default_file_source.cpp | 11 ++++++++++- src/mbgl/storage/shared_request_base.hpp | 11 ----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 68a072f40..6ead7781b 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -119,6 +119,15 @@ void DefaultFileSource::Impl::cancel(Request* req) { // unsubscribe callback triggers the removal of the SharedRequestBase pointer from the list // of pending requests and initiates cancelation. sharedRequest->unsubscribe(req); + + if (sharedRequest->abandoned()) { + // There are no observers anymore. We are initiating cancelation. + // First, remove this SharedRequestBase from the source. + pending.erase(sharedRequest->resource); + + // Then, initiate cancelation of this request + sharedRequest->cancel(); + } } else { // There is no request for this URL anymore. Likely, the request already completed // before we got around to process the cancelation request. @@ -189,7 +198,7 @@ void DefaultFileSource::Impl::notify(SharedRequestBase *sharedRequest, assert(find(sharedRequest->resource) == sharedRequest); pending.erase(sharedRequest->resource); - if (response && cache) { + if (cache) { // Store response in database cache->put(sharedRequest->resource, response, hint); } diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp index 3fc0c5bfe..ce741ce11 100644 --- a/src/mbgl/storage/shared_request_base.hpp +++ b/src/mbgl/storage/shared_request_base.hpp @@ -46,23 +46,12 @@ public: void subscribe(Request *request) { MBGL_VERIFY_THREAD(tid); - observers.insert(request); } void unsubscribe(Request *request) { MBGL_VERIFY_THREAD(tid); - observers.erase(request); - - if (abandoned()) { - // There are no observers anymore. We are initiating cancelation. - // First, remove this SharedRequestBase from the source. - source.notify(this, nullptr, FileCache::Hint::No); - - // Then, initiate cancelation of this request - cancel(); - } } bool abandoned() const { From 359aca6624f183099a9afe58aae5a41bd2cb3772 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 17 Apr 2015 09:31:00 -0700 Subject: [PATCH 038/373] Privatize SharedRequestBase::source --- platform/default/asset_request_fs.cpp | 7 ++++--- platform/default/asset_request_zip.cpp | 7 ++++--- src/mbgl/storage/asset_request.hpp | 3 ++- src/mbgl/storage/default_file_source.cpp | 2 +- src/mbgl/storage/shared_request_base.hpp | 4 +--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/platform/default/asset_request_fs.cpp b/platform/default/asset_request_fs.cpp index fbb739c5c..446f2f3d5 100644 --- a/platform/default/asset_request_fs.cpp +++ b/platform/default/asset_request_fs.cpp @@ -62,7 +62,7 @@ AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : re path = url.substr(8); } else { // This is a relative path. Prefix with the application root. - path = request->source.assetRoot + "/" + url.substr(8); + path = request->assetRoot + "/" + url.substr(8); } uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened); @@ -207,8 +207,9 @@ void AssetRequestImpl::cleanup(uv_fs_t *req) { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_) - : SharedRequestBase(source_, resource_) { +AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_, const std::string& assetRoot_) + : SharedRequestBase(source_, resource_) + , assetRoot(assetRoot_) { assert(algo::starts_with(resource.url, "asset://")); } diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp index ba91809f1..8a471a4fc 100644 --- a/platform/default/asset_request_zip.cpp +++ b/platform/default/asset_request_zip.cpp @@ -114,7 +114,7 @@ AssetRequestImpl::~AssetRequestImpl() { AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : context(*AssetZipContext::Get(loop)), request(request_), - root(request->source.assetRoot), + root(request->assetRoot), path(std::string { "assets/" } + request->resource.url.substr(8)) { auto zip = context.getHandle(root); if (zip) { @@ -274,8 +274,9 @@ void AssetRequestImpl::cancel() { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_) - : SharedRequestBase(source_, resource_) { +AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_, const std::string& assetRoot_) + : SharedRequestBase(source_, resource_) + , assetRoot(assetRoot_) { assert(algo::starts_with(resource.url, "asset://")); } diff --git a/src/mbgl/storage/asset_request.hpp b/src/mbgl/storage/asset_request.hpp index 22e63c1ad..2a571d209 100644 --- a/src/mbgl/storage/asset_request.hpp +++ b/src/mbgl/storage/asset_request.hpp @@ -7,7 +7,7 @@ namespace mbgl { class AssetRequest : public SharedRequestBase { public: - AssetRequest(DefaultFileSource::Impl &source, const Resource &resource); + AssetRequest(DefaultFileSource::Impl&, const Resource&, const std::string& assetRoot); void start(uv_loop_t *loop, std::shared_ptr response = nullptr); void cancel(); @@ -15,6 +15,7 @@ public: private: ~AssetRequest(); void *ptr = nullptr; + const std::string& assetRoot; friend class AssetRequestImpl; }; diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 6ead7781b..f4c220e36 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -89,7 +89,7 @@ void DefaultFileSource::Impl::add(Request* req, uv_loop_t* loop) { if (!sharedRequest) { // There is no request for this URL yet. Create a new one and start it. if (algo::starts_with(resource.url, "asset://")) { - sharedRequest = new AssetRequest(*this, resource); + sharedRequest = new AssetRequest(*this, resource, assetRoot); } else { sharedRequest = new HTTPRequest(*this, resource); } diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp index ce741ce11..cf70ac0f0 100644 --- a/src/mbgl/storage/shared_request_base.hpp +++ b/src/mbgl/storage/shared_request_base.hpp @@ -85,10 +85,8 @@ protected: public: const Resource resource; -protected: - DefaultFileSource::Impl &source; - private: + DefaultFileSource::Impl& source; std::set observers; }; From cdd8f3ac3235e1d5aab47a6d32c48a0b82a3a1b9 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 17 Apr 2015 09:58:24 -0700 Subject: [PATCH 039/373] Separate RequestBase from DefaultFileSource internals SharedRequestBase was trying to do two different jobs: be a base class for Asset/HttpRequest and track internal state for DefaultFileSource. Now we have RequestBase for the former, and DefaultFileRequest for the latter. --- platform/darwin/http_request_nsurl.mm | 13 +- platform/default/asset_request_fs.cpp | 11 +- platform/default/asset_request_zip.cpp | 13 +- platform/default/http_request_curl.cpp | 13 +- src/mbgl/storage/asset_request.hpp | 6 +- src/mbgl/storage/default_file_source.cpp | 214 +++++++++--------- src/mbgl/storage/default_file_source_impl.hpp | 37 +-- src/mbgl/storage/http_request.hpp | 8 +- src/mbgl/storage/request_base.hpp | 39 ++++ src/mbgl/storage/shared_request_base.hpp | 95 -------- 10 files changed, 194 insertions(+), 255 deletions(-) create mode 100644 src/mbgl/storage/request_base.hpp delete mode 100644 src/mbgl/storage/shared_request_base.hpp diff --git a/platform/darwin/http_request_nsurl.mm b/platform/darwin/http_request_nsurl.mm index 24b31ae0a..07ac16e05 100644 --- a/platform/darwin/http_request_nsurl.mm +++ b/platform/darwin/http_request_nsurl.mm @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -397,36 +398,28 @@ void HTTPRequestImpl::restart(uv_timer_t *timer, int) { // ------------------------------------------------------------------------------------------------- -HTTPRequest::HTTPRequest(DefaultFileSource::Impl &source, const Resource &resource) - : SharedRequestBase(source, resource) { +HTTPRequest::HTTPRequest(const Resource& resource, Callback callback) + : RequestBase(resource, callback) { } HTTPRequest::~HTTPRequest() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->cancel(); } } void HTTPRequest::start(uv_loop_t *loop, std::shared_ptr response) { - MBGL_VERIFY_THREAD(tid); - assert(!ptr); ptr = new HTTPRequestImpl(this, loop, response); } void HTTPRequest::retryImmediately() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->retryImmediately(); } } void HTTPRequest::cancel() { - MBGL_VERIFY_THREAD(tid); - delete this; } diff --git a/platform/default/asset_request_fs.cpp b/platform/default/asset_request_fs.cpp index 446f2f3d5..9580c2f5b 100644 --- a/platform/default/asset_request_fs.cpp +++ b/platform/default/asset_request_fs.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -207,23 +208,19 @@ void AssetRequestImpl::cleanup(uv_fs_t *req) { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_, const std::string& assetRoot_) - : SharedRequestBase(source_, resource_) +AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, const std::string& assetRoot_) + : RequestBase(resource_, callback_) , assetRoot(assetRoot_) { assert(algo::starts_with(resource.url, "asset://")); } AssetRequest::~AssetRequest() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->request = nullptr; } } void AssetRequest::start(uv_loop_t *loop, std::shared_ptr response) { - MBGL_VERIFY_THREAD(tid); - // We're ignoring the existing response if any. (void(response)); @@ -233,8 +230,6 @@ void AssetRequest::start(uv_loop_t *loop, std::shared_ptr respon } void AssetRequest::cancel() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->canceled = true; diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp index 8a471a4fc..69de1c742 100644 --- a/platform/default/asset_request_zip.cpp +++ b/platform/default/asset_request_zip.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -107,7 +108,7 @@ AssetRequestImpl::~AssetRequestImpl() { MBGL_VERIFY_THREAD(tid); if (request) { - request->ptr = nullptr; + request->impl = nullptr; } } @@ -274,23 +275,19 @@ void AssetRequestImpl::cancel() { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(DefaultFileSource::Impl &source_, const Resource &resource_, const std::string& assetRoot_) - : SharedRequestBase(source_, resource_) +AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, const std::string& assetRoot_) + : RequestBase(resource_, callback_) , assetRoot(assetRoot_) { assert(algo::starts_with(resource.url, "asset://")); } AssetRequest::~AssetRequest() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->cancel(); } } void AssetRequest::start(uv_loop_t *loop, std::shared_ptr response) { - MBGL_VERIFY_THREAD(tid); - // We're ignoring the existing response if any. (void(response)); @@ -300,8 +297,6 @@ void AssetRequest::start(uv_loop_t *loop, std::shared_ptr respon } void AssetRequest::cancel() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->cancel(); } diff --git a/platform/default/http_request_curl.cpp b/platform/default/http_request_curl.cpp index a5de61104..ffe3b525a 100644 --- a/platform/default/http_request_curl.cpp +++ b/platform/default/http_request_curl.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -722,36 +723,28 @@ void HTTPRequestImpl::handleResult(CURLcode code) { // ------------------------------------------------------------------------------------------------- -HTTPRequest::HTTPRequest(DefaultFileSource::Impl &source_, const Resource &resource_) - : SharedRequestBase(source_, resource_) { +HTTPRequest::HTTPRequest(const Resource& resource_, Callback callback_) + : RequestBase(resource_, callback_) { } HTTPRequest::~HTTPRequest() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->abandon(); } } void HTTPRequest::start(uv_loop_t *loop, std::shared_ptr response) { - MBGL_VERIFY_THREAD(tid); - assert(!ptr); ptr = new HTTPRequestImpl(this, loop, response); } void HTTPRequest::retryImmediately() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { reinterpret_cast(ptr)->retryImmediately(); } } void HTTPRequest::cancel() { - MBGL_VERIFY_THREAD(tid); - if (ptr) { delete reinterpret_cast(ptr); ptr = nullptr; diff --git a/src/mbgl/storage/asset_request.hpp b/src/mbgl/storage/asset_request.hpp index 2a571d209..e20e1d818 100644 --- a/src/mbgl/storage/asset_request.hpp +++ b/src/mbgl/storage/asset_request.hpp @@ -1,13 +1,13 @@ #ifndef MBGL_STORAGE_DEFAULT_ASSET_REQUEST #define MBGL_STORAGE_DEFAULT_ASSET_REQUEST -#include "shared_request_base.hpp" +#include "request_base.hpp" namespace mbgl { -class AssetRequest : public SharedRequestBase { +class AssetRequest : public RequestBase { public: - AssetRequest(DefaultFileSource::Impl&, const Resource&, const std::string& assetRoot); + AssetRequest(const Resource&, Callback, const std::string& assetRoot); void start(uv_loop_t *loop, std::shared_ptr response = nullptr); void cancel(); diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index f4c220e36..c510b5c7f 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -28,10 +28,6 @@ namespace algo = boost::algorithm; namespace mbgl { -DefaultFileSource::Impl::Impl(FileCache* cache_, const std::string& root) - : assetRoot(root.empty() ? platform::assetRoot() : root), cache(cache_) { -} - DefaultFileSource::DefaultFileSource(FileCache* cache, const std::string& root) : thread(util::make_unique>("FileSource", cache, root)) { } @@ -40,18 +36,6 @@ DefaultFileSource::~DefaultFileSource() { MBGL_VERIFY_THREAD(tid); } -SharedRequestBase *DefaultFileSource::Impl::find(const Resource &resource) { - // We're using a set of pointers here instead of a map between url and SharedRequestBase because - // we need to find the requests both by pointer and by URL. Given that the number of requests - // is generally very small (typically < 10 at a time), hashing by URL incurs too much overhead - // anyway. - const auto it = pending.find(resource); - if (it != pending.end()) { - return it->second; - } - return nullptr; -} - Request* DefaultFileSource::request(const Resource& resource, uv_loop_t* l, const Environment& env, @@ -81,52 +65,95 @@ void DefaultFileSource::abort(const Environment &env) { thread->invoke(&Impl::abort, std::ref(env)); } -void DefaultFileSource::Impl::add(Request* req, uv_loop_t* loop) { - const Resource &resource = req->resource; +// ----- Impl ----- - // We're adding a new Request. - SharedRequestBase *sharedRequest = find(resource); - if (!sharedRequest) { - // There is no request for this URL yet. Create a new one and start it. - if (algo::starts_with(resource.url, "asset://")) { - sharedRequest = new AssetRequest(*this, resource, assetRoot); - } else { - sharedRequest = new HTTPRequest(*this, resource); - } +DefaultFileSource::Impl::Impl(FileCache* cache_, const std::string& root) + : cache(cache_), assetRoot(root.empty() ? platform::assetRoot() : root) { +} - const bool inserted = pending.emplace(resource, sharedRequest).second; - assert(inserted); - (void (inserted)); // silence unused variable warning on Release builds. - - // But first, we're going to start querying the database if it exists. - if (!cache) { - sharedRequest->start(loop); - } else { - // Otherwise, first check the cache for existing data so that we can potentially - // revalidate the information without having to redownload everything. - cache->get(resource, [this, resource, loop](std::unique_ptr response) { - processResult(resource, std::move(response), loop); - }); - } +DefaultFileRequest* DefaultFileSource::Impl::find(const Resource& resource) { + const auto it = pending.find(resource); + if (it != pending.end()) { + return &it->second; } - sharedRequest->subscribe(req); + return nullptr; +} + +void DefaultFileSource::Impl::add(Request* req, uv_loop_t* loop) { + const Resource& resource = req->resource; + DefaultFileRequest* request = find(resource); + + if (request) { + request->observers.insert(req); + return; + } + + request = &pending.emplace(resource, DefaultFileRequest(resource, loop)).first->second; + request->observers.insert(req); + + if (cache) { + startCacheRequest(resource); + } else { + startRealRequest(resource); + } +} + +void DefaultFileSource::Impl::startCacheRequest(const Resource& resource) { + // Check the cache for existing data so that we can potentially + // revalidate the information without having to redownload everything. + cache->get(resource, [this, resource](std::unique_ptr response) { + DefaultFileRequest* request = find(resource); + + if (!request) { + // There is no request for this URL anymore. Likely, the request was canceled + // before we got around to process the cache result. + return; + } + + auto expired = [&response] { + const int64_t now = std::chrono::duration_cast( + SystemClock::now().time_since_epoch()).count(); + return response->expires <= now; + }; + + if (!response || expired()) { + // No response or stale cache. Run the real request. + startRealRequest(resource, std::move(response)); + } else { + // The response is fresh. We're good to notify the caller. + notify(request, std::move(response), FileCache::Hint::No); + } + }); +} + +void DefaultFileSource::Impl::startRealRequest(const Resource& resource, std::shared_ptr response) { + DefaultFileRequest* request = find(resource); + + auto callback = [request, this] (std::shared_ptr res, FileCache::Hint hint) { + notify(request, res, hint); + }; + + if (algo::starts_with(resource.url, "asset://")) { + request->request = new AssetRequest(resource, callback, assetRoot); + } else { + request->request = new HTTPRequest(resource, callback); + } + + request->request->start(request->loop, response); } void DefaultFileSource::Impl::cancel(Request* req) { - SharedRequestBase *sharedRequest = find(req->resource); - if (sharedRequest) { - // If the number of dependent requests of the SharedRequestBase drops to zero, the - // unsubscribe callback triggers the removal of the SharedRequestBase pointer from the list - // of pending requests and initiates cancelation. - sharedRequest->unsubscribe(req); + DefaultFileRequest* request = find(req->resource); - if (sharedRequest->abandoned()) { - // There are no observers anymore. We are initiating cancelation. - // First, remove this SharedRequestBase from the source. - pending.erase(sharedRequest->resource); - - // Then, initiate cancelation of this request - sharedRequest->cancel(); + if (request) { + // If the number of dependent requests of the DefaultFileRequest drops to zero, + // cancel the request and remove it from the pending list. + request->observers.erase(req); + if (request->observers.empty()) { + if (request->request) { + request->request->cancel(); + } + pending.erase(request->resource); } } else { // There is no request for this URL anymore. Likely, the request already completed @@ -138,70 +165,51 @@ void DefaultFileSource::Impl::cancel(Request* req) { req->destruct(); } -void DefaultFileSource::Impl::processResult(const Resource& resource, std::shared_ptr response, uv_loop_t* loop) { - SharedRequestBase *sharedRequest = find(resource); - if (sharedRequest) { - if (response) { - // This entry was stored in the cache. Now determine if we need to revalidate. - const int64_t now = std::chrono::duration_cast( - SystemClock::now().time_since_epoch()).count(); - if (response->expires > now) { - // The response is fresh. We're good to notify the caller. - sharedRequest->notify(response, FileCache::Hint::No); - sharedRequest->cancel(); - return; - } else { - // The cached response is stale. Now run the real request. - sharedRequest->start(loop, response); - } - } else { - // There is no response. Now run the real request. - sharedRequest->start(loop); - } - } else { - // There is no request for this URL anymore. Likely, the request was canceled - // before we got around to process the cache result. - } -} - // Aborts all requests that are part of the current environment. void DefaultFileSource::Impl::abort(const Environment& env) { // Construct a cancellation response. - auto res = util::make_unique(); - res->status = Response::Error; - res->message = "Environment is terminating"; - std::shared_ptr response = std::move(res); + auto response = std::make_shared(); + response->status = Response::Error; + response->message = "Environment is terminating"; // Iterate through all pending requests and remove them in case they're abandoned. - util::erase_if(pending, [&](const std::pair &it) -> bool { - // Obtain all pending requests that are in the current environment. - const auto aborted = it.second->removeAllInEnvironment(env); + util::erase_if(pending, [&](std::pair& it) -> bool { + // Notify all pending requests that are in the current environment. + util::erase_if(it.second.observers, [&](Request* req) -> bool { + if (&req->env == &env) { + req->notify(response); + return true; + } else { + return false; + } + }); - // Notify all observers. - for (auto req : aborted) { - req->notify(response); + bool abandoned = it.second.observers.empty(); + + if (abandoned && it.second.request) { + it.second.request->cancel(); } - // Finally, remove all requests that are now abandoned. - if (it.second->abandoned()) { - it.second->cancel(); - return true; - } else { - return false; - } + return abandoned; }); } -void DefaultFileSource::Impl::notify(SharedRequestBase *sharedRequest, - std::shared_ptr response, FileCache::Hint hint) { +void DefaultFileSource::Impl::notify(DefaultFileRequest* request, std::shared_ptr response, FileCache::Hint hint) { // First, remove the request, since it might be destructed at any point now. - assert(find(sharedRequest->resource) == sharedRequest); - pending.erase(sharedRequest->resource); + assert(find(request->resource) == request); + assert(response); + + // Notify all observers. + for (auto req : request->observers) { + req->notify(response); + } if (cache) { // Store response in database - cache->put(sharedRequest->resource, response, hint); + cache->put(request->resource, response, hint); } + + pending.erase(request->resource); } } diff --git a/src/mbgl/storage/default_file_source_impl.hpp b/src/mbgl/storage/default_file_source_impl.hpp index 7a673b6ce..d3f83af38 100644 --- a/src/mbgl/storage/default_file_source_impl.hpp +++ b/src/mbgl/storage/default_file_source_impl.hpp @@ -8,27 +8,36 @@ namespace mbgl { -class SharedRequestBase; +class RequestBase; + +struct DefaultFileRequest { + const Resource resource; + uv_loop_t* loop; + std::set observers; + RequestBase* request = nullptr; + + DefaultFileRequest(const Resource& resource_, uv_loop_t* loop_) + : resource(resource_), loop(loop_) {} +}; class DefaultFileSource::Impl { public: - Impl(FileCache *cache, const std::string &root = ""); + Impl(FileCache*, const std::string& = ""); - void notify(SharedRequestBase *sharedRequest, - std::shared_ptr response, FileCache::Hint hint); - SharedRequestBase *find(const Resource &resource); - - void add(Request* request, uv_loop_t* loop); - void cancel(Request* request); - void abort(const Environment& env); - - const std::string assetRoot; + void add(Request*, uv_loop_t*); + void cancel(Request*); + void abort(const Environment&); private: - void processResult(const Resource& resource, std::shared_ptr response, uv_loop_t* loop); + DefaultFileRequest* find(const Resource&); - std::unordered_map pending; - FileCache *cache = nullptr; + void startCacheRequest(const Resource&); + void startRealRequest(const Resource&, std::shared_ptr = nullptr); + void notify(DefaultFileRequest*, std::shared_ptr, FileCache::Hint); + + std::unordered_map pending; + FileCache* cache = nullptr; + const std::string assetRoot; }; } diff --git a/src/mbgl/storage/http_request.hpp b/src/mbgl/storage/http_request.hpp index 6232bd22e..faf6ee2f1 100644 --- a/src/mbgl/storage/http_request.hpp +++ b/src/mbgl/storage/http_request.hpp @@ -1,13 +1,15 @@ #ifndef MBGL_STORAGE_DEFAULT_HTTP_REQUEST #define MBGL_STORAGE_DEFAULT_HTTP_REQUEST -#include "shared_request_base.hpp" +#include "request_base.hpp" namespace mbgl { -class HTTPRequest : public SharedRequestBase { +struct Resource; + +class HTTPRequest : public RequestBase { public: - HTTPRequest(DefaultFileSource::Impl &source, const Resource &resource); + HTTPRequest(const Resource&, Callback); void start(uv_loop_t *loop, std::shared_ptr response = nullptr); void cancel(); diff --git a/src/mbgl/storage/request_base.hpp b/src/mbgl/storage/request_base.hpp new file mode 100644 index 000000000..281e76a02 --- /dev/null +++ b/src/mbgl/storage/request_base.hpp @@ -0,0 +1,39 @@ +#ifndef MBGL_STORAGE_REQUEST +#define MBGL_STORAGE_REQUEST + +#include +#include + +#include +#include + +typedef struct uv_loop_s uv_loop_t; + +namespace mbgl { + +struct Resource; +class Response; + +class RequestBase : private util::noncopyable { +public: + using Callback = std::function response, FileCache::Hint hint)>; + + RequestBase(const Resource& resource_, Callback notify_) + : notify(notify_) + , resource(resource_) { + } + + virtual ~RequestBase() = default; + + virtual void start(uv_loop_t *loop, std::shared_ptr response = nullptr) = 0; + virtual void cancel() = 0; + + Callback notify; + +protected: + const Resource& resource; +}; + +} + +#endif diff --git a/src/mbgl/storage/shared_request_base.hpp b/src/mbgl/storage/shared_request_base.hpp deleted file mode 100644 index cf70ac0f0..000000000 --- a/src/mbgl/storage/shared_request_base.hpp +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE -#define MBGL_STORAGE_DEFAULT_SHARED_REQUEST_BASE - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -typedef struct uv_loop_s uv_loop_t; - -namespace mbgl { - -class Request; -class Response; -class DefaultFileSource; - -class SharedRequestBase : private util::noncopyable { -protected: - MBGL_STORE_THREAD(tid) - -public: - SharedRequestBase(DefaultFileSource::Impl &source_, const Resource &resource_) - : resource(resource_), source(source_) {} - - virtual void start(uv_loop_t *loop, std::shared_ptr response = nullptr) = 0; - virtual void cancel() = 0; - - void notify(std::shared_ptr response, FileCache::Hint hint) { - MBGL_VERIFY_THREAD(tid); - assert(response); - - source.notify(this, response, hint); - - // Notify all observers. - for (auto req : observers) { - req->notify(response); - } - } - - void subscribe(Request *request) { - MBGL_VERIFY_THREAD(tid); - observers.insert(request); - } - - void unsubscribe(Request *request) { - MBGL_VERIFY_THREAD(tid); - observers.erase(request); - } - - bool abandoned() const { - return observers.empty(); - } - - std::vector removeAllInEnvironment(const Environment &env) { - MBGL_VERIFY_THREAD(tid); - - std::vector result; - - // Removes all Requests in the supplied environment and returns a list - // of them. - util::erase_if(observers, [&](Request *req) -> bool { - if (&req->env == &env) { - result.push_back(req); - return true; - } else { - return false; - } - }); - - return result; - } - -protected: - virtual ~SharedRequestBase() { - MBGL_VERIFY_THREAD(tid); - } - -public: - const Resource resource; - -private: - DefaultFileSource::Impl& source; - std::set observers; -}; - -} - -#endif From 8e5fa341ebdc1699f08a1dbf4b0dfd98a9969948 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Fri, 17 Apr 2015 12:37:43 -0700 Subject: [PATCH 040/373] Remove RequestBase::start Requests are always started immediately upon construction. While here, use typed pointers, not void*. --- platform/darwin/http_request_nsurl.mm | 23 +++++----- platform/default/asset_request_fs.cpp | 54 +++++++++--------------- platform/default/asset_request_zip.cpp | 28 +++++------- platform/default/http_request_curl.cpp | 28 +++++------- src/mbgl/storage/asset_request.hpp | 12 +++--- src/mbgl/storage/default_file_source.cpp | 6 +-- src/mbgl/storage/http_request.hpp | 12 +++--- src/mbgl/storage/request_base.hpp | 11 ++--- 8 files changed, 70 insertions(+), 104 deletions(-) diff --git a/platform/darwin/http_request_nsurl.mm b/platform/darwin/http_request_nsurl.mm index 07ac16e05..f5e7888f5 100644 --- a/platform/darwin/http_request_nsurl.mm +++ b/platform/darwin/http_request_nsurl.mm @@ -200,7 +200,7 @@ void HTTPRequestImpl::handleResponse() { } context->removeRequest(request); - request->ptr = nullptr; + request->impl = nullptr; delete request; request = nullptr; } @@ -243,7 +243,7 @@ HTTPRequestImpl::~HTTPRequestImpl() { if (request) { context->removeRequest(request); - request->ptr = nullptr; + request->impl = nullptr; } } @@ -398,24 +398,21 @@ void HTTPRequestImpl::restart(uv_timer_t *timer, int) { // ------------------------------------------------------------------------------------------------- -HTTPRequest::HTTPRequest(const Resource& resource, Callback callback) - : RequestBase(resource, callback) { +HTTPRequest::HTTPRequest(const Resource& resource, Callback callback, + uv_loop_t* loop, std::shared_ptr response) + : RequestBase(resource, callback) + , impl(new HTTPRequestImpl(this, loop, response)) { } HTTPRequest::~HTTPRequest() { - if (ptr) { - reinterpret_cast(ptr)->cancel(); + if (impl) { + impl->cancel(); } } -void HTTPRequest::start(uv_loop_t *loop, std::shared_ptr response) { - assert(!ptr); - ptr = new HTTPRequestImpl(this, loop, response); -} - void HTTPRequest::retryImmediately() { - if (ptr) { - reinterpret_cast(ptr)->retryImmediately(); + if (impl) { + impl->retryImmediately(); } } diff --git a/platform/default/asset_request_fs.cpp b/platform/default/asset_request_fs.cpp index 9580c2f5b..87e432062 100644 --- a/platform/default/asset_request_fs.cpp +++ b/platform/default/asset_request_fs.cpp @@ -26,7 +26,7 @@ class AssetRequestImpl { MBGL_STORE_THREAD(tid) public: - AssetRequestImpl(AssetRequest *request, uv_loop_t *loop); + AssetRequestImpl(AssetRequest*, uv_loop_t*, const std::string& assetRoot); ~AssetRequestImpl(); static void fileOpened(uv_fs_t *req); @@ -36,8 +36,8 @@ public: static void notifyError(uv_fs_t *req); static void cleanup(uv_fs_t *req); - AssetRequest *request = nullptr; + std::string assetRoot; bool canceled = false; uv_fs_t req; uv_file fd = -1; @@ -49,11 +49,13 @@ AssetRequestImpl::~AssetRequestImpl() { MBGL_VERIFY_THREAD(tid); if (request) { - request->ptr = nullptr; + request->impl = nullptr; } } -AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : request(request_) { +AssetRequestImpl::AssetRequestImpl(AssetRequest* request_, uv_loop_t* loop, const std::string& assetRoot_) + : request(request_) + , assetRoot(assetRoot_) { req.data = this; const auto &url = request->resource.url; @@ -63,7 +65,7 @@ AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) : re path = url.substr(8); } else { // This is a relative path. Prefix with the application root. - path = request->assetRoot + "/" + url.substr(8); + path = assetRoot + "/" + url.substr(8); } uv_fs_open(loop, &req, path.c_str(), O_RDONLY, S_IRUSR, fileOpened); @@ -208,40 +210,26 @@ void AssetRequestImpl::cleanup(uv_fs_t *req) { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, const std::string& assetRoot_) +AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, + uv_loop_t* loop, const std::string& assetRoot) : RequestBase(resource_, callback_) - , assetRoot(assetRoot_) { + , impl(new AssetRequestImpl(this, loop, assetRoot)) { assert(algo::starts_with(resource.url, "asset://")); -} - -AssetRequest::~AssetRequest() { - if (ptr) { - reinterpret_cast(ptr)->request = nullptr; - } -} - -void AssetRequest::start(uv_loop_t *loop, std::shared_ptr response) { - // We're ignoring the existing response if any. - (void(response)); - - assert(!ptr); - ptr = new AssetRequestImpl(this, loop); // Note: the AssetRequestImpl deletes itself. } -void AssetRequest::cancel() { - if (ptr) { - reinterpret_cast(ptr)->canceled = true; - - // uv_cancel fails frequently when the request has already been started. - // In that case, we have to let it complete and check the canceled bool - // instead. The cancelation callback will delete the AssetRequest object. - uv_cancel((uv_req_t *)&reinterpret_cast(ptr)->req); - } else { - // This request is canceled before we called start. We're safe to delete - // ourselves now. - delete this; +AssetRequest::~AssetRequest() { + if (impl) { + impl->request = nullptr; } } +void AssetRequest::cancel() { + impl->canceled = true; + // uv_cancel fails frequently when the request has already been started. + // In that case, we have to let it complete and check the canceled bool + // instead. The cancelation callback will delete the AssetRequest object. + uv_cancel((uv_req_t *)&impl->req); +} + } diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp index 69de1c742..9f7ed6d9b 100644 --- a/platform/default/asset_request_zip.cpp +++ b/platform/default/asset_request_zip.cpp @@ -77,7 +77,7 @@ class AssetRequestImpl { MBGL_STORE_THREAD(tid) public: - AssetRequestImpl(AssetRequest *request, uv_loop_t *loop); + AssetRequestImpl(AssetRequest*, uv_loop_t*, const std::string& assetRoot); ~AssetRequestImpl(); void cancel(); @@ -112,10 +112,10 @@ AssetRequestImpl::~AssetRequestImpl() { } } -AssetRequestImpl::AssetRequestImpl(AssetRequest *request_, uv_loop_t *loop) +AssetRequestImpl::AssetRequestImpl(AssetRequest* request_, uv_loop_t* loop, const std::string& assetRoot_) : context(*AssetZipContext::Get(loop)), request(request_), - root(request->assetRoot), + root(assetRoot_), path(std::string { "assets/" } + request->resource.url.substr(8)) { auto zip = context.getHandle(root); if (zip) { @@ -275,30 +275,22 @@ void AssetRequestImpl::cancel() { // ------------------------------------------------------------------------------------------------- -AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, const std::string& assetRoot_) +AssetRequest::AssetRequest(const Resource& resource_, Callback callback_, + uv_loop_t* loop, const std::string& assetRoot) : RequestBase(resource_, callback_) - , assetRoot(assetRoot_) { + , impl(new AssetRequestImpl(this, loop, assetRoot)) { assert(algo::starts_with(resource.url, "asset://")); } AssetRequest::~AssetRequest() { - if (ptr) { - reinterpret_cast(ptr)->cancel(); + if (impl) { + impl->cancel(); } } -void AssetRequest::start(uv_loop_t *loop, std::shared_ptr response) { - // We're ignoring the existing response if any. - (void(response)); - - assert(!ptr); - ptr = new AssetRequestImpl(this, loop); - // Note: the AssetRequestImpl deletes itself. -} - void AssetRequest::cancel() { - if (ptr) { - reinterpret_cast(ptr)->cancel(); + if (impl) { + impl->cancel(); } delete this; diff --git a/platform/default/http_request_curl.cpp b/platform/default/http_request_curl.cpp index ffe3b525a..95cc88211 100644 --- a/platform/default/http_request_curl.cpp +++ b/platform/default/http_request_curl.cpp @@ -495,7 +495,7 @@ HTTPRequestImpl::~HTTPRequestImpl() { if (request) { context->removeRequest(request); - request->ptr = nullptr; + request->impl = nullptr; } handleError(curl_multi_remove_handle(context->multi, handle)); @@ -723,33 +723,27 @@ void HTTPRequestImpl::handleResult(CURLcode code) { // ------------------------------------------------------------------------------------------------- -HTTPRequest::HTTPRequest(const Resource& resource_, Callback callback_) - : RequestBase(resource_, callback_) { +HTTPRequest::HTTPRequest(const Resource& resource_, Callback callback_, + uv_loop_t* loop, std::shared_ptr response) + : RequestBase(resource_, callback_) + , impl(new HTTPRequestImpl(this, loop, response)) { } HTTPRequest::~HTTPRequest() { - if (ptr) { - reinterpret_cast(ptr)->abandon(); + if (impl) { + impl->abandon(); } } -void HTTPRequest::start(uv_loop_t *loop, std::shared_ptr response) { - assert(!ptr); - ptr = new HTTPRequestImpl(this, loop, response); -} - void HTTPRequest::retryImmediately() { - if (ptr) { - reinterpret_cast(ptr)->retryImmediately(); + if (impl) { + impl->retryImmediately(); } } void HTTPRequest::cancel() { - if (ptr) { - delete reinterpret_cast(ptr); - ptr = nullptr; - } - + delete impl; + impl = nullptr; delete this; } diff --git a/src/mbgl/storage/asset_request.hpp b/src/mbgl/storage/asset_request.hpp index e20e1d818..3f9b018b5 100644 --- a/src/mbgl/storage/asset_request.hpp +++ b/src/mbgl/storage/asset_request.hpp @@ -3,20 +3,22 @@ #include "request_base.hpp" +typedef struct uv_loop_s uv_loop_t; + namespace mbgl { +class AssetRequestImpl; + class AssetRequest : public RequestBase { public: - AssetRequest(const Resource&, Callback, const std::string& assetRoot); + AssetRequest(const Resource&, Callback, uv_loop_t*, const std::string& assetRoot); - void start(uv_loop_t *loop, std::shared_ptr response = nullptr); - void cancel(); + void cancel() override; private: ~AssetRequest(); - void *ptr = nullptr; - const std::string& assetRoot; + AssetRequestImpl* impl; friend class AssetRequestImpl; }; diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index c510b5c7f..3e02c05fa 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -134,12 +134,10 @@ void DefaultFileSource::Impl::startRealRequest(const Resource& resource, std::sh }; if (algo::starts_with(resource.url, "asset://")) { - request->request = new AssetRequest(resource, callback, assetRoot); + request->request = new AssetRequest(resource, callback, request->loop, assetRoot); } else { - request->request = new HTTPRequest(resource, callback); + request->request = new HTTPRequest(resource, callback, request->loop, response); } - - request->request->start(request->loop, response); } void DefaultFileSource::Impl::cancel(Request* req) { diff --git a/src/mbgl/storage/http_request.hpp b/src/mbgl/storage/http_request.hpp index faf6ee2f1..bbe1265c6 100644 --- a/src/mbgl/storage/http_request.hpp +++ b/src/mbgl/storage/http_request.hpp @@ -3,23 +3,23 @@ #include "request_base.hpp" +typedef struct uv_loop_s uv_loop_t; + namespace mbgl { -struct Resource; +class HTTPRequestImpl; class HTTPRequest : public RequestBase { public: - HTTPRequest(const Resource&, Callback); - - void start(uv_loop_t *loop, std::shared_ptr response = nullptr); - void cancel(); + HTTPRequest(const Resource&, Callback, uv_loop_t*, std::shared_ptr = nullptr); + void cancel() override; void retryImmediately(); private: ~HTTPRequest(); - void *ptr = nullptr; + HTTPRequestImpl* impl; friend class HTTPRequestImpl; }; diff --git a/src/mbgl/storage/request_base.hpp b/src/mbgl/storage/request_base.hpp index 281e76a02..e4ea7117c 100644 --- a/src/mbgl/storage/request_base.hpp +++ b/src/mbgl/storage/request_base.hpp @@ -7,8 +7,6 @@ #include #include -typedef struct uv_loop_s uv_loop_t; - namespace mbgl { struct Resource; @@ -19,19 +17,16 @@ public: using Callback = std::function response, FileCache::Hint hint)>; RequestBase(const Resource& resource_, Callback notify_) - : notify(notify_) - , resource(resource_) { + : resource(resource_) + , notify(notify_) { } virtual ~RequestBase() = default; - - virtual void start(uv_loop_t *loop, std::shared_ptr response = nullptr) = 0; virtual void cancel() = 0; - Callback notify; - protected: const Resource& resource; + Callback notify; }; } From c0b75f1af77e78e309cb18807de74f3788488a7a Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 27 Apr 2015 13:05:30 -0700 Subject: [PATCH 041/373] Remove Environment::terminate and associated code Fixes #1336 --- include/mbgl/map/environment.hpp | 5 -- include/mbgl/storage/default_file_source.hpp | 9 +-- include/mbgl/storage/file_source.hpp | 14 +---- include/mbgl/storage/request.hpp | 8 +-- src/mbgl/map/environment.cpp | 10 +--- src/mbgl/storage/default_file_source.cpp | 41 +------------ src/mbgl/storage/default_file_source_impl.hpp | 1 - src/mbgl/storage/request.cpp | 4 +- test/fixtures/database/cache.db | Bin 0 -> 4096 bytes test/fixtures/database/invalid.db | Bin 0 -> 4096 bytes test/storage/cache_response.cpp | 5 +- test/storage/cache_revalidate.cpp | 14 ++--- test/storage/directory_reading.cpp | 6 +- test/storage/file_reading.cpp | 12 +--- test/storage/http_cancel.cpp | 9 +-- test/storage/http_coalescing.cpp | 4 +- test/storage/http_environment.cpp | 54 ------------------ test/storage/http_error.cpp | 6 +- test/storage/http_header_parsing.cpp | 6 +- test/storage/http_load.cpp | 4 +- test/storage/http_noloop.cpp | 4 +- test/storage/http_other_loop.cpp | 4 +- test/storage/http_reading.cpp | 14 ++--- test/test.gypi | 1 - 24 files changed, 42 insertions(+), 193 deletions(-) create mode 100644 test/fixtures/database/cache.db create mode 100644 test/fixtures/database/invalid.db delete mode 100644 test/storage/http_environment.cpp diff --git a/include/mbgl/map/environment.hpp b/include/mbgl/map/environment.hpp index 1cd33a5e6..a00fb2445 100644 --- a/include/mbgl/map/environment.hpp +++ b/include/mbgl/map/environment.hpp @@ -54,11 +54,6 @@ public: // Only call this while the OpenGL context is exclusive to this thread. void performCleanup(); - // ############################################################################################# - - // Request to terminate the environment. - void terminate(); - private: unsigned id; FileSource& fileSource; diff --git a/include/mbgl/storage/default_file_source.hpp b/include/mbgl/storage/default_file_source.hpp index f39374716..d50d5ddea 100644 --- a/include/mbgl/storage/default_file_source.hpp +++ b/include/mbgl/storage/default_file_source.hpp @@ -16,12 +16,9 @@ public: ~DefaultFileSource() override; // FileSource API - Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env, - Callback callback) override; - void cancel(Request *request) override; - void request(const Resource &resource, const Environment &env, Callback callback) override; - - void abort(const Environment &env) override; + Request* request(const Resource&, uv_loop_t*, Callback) override; + void cancel(Request*) override; + void request(const Resource&, Callback) override; public: class Impl; diff --git a/include/mbgl/storage/file_source.hpp b/include/mbgl/storage/file_source.hpp index 30e88c39f..535c41e81 100644 --- a/include/mbgl/storage/file_source.hpp +++ b/include/mbgl/storage/file_source.hpp @@ -15,7 +15,6 @@ typedef struct uv_loop_s uv_loop_t; namespace mbgl { class Request; -class Environment; class FileSource : private util::noncopyable { protected: @@ -28,19 +27,12 @@ public: // These can be called from any thread. The callback will be invoked in the loop. // You can only cancel a request from the same thread it was created in. - virtual Request *request(const Resource &resource, uv_loop_t *loop, const Environment &env, - Callback callback) = 0; - virtual void cancel(Request *request) = 0; + virtual Request* request(const Resource&, uv_loop_t*, Callback) = 0; + virtual void cancel(Request*) = 0; // These can be called from any thread. The callback will be invoked in an arbitrary other thread. // You cannot cancel these requests. - virtual void request(const Resource &resource, const Environment &env, Callback callback) = 0; - - // This can be called from any thread. All requests with the environment pointer env should be - // notified as errored. Note that this is /different/ from canceling requests; a canceled - // request's callback is never called, while an aborted request's callback is called with - // a error message. - virtual void abort(const Environment &env) = 0; + virtual void request(const Resource&, Callback) = 0; }; } diff --git a/include/mbgl/storage/request.hpp b/include/mbgl/storage/request.hpp index 00157329b..a01808ce8 100644 --- a/include/mbgl/storage/request.hpp +++ b/include/mbgl/storage/request.hpp @@ -17,14 +17,13 @@ typedef struct uv_loop_s uv_loop_t; namespace mbgl { class Response; -class Environment; class Request : private util::noncopyable { MBGL_STORE_THREAD(tid) public: using Callback = std::function; - Request(const Resource &resource, uv_loop_t *loop, const Environment &env, Callback callback); + Request(const Resource &resource, uv_loop_t *loop, Callback callback); public: // May be called from any thread. @@ -48,11 +47,6 @@ private: public: const Resource resource; - - // The environment ref is used to associate requests with a particular environment. This allows - // us to only terminate requests associated with that environment, e.g. when the map the env - // belongs to is discarded. - const Environment &env; }; } diff --git a/src/mbgl/map/environment.cpp b/src/mbgl/map/environment.cpp index 469790501..4c7a5faf8 100644 --- a/src/mbgl/map/environment.cpp +++ b/src/mbgl/map/environment.cpp @@ -122,13 +122,13 @@ unsigned Environment::getID() const { void Environment::requestAsync(const Resource& resource, std::function callback) { - fileSource.request(resource, *this, std::move(callback)); + fileSource.request(resource, std::move(callback)); } Request* Environment::request(const Resource& resource, std::function callback) { assert(currentlyOn(ThreadType::Map)); - return fileSource.request(resource, loop, *this, std::move(callback)); + return fileSource.request(resource, loop, std::move(callback)); } void Environment::cancelRequest(Request* req) { @@ -178,10 +178,4 @@ void Environment::performCleanup() { } } -// ############################################################################################# - -void Environment::terminate() { - fileSource.abort(*this); -} - } diff --git a/src/mbgl/storage/default_file_source.cpp b/src/mbgl/storage/default_file_source.cpp index 3e02c05fa..7080809d7 100644 --- a/src/mbgl/storage/default_file_source.cpp +++ b/src/mbgl/storage/default_file_source.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" @@ -38,9 +37,8 @@ DefaultFileSource::~DefaultFileSource() { Request* DefaultFileSource::request(const Resource& resource, uv_loop_t* l, - const Environment& env, Callback callback) { - auto req = new Request(resource, l, env, std::move(callback)); + auto req = new Request(resource, l, std::move(callback)); // This function can be called from any thread. Make sure we're executing the actual call in the // file source loop by sending it over the queue. @@ -49,8 +47,8 @@ Request* DefaultFileSource::request(const Resource& resource, return req; } -void DefaultFileSource::request(const Resource& resource, const Environment& env, Callback callback) { - request(resource, nullptr, env, std::move(callback)); +void DefaultFileSource::request(const Resource& resource, Callback callback) { + request(resource, nullptr, std::move(callback)); } void DefaultFileSource::cancel(Request *req) { @@ -61,10 +59,6 @@ void DefaultFileSource::cancel(Request *req) { thread->invoke(&Impl::cancel, req); } -void DefaultFileSource::abort(const Environment &env) { - thread->invoke(&Impl::abort, std::ref(env)); -} - // ----- Impl ----- DefaultFileSource::Impl::Impl(FileCache* cache_, const std::string& root) @@ -163,35 +157,6 @@ void DefaultFileSource::Impl::cancel(Request* req) { req->destruct(); } -// Aborts all requests that are part of the current environment. -void DefaultFileSource::Impl::abort(const Environment& env) { - // Construct a cancellation response. - auto response = std::make_shared(); - response->status = Response::Error; - response->message = "Environment is terminating"; - - // Iterate through all pending requests and remove them in case they're abandoned. - util::erase_if(pending, [&](std::pair& it) -> bool { - // Notify all pending requests that are in the current environment. - util::erase_if(it.second.observers, [&](Request* req) -> bool { - if (&req->env == &env) { - req->notify(response); - return true; - } else { - return false; - } - }); - - bool abandoned = it.second.observers.empty(); - - if (abandoned && it.second.request) { - it.second.request->cancel(); - } - - return abandoned; - }); -} - void DefaultFileSource::Impl::notify(DefaultFileRequest* request, std::shared_ptr response, FileCache::Hint hint) { // First, remove the request, since it might be destructed at any point now. assert(find(request->resource) == request); diff --git a/src/mbgl/storage/default_file_source_impl.hpp b/src/mbgl/storage/default_file_source_impl.hpp index d3f83af38..1d4da0906 100644 --- a/src/mbgl/storage/default_file_source_impl.hpp +++ b/src/mbgl/storage/default_file_source_impl.hpp @@ -26,7 +26,6 @@ public: void add(Request*, uv_loop_t*); void cancel(Request*); - void abort(const Environment&); private: DefaultFileRequest* find(const Resource&); diff --git a/src/mbgl/storage/request.cpp b/src/mbgl/storage/request.cpp index ea80e5950..d413cabbe 100644 --- a/src/mbgl/storage/request.cpp +++ b/src/mbgl/storage/request.cpp @@ -16,8 +16,8 @@ namespace mbgl { struct Request::Canceled { std::mutex mutex; bool confirmed = false; }; // Note: This requires that loop is running in the current thread (or not yet running). -Request::Request(const Resource &resource_, uv_loop_t *loop, const Environment &env_, Callback callback_) - : callback(callback_), resource(resource_), env(env_) { +Request::Request(const Resource &resource_, uv_loop_t *loop, Callback callback_) + : callback(callback_), resource(resource_) { // When there is no loop supplied (== nullptr), the callback will be fired in an arbitrary // thread (the thread notify() is called from) rather than kicking back to the calling thread. if (loop) { diff --git a/test/fixtures/database/cache.db b/test/fixtures/database/cache.db new file mode 100644 index 0000000000000000000000000000000000000000..c358381f1f2df0b84c23809ec23b385c7d082388 GIT binary patch literal 4096 zcmeH`-A=+V6oA`p5o5xY7u=rRNur5{7jQ@=$Q(LH0#|EgMHayUD+#yi6ZsUriBI8$ zWdpVl@Bx-KY1;GC)6=i#JU!Z>;4qBl6DFXB41_Vd20#dDavE}O#;%MvhJRKKUHlxE z^QxT@T*^z8ncL^#^P);{K~t_+gM!88{$rx{5=qAE&rfF-`nA6YP1+v$NSwTZi|ox=nVXfE;u&A5-v1&w~fIb#J+S zXp=rT9S@wYZJ#GTv0!2mQ<UO7|%7bV!m0oc!+%^?xkXx&3dvIB;X-Ac&iBZBno{eQs`)nbiMD{Z@{#CZu wWf>afRW0VbypXl29;FB<0{aM@tdy$%_n}cbMWFBmRR0(Li`4@afrAA800yR#H~;_u literal 0 HcmV?d00001 diff --git a/test/fixtures/database/invalid.db b/test/fixtures/database/invalid.db new file mode 100644 index 0000000000000000000000000000000000000000..f07e4af03da4e33ef3ee4027f39c92c6a2ec2ab0 GIT binary patch literal 4096 zcmeH}K~KUk6oA{6=rAEM(S*d))m?7o$ieT3d!%{ zQ^)qO=k-N$LOkno$r)6vMkTg8f!|ZB!kKW>RG>y+X-Y$)4meir9xwT~*T# zAIKoGodk`upXgD2XVhE7}PUlV2%$S>|&wK4)cu*`#5z4CYgEe(u pOumq6S~LMoV7UpblYDya8xYsO`ad5n_r>+?GyzRuo&X_c`WrA$q!IuC literal 0 HcmV?d00001 diff --git a/test/storage/cache_response.cpp b/test/storage/cache_response.cpp index d5dd8b36e..87de62025 100644 --- a/test/storage/cache_response.cpp +++ b/test/storage/cache_response.cpp @@ -14,9 +14,8 @@ TEST_F(Storage, CacheResponse) { DefaultFileSource fs(&cache); const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/cache" }; - auto &env = *static_cast(nullptr); - fs.request(resource, uv_default_loop(), env, [&](const Response &res) { + fs.request(resource, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Response 1", res.data); EXPECT_LT(0, res.expires); @@ -24,7 +23,7 @@ TEST_F(Storage, CacheResponse) { EXPECT_EQ("", res.etag); EXPECT_EQ("", res.message); - fs.request(resource, uv_default_loop(), env, [&, res](const Response &res2) { + fs.request(resource, uv_default_loop(), [&, res](const Response &res2) { EXPECT_EQ(res.status, res2.status); EXPECT_EQ(res.data, res2.data); EXPECT_EQ(res.expires, res2.expires); diff --git a/test/storage/cache_revalidate.cpp b/test/storage/cache_revalidate.cpp index ceb6b2969..1bfd6941b 100644 --- a/test/storage/cache_revalidate.cpp +++ b/test/storage/cache_revalidate.cpp @@ -15,10 +15,8 @@ TEST_F(Storage, CacheRevalidate) { SQLiteCache cache(":memory:"); DefaultFileSource fs(&cache); - auto &env = *static_cast(nullptr); - const Resource revalidateSame { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" }; - fs.request(revalidateSame, uv_default_loop(), env, [&](const Response &res) { + fs.request(revalidateSame, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Response", res.data); EXPECT_EQ(0, res.expires); @@ -26,7 +24,7 @@ TEST_F(Storage, CacheRevalidate) { EXPECT_EQ("snowfall", res.etag); EXPECT_EQ("", res.message); - fs.request(revalidateSame, uv_default_loop(), env, [&, res](const Response &res2) { + fs.request(revalidateSame, uv_default_loop(), [&, res](const Response &res2) { EXPECT_EQ(Response::Successful, res2.status); EXPECT_EQ("Response", res2.data); // We use this to indicate that a 304 reply came back. @@ -42,7 +40,7 @@ TEST_F(Storage, CacheRevalidate) { const Resource revalidateModified{ Resource::Unknown, "http://127.0.0.1:3000/revalidate-modified" }; - fs.request(revalidateModified, uv_default_loop(), env, [&](const Response &res) { + fs.request(revalidateModified, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Response", res.data); EXPECT_EQ(0, res.expires); @@ -50,7 +48,7 @@ TEST_F(Storage, CacheRevalidate) { EXPECT_EQ("", res.etag); EXPECT_EQ("", res.message); - fs.request(revalidateModified, uv_default_loop(), env, [&, res](const Response &res2) { + fs.request(revalidateModified, uv_default_loop(), [&, res](const Response &res2) { EXPECT_EQ(Response::Successful, res2.status); EXPECT_EQ("Response", res2.data); // We use this to indicate that a 304 reply came back. @@ -64,7 +62,7 @@ TEST_F(Storage, CacheRevalidate) { }); const Resource revalidateEtag { Resource::Unknown, "http://127.0.0.1:3000/revalidate-etag" }; - fs.request(revalidateEtag, uv_default_loop(), env, [&](const Response &res) { + fs.request(revalidateEtag, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Response 1", res.data); EXPECT_EQ(0, res.expires); @@ -72,7 +70,7 @@ TEST_F(Storage, CacheRevalidate) { EXPECT_EQ("response-1", res.etag); EXPECT_EQ("", res.message); - fs.request(revalidateEtag, uv_default_loop(), env, [&, res](const Response &res2) { + fs.request(revalidateEtag, uv_default_loop(), [&, res](const Response &res2) { EXPECT_EQ(Response::Successful, res2.status); EXPECT_EQ("Response 2", res2.data); EXPECT_EQ(0, res2.expires); diff --git a/test/storage/directory_reading.cpp b/test/storage/directory_reading.cpp index ccae4177c..4459b42c2 100644 --- a/test/storage/directory_reading.cpp +++ b/test/storage/directory_reading.cpp @@ -15,10 +15,8 @@ TEST_F(Storage, AssetReadDirectory) { DefaultFileSource fs(nullptr); #endif - auto &env = *static_cast(nullptr); - fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage" }, uv_default_loop(), - env, [&](const Response &res) { + [&](const Response &res) { EXPECT_EQ(Response::Error, res.status); EXPECT_EQ(0ul, res.data.size()); EXPECT_EQ(0, res.expires); @@ -27,7 +25,7 @@ TEST_F(Storage, AssetReadDirectory) { #ifdef MBGL_ASSET_ZIP EXPECT_EQ("No such file", res.message); #elif MBGL_ASSET_FS - EXPECT_EQ("illegal operation on a directory", res.message); + EXPECT_EQ("illegal operation on a directory", res.message); #endif ReadDirectory.finish(); }); diff --git a/test/storage/file_reading.cpp b/test/storage/file_reading.cpp index 01db75d5c..8db911f65 100644 --- a/test/storage/file_reading.cpp +++ b/test/storage/file_reading.cpp @@ -16,10 +16,8 @@ TEST_F(Storage, AssetEmptyFile) { DefaultFileSource fs(nullptr); #endif - auto &env = *static_cast(nullptr); - fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/empty" }, uv_default_loop(), - env, [&](const Response &res) { + [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ(0ul, res.data.size()); EXPECT_EQ(0, res.expires); @@ -43,10 +41,8 @@ TEST_F(Storage, AssetNonEmptyFile) { DefaultFileSource fs(nullptr); #endif - auto &env = *static_cast(nullptr); - fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/nonempty" }, - uv_default_loop(), env, [&](const Response &res) { + uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ(16ul, res.data.size()); EXPECT_EQ(0, res.expires); @@ -71,10 +67,8 @@ TEST_F(Storage, AssetNonExistentFile) { DefaultFileSource fs(nullptr); #endif - auto &env = *static_cast(nullptr); - fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/does_not_exist" }, - uv_default_loop(), env, [&](const Response &res) { + uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Error, res.status); EXPECT_EQ(0ul, res.data.size()); EXPECT_EQ(0, res.expires); diff --git a/test/storage/http_cancel.cpp b/test/storage/http_cancel.cpp index 80efb3977..a73182da5 100644 --- a/test/storage/http_cancel.cpp +++ b/test/storage/http_cancel.cpp @@ -14,10 +14,8 @@ TEST_F(Storage, HTTPCancel) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - auto req = - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env, + fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &) { ADD_FAILURE() << "Callback should not be called"; }); fs.cancel(req); @@ -33,13 +31,12 @@ TEST_F(Storage, HTTPCancelMultiple) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" }; - auto req2 = fs.request(resource, uv_default_loop(), env, [&](const Response &) { + auto req2 = fs.request(resource, uv_default_loop(), [&](const Response &) { ADD_FAILURE() << "Callback should not be called"; }); - fs.request(resource, uv_default_loop(), env, [&](const Response &res) { + fs.request(resource, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(0, res.expires); diff --git a/test/storage/http_coalescing.cpp b/test/storage/http_coalescing.cpp index 28fa4415b..5c90009f8 100644 --- a/test/storage/http_coalescing.cpp +++ b/test/storage/http_coalescing.cpp @@ -14,8 +14,6 @@ TEST_F(Storage, HTTPCoalescing) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - static const Response *reference = nullptr; const auto complete = [&](const Response &res) { @@ -43,7 +41,7 @@ TEST_F(Storage, HTTPCoalescing) { const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" }; for (int i = 0; i < total; i++) { - fs.request(resource, uv_default_loop(), env, complete); + fs.request(resource, uv_default_loop(), complete); } uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/test/storage/http_environment.cpp b/test/storage/http_environment.cpp deleted file mode 100644 index 41a9d43d5..000000000 --- a/test/storage/http_environment.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "storage.hpp" - -#include - -#include -#include - -#include - -TEST_F(Storage, HTTPCancelEnvironment) { - SCOPED_TEST(HTTPRetainedEnvironment) - SCOPED_TEST(HTTPCanceledEnvironment) - - using namespace mbgl; - - DefaultFileSource fs(nullptr); - - // Create two fake environment pointers. The FileSource implementation treats these as opaque - // pointers and doesn't reach into them. - auto &env1 = *reinterpret_cast(1); - auto &env2 = *reinterpret_cast(2); - - const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/delayed" }; - - // Environment 1 - fs.request(resource, uv_default_loop(), env1, [&](const Response &res) { - // This environment gets aborted below. This means the request is marked as failing and - // will return an error here. - EXPECT_EQ(Response::Error, res.status); - EXPECT_EQ("", res.data); - EXPECT_EQ(0, res.expires); - EXPECT_EQ(0, res.modified); - EXPECT_EQ("", res.etag); - EXPECT_EQ("Environment is terminating", res.message); - HTTPCanceledEnvironment.finish(); - }); - - // Environment 2 - fs.request(resource, uv_default_loop(), env2, [&](const Response &res) { - // The same request as above, but in a different environment which doesn't get aborted. This - // means the request should succeed. - EXPECT_EQ(Response::Successful, res.status); - EXPECT_EQ("Response", res.data); - EXPECT_EQ(0, res.expires); - EXPECT_EQ(0, res.modified); - EXPECT_EQ("", res.etag); - EXPECT_EQ("", res.message); - HTTPRetainedEnvironment.finish(); - }); - - fs.abort(env1); - - uv_run(uv_default_loop(), UV_RUN_DEFAULT); -} diff --git a/test/storage/http_error.cpp b/test/storage/http_error.cpp index e5728d97b..eeb8117a0 100644 --- a/test/storage/http_error.cpp +++ b/test/storage/http_error.cpp @@ -22,12 +22,10 @@ TEST_F(Storage, HTTPError) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - auto start = uv_hrtime(); fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, uv_default_loop(), - env, [&](const Response &res) { + [&](const Response &res) { const auto duration = double(uv_hrtime() - start) / 1e9; EXPECT_LT(1, duration) << "Backoff timer didn't wait 1 second"; EXPECT_GT(1.2, duration) << "Backoff timer fired too late"; @@ -41,7 +39,7 @@ TEST_F(Storage, HTTPError) { HTTPTemporaryError.finish(); }); - fs.request({ Resource::Unknown, "http://127.0.0.1:3001/" }, uv_default_loop(), env, + fs.request({ Resource::Unknown, "http://127.0.0.1:3001/" }, uv_default_loop(), [&](const Response &res) { const auto duration = double(uv_hrtime() - start) / 1e9; // 1.5 seconds == 4 retries, with a 500ms timeout (see above). diff --git a/test/storage/http_header_parsing.cpp b/test/storage/http_header_parsing.cpp index 1561660b6..5f18b163a 100644 --- a/test/storage/http_header_parsing.cpp +++ b/test/storage/http_header_parsing.cpp @@ -15,11 +15,9 @@ TEST_F(Storage, HTTPHeaderParsing) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?modified=1420794326&expires=1420797926&etag=foo" }, - uv_default_loop(), env, [&](const Response &res) { + uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(1420797926, res.expires); @@ -33,7 +31,7 @@ TEST_F(Storage, HTTPHeaderParsing) { SystemClock::now().time_since_epoch()).count(); fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?cachecontrol=max-age=120" }, - uv_default_loop(), env, [&](const Response &res) { + uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Hello World!", res.data); EXPECT_GT(2, std::abs(res.expires - now - 120)) << "Expiration date isn't about 120 seconds in the future"; diff --git a/test/storage/http_load.cpp b/test/storage/http_load.cpp index c4069eba3..2347a76ab 100644 --- a/test/storage/http_load.cpp +++ b/test/storage/http_load.cpp @@ -11,8 +11,6 @@ TEST_F(Storage, HTTPLoad) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - const int concurrency = 50; const int max = 10000; int number = 1; @@ -21,7 +19,7 @@ TEST_F(Storage, HTTPLoad) { const auto current = number++; fs.request({ Resource::Unknown, std::string("http://127.0.0.1:3000/load/") + std::to_string(current) }, - uv_default_loop(), env, [&, current](const Response &res) { + uv_default_loop(), [&, current](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ(std::string("Request ") + std::to_string(current), res.data); EXPECT_EQ(0, res.expires); diff --git a/test/storage/http_noloop.cpp b/test/storage/http_noloop.cpp index cd4ebeb2c..e133d3e0c 100644 --- a/test/storage/http_noloop.cpp +++ b/test/storage/http_noloop.cpp @@ -12,8 +12,6 @@ TEST_F(Storage, HTTPNoLoop) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - const auto mainThread = uv_thread_self(); // Async handle that keeps the main loop alive until the thread finished @@ -22,7 +20,7 @@ TEST_F(Storage, HTTPNoLoop) { uv::close(as); }); - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, nullptr, env, + fs.request({ Resource::Unknown, "http://127.0.0.1:3000/temporary-error" }, nullptr, [&](const Response &res) { EXPECT_NE(uv_thread_self(), mainThread) << "Response was called in the same thread"; EXPECT_EQ(Response::Successful, res.status); diff --git a/test/storage/http_other_loop.cpp b/test/storage/http_other_loop.cpp index 9ad673cf7..64612f13d 100644 --- a/test/storage/http_other_loop.cpp +++ b/test/storage/http_other_loop.cpp @@ -12,9 +12,7 @@ TEST_F(Storage, HTTPOtherLoop) { // This file source launches a separate thread to do the processing. DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env, + fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(Response::Successful, res.status); EXPECT_EQ("Hello World!", res.data); diff --git a/test/storage/http_reading.cpp b/test/storage/http_reading.cpp index 350a8eaa4..09d33fd6a 100644 --- a/test/storage/http_reading.cpp +++ b/test/storage/http_reading.cpp @@ -14,11 +14,9 @@ TEST_F(Storage, HTTPReading) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - const auto mainThread = uv_thread_self(); - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env, + fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), [&](const Response &res) { EXPECT_EQ(uv_thread_self(), mainThread); EXPECT_EQ(Response::Successful, res.status); @@ -31,7 +29,7 @@ TEST_F(Storage, HTTPReading) { }); fs.request({ Resource::Unknown, "http://127.0.0.1:3000/doesnotexist" }, uv_default_loop(), - env, [&](const Response &res) { + [&](const Response &res) { EXPECT_EQ(uv_thread_self(), mainThread); EXPECT_EQ(Response::Error, res.status); EXPECT_EQ("HTTP status code 404", res.message); @@ -51,9 +49,7 @@ TEST_F(Storage, HTTPNoCallback) { DefaultFileSource fs(nullptr); - auto &env = *static_cast(nullptr); - - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), env, + fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, uv_default_loop(), nullptr); uv_run(uv_default_loop(), UV_RUN_DEFAULT); @@ -68,10 +64,8 @@ TEST_F(Storage, HTTPCallbackNotOnLoop) { SCOPED_TEST(HTTPTest) - auto &env = *static_cast(nullptr); - std::promise promise; - fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, env, [&] (const Response &) { + fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test" }, [&] (const Response &) { promise.set_value(); }); diff --git a/test/test.gypi b/test/test.gypi index 5c975d547..d22dc3b43 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -62,7 +62,6 @@ 'storage/file_reading.cpp', 'storage/http_cancel.cpp', 'storage/http_coalescing.cpp', - 'storage/http_environment.cpp', 'storage/http_error.cpp', 'storage/http_header_parsing.cpp', 'storage/http_load.cpp', From 473aa281c7e379060c6dba60b7ba6b69c6f0bdf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Tue, 28 Apr 2015 11:48:57 +0200 Subject: [PATCH 042/373] make meta-target for all iOS targets too and split up project.gyp this will make it easier to add more targets to iOS builds in the future. It'll also help by having Xcode files named after the platform they're for, so it's easier to distinguish windows --- Makefile | 24 +++++++++---------- gyp/ios.gyp | 5 ++++ gyp/linux.gyp | 7 ++++++ gyp/osx.gyp | 8 +++++++ gyp/project.gyp | 19 --------------- .../{mapboxgl-app.gyp => mapboxgl-app.gypi} | 16 ++++++------- 6 files changed, 40 insertions(+), 39 deletions(-) create mode 100644 gyp/ios.gyp create mode 100644 gyp/linux.gyp create mode 100644 gyp/osx.gyp delete mode 100644 gyp/project.gyp rename ios/app/{mapboxgl-app.gyp => mapboxgl-app.gypi} (80%) diff --git a/Makefile b/Makefile index b87ceb0ac..d1552d1a8 100644 --- a/Makefile +++ b/Makefile @@ -46,11 +46,11 @@ KIF: .PRECIOUS: Makefile/project Makefile/project: config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp gyp/project.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make + deps/run_gyp gyp/$(HOST).gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make .PRECIOUS: Xcode/project Xcode/project: config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp gyp/project.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode + deps/run_gyp gyp/$(HOST).gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode #### Library builds ############################################################ @@ -77,7 +77,7 @@ test-%: test .PHONY: xtest xtest: XCPRETTY := $(shell ./scripts/xcpretty.sh) xtest: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) $(XCPRETTY) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) $(XCPRETTY) xtest-%: xtest ./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$* @@ -94,11 +94,11 @@ run-osx: osx .PHONY: xosx-proj xosx run-xosx xosx-proj: Xcode/project - open ./build/osx/gyp/project.xcodeproj + open ./build/osx/gyp/osx.xcodeproj xosx: XCPRETTY := $(shell ./scripts/xcpretty.sh) xosx: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) $(XCPRETTY) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) $(XCPRETTY) run-xosx: xosx "gyp/build/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" @@ -111,20 +111,20 @@ xproj: xosx-proj #### iOS application builds #################################################### .PRECIOUS: Xcode/ios -Xcode/ios: ios/app/mapboxgl-app.gyp config/ios.gypi styles/styles SMCalloutView - deps/run_gyp ios/app/mapboxgl-app.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode +Xcode/ios: gyp/ios.gyp config/ios.gypi styles/styles SMCalloutView + deps/run_gyp gyp/ios.gyp $(CONFIG_ios) $(LIBS_ios) --generator-output=./build/ios -f xcode .PHONY: ios-proj ios isim ipackage ios-proj: Xcode/ios - open ./build/ios/ios/app/mapboxgl-app.xcodeproj + open ./build/ios/gyp/ios.xcodeproj ios: XCPRETTY := $(shell ./scripts/xcpretty.sh) ios: Xcode/ios - xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) $(XCPRETTY) + xcodebuild -sdk iphoneos ARCHS="arm64 armv7 armv7s" PROVISIONING_PROFILE="2b532944-bf3d-4bf4-aa6c-a81676984ae8" -project ./build/ios/gyp/ios.xcodeproj -configuration Release -target iosapp -jobs $(JOBS) $(XCPRETTY) isim: XCPRETTY := $(shell ./scripts/xcpretty.sh) isim: Xcode/ios - xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/ios/app/mapboxgl-app.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) $(XCPRETTY) + xcodebuild -sdk iphonesimulator ARCHS="x86_64 i386" -project ./build/ios/gyp/ios.xcodeproj -configuration Debug -target iosapp -jobs $(JOBS) $(XCPRETTY) ipackage: clean Xcode/ios ./scripts/ios/package.sh @@ -148,7 +148,7 @@ run-linux: linux .PHONY: xlinux run-xlinux xlinux: XCPRETTY := $(shell ./scripts/xcpretty.sh) xlinux: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) $(XCPRETTY) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) $(XCPRETTY) run-xlinux: xlinux "gyp/build/$(BUILDTYPE)/mapbox-gl" @@ -191,7 +191,7 @@ render: Makefile/project .PHONY: xrender run-xrender xrender: Xcode/project - xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS) + xcodebuild -project ./build/osx/gyp/osx.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS) ##### Maintenace operations #################################################### diff --git a/gyp/ios.gyp b/gyp/ios.gyp new file mode 100644 index 000000000..989f34cb7 --- /dev/null +++ b/gyp/ios.gyp @@ -0,0 +1,5 @@ +{ + 'includes': [ + '../ios/app/mapboxgl-app.gypi', + ], +} diff --git a/gyp/linux.gyp b/gyp/linux.gyp new file mode 100644 index 000000000..0f7126934 --- /dev/null +++ b/gyp/linux.gyp @@ -0,0 +1,7 @@ +{ + 'includes': [ + '../linux/mapboxgl-app.gypi', + '../test/test.gypi', + '../bin/render.gypi', + ], +} diff --git a/gyp/osx.gyp b/gyp/osx.gyp new file mode 100644 index 000000000..64663540b --- /dev/null +++ b/gyp/osx.gyp @@ -0,0 +1,8 @@ +{ + 'includes': [ + '../macosx/mapboxgl-app.gypi', + '../linux/mapboxgl-app.gypi', + '../test/test.gypi', + '../bin/render.gypi', + ], +} diff --git a/gyp/project.gyp b/gyp/project.gyp deleted file mode 100644 index 9f53eef51..000000000 --- a/gyp/project.gyp +++ /dev/null @@ -1,19 +0,0 @@ -{ - 'conditions': [ - ['host == "osx"', { - 'includes': [ - '../macosx/mapboxgl-app.gypi', - '../linux/mapboxgl-app.gypi', - '../test/test.gypi', - '../bin/render.gypi', - ] - }], - ['host == "linux"', { - 'includes': [ - '../linux/mapboxgl-app.gypi', - '../test/test.gypi', - '../bin/render.gypi', - ] - }], - ], -} diff --git a/ios/app/mapboxgl-app.gyp b/ios/app/mapboxgl-app.gypi similarity index 80% rename from ios/app/mapboxgl-app.gyp rename to ios/app/mapboxgl-app.gypi index 0e093a1d8..73b66dff1 100644 --- a/ios/app/mapboxgl-app.gyp +++ b/ios/app/mapboxgl-app.gypi @@ -9,18 +9,18 @@ 'product_extension': 'app', 'mac_bundle': 1, 'mac_bundle_resources': [ - ' Date: Mon, 23 Mar 2015 12:11:39 +0100 Subject: [PATCH 043/373] move TransformState to MapData object --- include/mbgl/map/map.hpp | 7 ++----- src/mbgl/map/map.cpp | 19 ++++++++---------- src/mbgl/map/map_data.hpp | 15 ++++++++++++++ src/mbgl/map/source.cpp | 42 +++++++++++++++++++++++---------------- src/mbgl/map/source.hpp | 27 ++++++++++++++++++++----- 5 files changed, 72 insertions(+), 38 deletions(-) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index f9738debe..148509ece 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -144,8 +144,8 @@ public: inline double getMetersPerPixelAtLatitude(const double lat, const double zoom) const { return Projection::getMetersPerPixelAtLatitude(lat, zoom); } inline const ProjectedMeters projectedMetersForLatLng(const LatLng latLng) const { return Projection::projectedMetersForLatLng(latLng); } inline const LatLng latLngForProjectedMeters(const ProjectedMeters projectedMeters) const { return Projection::latLngForProjectedMeters(projectedMeters); } - inline const vec2 pixelForLatLng(const LatLng latLng) const { return state.pixelForLatLng(latLng); } - inline const LatLng latLngForPixel(const vec2 pixel) const { return state.latLngForPixel(pixel); } + inline const vec2 pixelForLatLng(const LatLng latLng) const { return transform.currentState().pixelForLatLng(latLng); } + inline const LatLng latLngForPixel(const vec2 pixel) const { return transform.currentState().latLngForPixel(pixel); } // Annotations void setDefaultPointAnnotationSymbol(const std::string&); @@ -168,8 +168,6 @@ public: void toggleDebug(); bool getDebug() const; - inline const TransformState &getState() const { return state; } - TimePoint getTime() const; inline AnnotationManager& getAnnotationManager() const { return *annotationManager; } private: @@ -245,7 +243,6 @@ private: std::atomic_bool isStopped; Transform transform; - TransformState state; FileSource& fileSource; diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index e931d09e0..74b153862 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -450,7 +450,8 @@ std::string Map::getStyleJSON() const { } util::ptr Map::getSprite() { - const float pixelRatio = state.getPixelRatio(); + assert(Environment::currentlyOn(ThreadType::Map)); + const float pixelRatio = data->getTransformState().getPixelRatio(); const std::string &sprite_url = style->getSpriteURL(); if (!sprite || !sprite->hasPixelRatio(pixelRatio)) { sprite = Sprite::Create(sprite_url, pixelRatio, *env); @@ -672,10 +673,6 @@ bool Map::getDebug() const { return data->getDebug(); } -TimePoint Map::getTime() const { - return data->getAnimationTime(); -} - void Map::addClass(const std::string& klass) { if (data->addClass(klass)) { triggerUpdate(Update::Classes); @@ -717,7 +714,7 @@ void Map::updateTiles() { assert(Environment::currentlyOn(ThreadType::Map)); if (!style) return; for (const auto& source : style->sources) { - source->update(*this, getWorker(), style, *glyphAtlas, *glyphStore, + source->update(*this, *data, getWorker(), style, *glyphAtlas, *glyphStore, *spriteAtlas, getSprite(), *texturePool, [this]() { assert(Environment::currentlyOn(ThreadType::Map)); triggerUpdate(); @@ -728,7 +725,7 @@ void Map::updateTiles() { void Map::update() { assert(Environment::currentlyOn(ThreadType::Map)); - if (state.hasSize()) { + if (data->getTransformState().hasSize()) { prepare(); } } @@ -792,7 +789,7 @@ void Map::prepare() { u |= static_cast(Update::StyleInfo); } - state = transform.currentState(); + data->setTransformState(transform.currentState()); if (u & static_cast(Update::StyleInfo)) { reloadStyle(); @@ -828,11 +825,11 @@ void Map::prepare() { if (u & static_cast(Update::StyleInfo) || u & static_cast(Update::Classes) || u & static_cast(Update::Zoom)) { - style->recalculate(state.getNormalizedZoom(), now); + style->recalculate(data->getTransformState().getNormalizedZoom(), now); } // Allow the sprite atlas to potentially pull new sprite images if needed. - spriteAtlas->resize(state.getPixelRatio()); + spriteAtlas->resize(data->getTransformState().getPixelRatio()); spriteAtlas->setSprite(getSprite()); updateTiles(); @@ -854,7 +851,7 @@ void Map::render() { assert(style); assert(painter); - painter->render(*style, state, data->getAnimationTime()); + painter->render(*style, data->getTransformState(), data->getAnimationTime()); // Schedule another rerender when we definitely need a next frame. if (transform.needsTransition() || style->hasTransitions()) { diff --git a/src/mbgl/map/map_data.hpp b/src/mbgl/map/map_data.hpp index 718c3eb0e..cbb1b5413 100644 --- a/src/mbgl/map/map_data.hpp +++ b/src/mbgl/map/map_data.hpp @@ -7,6 +7,10 @@ #include #include #include +#include + +#include +#include namespace mbgl { @@ -87,12 +91,23 @@ public: defaultTransitionDuration = duration; }; + // Make sure the state is only accessible/modifiable from the Map thread. + inline const TransformState& getTransformState() const { + assert(Environment::currentlyOn(ThreadType::Map)); + return transformState; + } + inline void setTransformState(const TransformState& state) { + assert(Environment::currentlyOn(ThreadType::Map)); + transformState = state; + } + private: mutable std::mutex mtx; StyleInfo styleInfo; std::string accessToken; std::vector classes; + TransformState transformState; std::atomic debug { false }; std::atomic animationTime; std::atomic defaultTransitionDuration; diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp index 9e318964b..aa171ee43 100644 --- a/src/mbgl/map/source.cpp +++ b/src/mbgl/map/source.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -215,11 +216,17 @@ TileData::State Source::hasTile(const TileID& id) { return TileData::State::invalid; } -TileData::State Source::addTile(Map &map, Worker &worker, - util::ptr