From 0bb2e05063436202cbd5e657f5cf87a4819da397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Sat, 18 Apr 2015 23:28:51 -0700 Subject: [PATCH 01/27] weakSelf needs strongSelf The `weakSelf` dance requires the use of a `strongSelf` in non-trivial blocks. In these cases, `weakSelf` could disappear right out from under the block. A crash could potentially occur due to setting a `nil` value in an `NSMutableDictionary`. --- platform/ios/MGLMapboxEvents.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 605c6a3fa..149d90904 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -267,6 +267,9 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; __weak MGLMapboxEvents *weakSelf = self; dispatch_async(_serialQueue, ^{ + MGLMapboxEvents *strongSelf = weakSelf; + if ( ! strongSelf) return; + // Opt Out Checking When Built if (![[NSUserDefaults standardUserDefaults] boolForKey:@"mapbox_metrics_enabled_preference"]) { [_eventQueue removeAllObjects]; @@ -350,6 +353,9 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; __weak MGLMapboxEvents *weakSelf = self; dispatch_async(_serialQueue, ^{ + MGLMapboxEvents *strongSelf = weakSelf; + if ( ! strongSelf) return; + __block NSArray *events; NSUInteger upper = weakSelf.flushAt; @@ -379,6 +385,9 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; __weak MGLMapboxEvents *weakSelf = self; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + MGLMapboxEvents *strongSelf = weakSelf; + if ( ! strongSelf) return; + // Setup URL Request NSString *url = [NSString stringWithFormat:@"%@/events/v1?access_token=%@", MGLMapboxEventsAPIBase, weakSelf.token]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; From 2ec09a663f89a41ebe083a56c6a6944cc8b9293d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Mon, 20 Apr 2015 09:58:05 -0700 Subject: [PATCH 02/27] Use `strongSelf` inside blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’d be pointless to create a `strongSelf` but not use it; `weakSelf` isn’t guaranteed to exist past that point. --- platform/ios/MGLMapboxEvents.m | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/platform/ios/MGLMapboxEvents.m b/platform/ios/MGLMapboxEvents.m index 149d90904..e7a0702ab 100644 --- a/platform/ios/MGLMapboxEvents.m +++ b/platform/ios/MGLMapboxEvents.m @@ -50,7 +50,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; // from within a single thread use underscore syntax. // // All captures of `self` from within asynchronous -// dispatches will use a `weakSelf` to avoid cyclical +// dispatches will use a `strongSelf` to avoid cyclical // strong references. // @@ -293,35 +293,35 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; // mapbox-events stock attributes [evt setObject:event forKey:@"event"]; [evt setObject:@(1) forKey:@"version"]; - [evt setObject:[weakSelf.rfc3339DateFormatter stringFromDate:[NSDate date]] forKey:@"created"]; - [evt setObject:weakSelf.instanceID forKey:@"instance"]; - [evt setObject:weakSelf.advertiserId forKey:@"advertiserId"]; - [evt setObject:weakSelf.vendorId forKey:@"vendorId"]; - [evt setObject:weakSelf.appBundleId forKeyedSubscript:@"appBundleId"]; + [evt setObject:[strongSelf.rfc3339DateFormatter stringFromDate:[NSDate date]] forKey:@"created"]; + [evt setObject:strongSelf.instanceID forKey:@"instance"]; + [evt setObject:strongSelf.advertiserId forKey:@"advertiserId"]; + [evt setObject:strongSelf.vendorId forKey:@"vendorId"]; + [evt setObject:strongSelf.appBundleId forKeyedSubscript:@"appBundleId"]; // mapbox-events-ios stock attributes - [evt setValue:weakSelf.model forKey:@"model"]; - [evt setValue:weakSelf.iOSVersion forKey:@"operatingSystem"]; - [evt setValue:[weakSelf getDeviceOrientation] forKey:@"orientation"]; + [evt setValue:strongSelf.model forKey:@"model"]; + [evt setValue:strongSelf.iOSVersion forKey:@"operatingSystem"]; + [evt setValue:[strongSelf getDeviceOrientation] forKey:@"orientation"]; [evt setValue:@(100 * [UIDevice currentDevice].batteryLevel) forKey:@"batteryLevel"]; - [evt setValue:@(weakSelf.scale) forKey:@"resolution"]; - [evt setValue:weakSelf.carrier forKey:@"carrier"]; + [evt setValue:@(strongSelf.scale) forKey:@"resolution"]; + [evt setValue:strongSelf.carrier forKey:@"carrier"]; - NSString *cell = [weakSelf getCurrentCellularNetworkConnectionType]; + NSString *cell = [strongSelf getCurrentCellularNetworkConnectionType]; if (cell) { [evt setValue:cell forKey:@"cellularNetworkType"]; } else { [evt setObject:[NSNull null] forKey:@"cellularNetworkType"]; } - NSString *wifi = [weakSelf getWifiNetworkName]; + NSString *wifi = [strongSelf getWifiNetworkName]; if (wifi) { [evt setValue:wifi forKey:@"wifi"]; } else { [evt setObject:[NSNull null] forKey:@"wifi"]; } - [evt setValue:@([weakSelf getContentSizeScale]) forKey:@"accessibilityFontScale"]; + [evt setValue:@([strongSelf getContentSizeScale]) forKey:@"accessibilityFontScale"]; // Make Immutable Version NSDictionary *finalEvent = [NSDictionary dictionaryWithDictionary:evt]; @@ -330,12 +330,12 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; [_eventQueue addObject:finalEvent]; // Has Flush Limit Been Reached? - if (_eventQueue.count >= weakSelf.flushAt) { - [weakSelf flush]; + if (_eventQueue.count >= strongSelf.flushAt) { + [strongSelf flush]; } // Reset Timer (Initial Starting of Timer after first event is pushed) - [weakSelf startTimer]; + [strongSelf startTimer]; }); } @@ -358,8 +358,8 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; __block NSArray *events; - NSUInteger upper = weakSelf.flushAt; - if (weakSelf.flushAt > [_eventQueue count]) { + NSUInteger upper = strongSelf.flushAt; + if (strongSelf.flushAt > [_eventQueue count]) { if ([_eventQueue count] == 0) { return; } @@ -374,7 +374,7 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; [_eventQueue removeObjectsInRange:theRange]; // Send Array of Events to Server - [weakSelf postEvents:events]; + [strongSelf postEvents:events]; }); } @@ -389,9 +389,9 @@ NSString *const MGLEventGestureRotateStart = @"Rotation"; if ( ! strongSelf) return; // Setup URL Request - NSString *url = [NSString stringWithFormat:@"%@/events/v1?access_token=%@", MGLMapboxEventsAPIBase, weakSelf.token]; + NSString *url = [NSString stringWithFormat:@"%@/events/v1?access_token=%@", MGLMapboxEventsAPIBase, strongSelf.token]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; - [request setValue:[weakSelf getUserAgent] forHTTPHeaderField:@"User-Agent"]; + [request setValue:[strongSelf getUserAgent] forHTTPHeaderField:@"User-Agent"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setHTTPMethod:@"POST"]; From e1cf6d1515e74e5ee4f9868aa1a4b19c44e77ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Wed, 22 Apr 2015 12:45:09 -0700 Subject: [PATCH 03/27] Refactored constraints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing Visual Format Language usage necessitated various ternaries and over-wide lines that made the code harder to grok. Now it’s just plain ol’ Objective-C, mostly column-80-compliant. This change also adds additional constraint relations so that the various subviews respect the `MGLView`’s frame when it’s smaller than the view controller’s root view. Fixes #1327. --- platform/ios/MGLMapView.mm | 148 +++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 48 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5f5e99b0e..e57bc3414 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -491,70 +491,122 @@ 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. // - NSString *topGuideFormatString = (self.viewControllerForLayoutGuides ? @"[topLayoutGuide]" : @"|"); - NSString *bottomGuideFormatString = (self.viewControllerForLayoutGuides ? @"[bottomLayoutGuide]" : @"|"); - - id topGuideViewsObject = (self.viewControllerForLayoutGuides ? (id)self.viewControllerForLayoutGuides.topLayoutGuide : (id)@""); - id bottomGuideViewsObject = (self.viewControllerForLayoutGuides ? (id)self.viewControllerForLayoutGuides.bottomLayoutGuide : (id)@""); - - UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? self.viewControllerForLayoutGuides.view : self); + UIView *constraintParentView = (self.viewControllerForLayoutGuides.view ? + self.viewControllerForLayoutGuides.view : + self); // compass // UIView *compassContainer = self.compass.superview; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:%@-topSpacing-[container]", topGuideFormatString] - options:0 - metrics:@{ @"topSpacing" : @(5) } - views:@{ @"topLayoutGuide" : topGuideViewsObject, - @"container" : compassContainer }]]; + if (self.viewControllerForLayoutGuides) + { + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.viewControllerForLayoutGuides.topLayoutGuide + attribute:NSLayoutAttributeBottom + multiplier:1 + constant:5]]; + } + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self + attribute:NSLayoutAttributeTop + multiplier:1 + constant:5]]; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[container]-rightSpacing-|" - options:0 - metrics:@{ @"rightSpacing" : @(5) } - views:@{ @"container" : compassContainer }]]; + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeRight + relatedBy:NSLayoutRelationEqual + toItem:compassContainer + attribute:NSLayoutAttributeRight + multiplier:1 + constant:5]]; - [compassContainer addConstraint:[NSLayoutConstraint constraintWithItem:compassContainer - attribute:NSLayoutAttributeWidth - relatedBy:NSLayoutRelationEqual - toItem:nil - attribute:NSLayoutAttributeNotAnAttribute - multiplier:1 - constant:self.compass.image.size.width]]; + [compassContainer addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1 + constant:self.compass.image.size.width]]; - [compassContainer addConstraint:[NSLayoutConstraint constraintWithItem:compassContainer - attribute:NSLayoutAttributeHeight - relatedBy:NSLayoutRelationEqual - toItem:nil - attribute:NSLayoutAttributeNotAnAttribute - multiplier:1 - constant:self.compass.image.size.height]]; + [compassContainer addConstraint: + [NSLayoutConstraint constraintWithItem:compassContainer + attribute:NSLayoutAttributeHeight + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1 + constant:self.compass.image.size.height]]; // logo bug // - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[logoBug]-bottomSpacing-%@", bottomGuideFormatString] - options:0 - metrics:@{ @"bottomSpacing" : @(4) } - views:@{ @"logoBug" : self.logoBug, - @"bottomLayoutGuide" : bottomGuideViewsObject }]]; + if (self.viewControllerForLayoutGuides) + { + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.logoBug + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:4]]; + } + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.logoBug + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:4]]; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-leftSpacing-[logoBug]" - options:0 - metrics:@{ @"leftSpacing" : @(8) } - views:@{ @"logoBug" : self.logoBug }]]; + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self.logoBug + attribute:NSLayoutAttributeLeft + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeLeft + multiplier:1 + constant:8]]; // attribution button // - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:@"V:[attributionButton]-bottomSpacing-%@", bottomGuideFormatString] - options:0 - metrics:@{ @"bottomSpacing" : @(8) } - views:@{ @"attributionButton" : self.attributionButton, - @"bottomLayoutGuide" : bottomGuideViewsObject }]]; + if (self.viewControllerForLayoutGuides) + { + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self.viewControllerForLayoutGuides.bottomLayoutGuide + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.attributionButton + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:8]]; + } + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.attributionButton + attribute:NSLayoutAttributeBaseline + multiplier:1 + constant:8]]; - [constraintParentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[attributionButton]-rightSpacing-|" - options:0 - metrics:@{ @"rightSpacing" : @(8) } - views:@{ @"attributionButton" : self.attributionButton }]]; + [constraintParentView addConstraint: + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeRight + relatedBy:NSLayoutRelationEqual + toItem:self.attributionButton + attribute:NSLayoutAttributeRight + multiplier:1 + constant:8]]; [super updateConstraints]; } From 8ab22c11a26e58acb7467770eae5b1013c5dad8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Wed, 22 Apr 2015 12:48:15 -0700 Subject: [PATCH 04/27] Clip MGLMapView to its bounds Fixes #1300. --- platform/ios/MGLMapView.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index e57bc3414..0d2ad1edb 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -242,7 +242,8 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; _glView.contentMode = UIViewContentModeCenter; - [self setBackgroundColor:[UIColor clearColor]]; + self.backgroundColor = [UIColor clearColor]; + self.clipsToBounds = YES; // load extensions // From 9b8b072d28c61a6cca2e4aea3631f8b5660bedad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Wed, 22 Apr 2015 15:33:56 -0700 Subject: [PATCH 05/27] Cleaned up subview layout No need to set the frames manually since we set up constraints as soon as the `MGLMapView` is added to the view hierarchy. Set proper edge insets on the logo bug rather than fudging constraint constants. --- platform/ios/MGLMapView.mm | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 0d2ad1edb..405b643c0 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -294,9 +294,9 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; // setup logo bug // - _logoBug = [[UIImageView alloc] initWithImage:[MGLMapView resourceImageNamed:@"mapbox.png"]]; + UIImage *logo = [[MGLMapView resourceImageNamed:@"mapbox.png"] imageWithAlignmentRectInsets:UIEdgeInsetsMake(1.5, 4, 3.5, 2)]; + _logoBug = [[UIImageView alloc] initWithImage:logo]; _logoBug.accessibilityLabel = @"Mapbox logo"; - _logoBug.frame = CGRectMake(8, self.bounds.size.height - _logoBug.bounds.size.height - 4, _logoBug.bounds.size.width, _logoBug.bounds.size.height); _logoBug.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_logoBug]; @@ -305,7 +305,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; _attributionButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; _attributionButton.accessibilityLabel = @"Attribution info"; [_attributionButton addTarget:self action:@selector(showAttribution:) forControlEvents:UIControlEventTouchUpInside]; - _attributionButton.frame = CGRectMake(self.bounds.size.width - _attributionButton.bounds.size.width - 8, self.bounds.size.height - _attributionButton.bounds.size.height - 8, _attributionButton.bounds.size.width, _attributionButton.bounds.size.height); _attributionButton.translatesAutoresizingMaskIntoConstraints = NO; [self addSubview:_attributionButton]; @@ -316,7 +315,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; UIImage *compassImage = [MGLMapView resourceImageNamed:@"Compass.png"]; _compass.frame = CGRectMake(0, 0, compassImage.size.width, compassImage.size.height); _compass.alpha = 0; - UIView *container = [[UIView alloc] initWithFrame:CGRectMake(self.bounds.size.width - compassImage.size.width - 5, 5, compassImage.size.width, compassImage.size.height)]; + UIView *container = [[UIView alloc] initWithFrame:CGRectZero]; [container addSubview:_compass]; container.translatesAutoresizingMaskIntoConstraints = NO; [container addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleCompassTapGesture:)]]; @@ -558,7 +557,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; toItem:self.logoBug attribute:NSLayoutAttributeBaseline multiplier:1 - constant:4]]; + constant:8]]; } [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:self @@ -567,7 +566,7 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; toItem:self.logoBug attribute:NSLayoutAttributeBaseline multiplier:1 - constant:4]]; + constant:8]]; [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:self.logoBug From b43ba4089cf5aefe86fde1dae2fd5c06bd7bf784 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 22 Apr 2015 00:20:03 -0700 Subject: [PATCH 06/27] fixes #1308: normalize tile memory cache keys & allow dupe inserts --- src/mbgl/map/source.cpp | 6 +++--- src/mbgl/map/tile_cache.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp index 3245bab2e..9e318964b 100644 --- a/src/mbgl/map/source.cpp +++ b/src/mbgl/map/source.cpp @@ -245,7 +245,7 @@ TileData::State Source::addTile(Map &map, Worker &worker, } if (!new_tile.data) { - new_tile.data = cache.get(id.to_uint64()); + new_tile.data = cache.get(normalized_id.to_uint64()); } if (!new_tile.data) { @@ -418,7 +418,7 @@ void Source::update(Map &map, if (!obsolete) { retain_data.insert(tile.data->id); } else if (type != SourceType::Raster && tile.data->ready()) { - tileCache.add(tile.id.to_uint64(), tile.data); + tileCache.add(tile.id.normalized().to_uint64(), tile.data); } return obsolete; }); @@ -432,7 +432,7 @@ void Source::update(Map &map, bool obsolete = retain_data.find(tile->id) == retain_data.end(); if (obsolete) { - if (!tileCache.has(tile->id.to_uint64())) { + if (!tileCache.has(tile->id.normalized().to_uint64())) { tile->cancel(); } return true; diff --git a/src/mbgl/map/tile_cache.cpp b/src/mbgl/map/tile_cache.cpp index b64c8e2a6..25aed6d15 100644 --- a/src/mbgl/map/tile_cache.cpp +++ b/src/mbgl/map/tile_cache.cpp @@ -20,11 +20,16 @@ void TileCache::setSize(size_t size_) { void TileCache::add(uint64_t key, std::shared_ptr data) { - assert(tiles.find(key) == tiles.end()); + // insert new or query existing data + if (tiles.emplace(key, data).second) { + // remove existing data key + orderedKeys.remove(key); + } - tiles.emplace(key, data); + // (re-)insert data key as newest orderedKeys.push_back(key); + // purge oldest key/data if necessary if (orderedKeys.size() > size) { get(orderedKeys.front()); } From 44e2bf419f1495f177381a2bc294629bda59f411 Mon Sep 17 00:00:00 2001 From: Jason Wray Date: Tue, 21 Apr 2015 22:19:28 -0700 Subject: [PATCH 07/27] =?UTF-8?q?Correct=20indentation=20=E2=80=94=20#1315?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build-version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build-version.py b/scripts/build-version.py index 3fe789185..0110e6a2e 100755 --- a/scripts/build-version.py +++ b/scripts/build-version.py @@ -13,9 +13,9 @@ else: if sys.argv[2] == sys.argv[3]: tag = [0, 0, 0] else: - ver = re.sub("[^0-9.]", "", sys.argv[2]) + ver = re.sub("[^0-9.]", "", sys.argv[2]) tag = map(int, ver.split('.')) - rev = sys.argv[3][0:8] + rev = sys.argv[3][0:8] def mkdir_p(path): From 38315fd667c546f9ed181fc2762c36d1f403245f Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 23 Apr 2015 08:59:26 -0700 Subject: [PATCH 08/27] bump podspec to 0.2.15 --- ios/MapboxGL.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/MapboxGL.podspec b/ios/MapboxGL.podspec index 29e406362..57de3f6f3 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.14' + m.version = '0.2.15' 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 c7769d9a97d05c843ba3b5a1ca79404a125e363a Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 23 Apr 2015 09:00:24 -0700 Subject: [PATCH 09/27] [publish ios-v0.2.15] From fec1cf0e23a97b0f76f0aaabf0a71004e5a1dac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Thu, 23 Apr 2015 15:02:06 -0700 Subject: [PATCH 10/27] RTL-friendly constraints Use leading/trailing instead of left/right for subview constraints for eventual right-to-left flippedness. --- platform/ios/MGLMapView.mm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 405b643c0..3094d2f8c 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -521,10 +521,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:self - attribute:NSLayoutAttributeRight + attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:compassContainer - attribute:NSLayoutAttributeRight + attribute:NSLayoutAttributeTrailing multiplier:1 constant:5]]; @@ -570,10 +570,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:self.logoBug - attribute:NSLayoutAttributeLeft + attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self - attribute:NSLayoutAttributeLeft + attribute:NSLayoutAttributeLeading multiplier:1 constant:8]]; @@ -601,10 +601,10 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [constraintParentView addConstraint: [NSLayoutConstraint constraintWithItem:self - attribute:NSLayoutAttributeRight + attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.attributionButton - attribute:NSLayoutAttributeRight + attribute:NSLayoutAttributeTrailing multiplier:1 constant:8]]; From 7e335cafdc5ad6ec05bcc41f603962c85f90002f Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 23 Apr 2015 16:19:45 -0700 Subject: [PATCH 11/27] tighten up compass alpha adjustments & remove dupe --- platform/ios/MGLMapView.mm | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 5f5e99b0e..75c06532d 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -1151,12 +1151,6 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; if (finished) { [self notifyMapChange:@(animated ? mbgl::MapChangeRegionDidChangeAnimated : mbgl::MapChangeRegionDidChange)]; - - [UIView animateWithDuration:MGLAnimationDuration - animations:^ - { - self.compass.alpha = 0; - }]; } }]; } @@ -2255,6 +2249,17 @@ CLLocationCoordinate2D latLngToCoordinate(mbgl::LatLng latLng) } completion:nil]; } + else if (mbglMap->getBearing() == 0 && self.compass.alpha > 0) + { + [UIView animateWithDuration:MGLAnimationDuration + delay:0 + options:UIViewAnimationOptionBeginFromCurrentState + animations:^ + { + self.compass.alpha = 0; + } + completion:nil]; + } } + (UIImage *)resourceImageNamed:(NSString *)imageName From b528d7cc039f2a0abbf1eb6c77a7fc2099bc3a19 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Thu, 23 Apr 2015 17:54:08 -0700 Subject: [PATCH 12/27] fixes #830, #880: bring back iOS functional tests --- .gitmodules | 2 +- .travis.yml | 5 + Makefile | 6 + README.md | 2 + scripts/ios_travis/upload_screenshots.sh | 13 + scripts/package_ios.sh | 4 +- scripts/test_ios.sh | 16 + scripts/travis_script.sh | 21 +- test/ios/KIF | 2 +- test/ios/KIFTestActor+MapboxGL.h | 1 + test/ios/KIFTestActor+MapboxGL.m | 5 +- test/ios/MGLTAppDelegate.h | 2 +- test/ios/MGLTViewController.m | 2 +- test/ios/MapViewTests.h | 5 - test/ios/MapViewTests.m | 291 +++++++++++------- test/ios/README.md | 9 - test/ios/ios-tests.xcodeproj/project.pbxproj | 167 ++++------ .../xcshareddata/ios-tests.xccheckout | 24 +- .../xcschemes/Mapbox GL Tests.xcscheme | 13 +- 19 files changed, 329 insertions(+), 261 deletions(-) create mode 100755 scripts/ios_travis/upload_screenshots.sh create mode 100755 scripts/test_ios.sh delete mode 100644 test/ios/MapViewTests.h delete mode 100644 test/ios/README.md diff --git a/.gitmodules b/.gitmodules index 9e5265a6a..6a4b1d516 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,7 +12,7 @@ [submodule "test/ios/KIF"] path = test/ios/KIF - url = https://github.com/mapbox/KIF.git + url = https://github.com/kif-framework/KIF.git [submodule "platform/ios/vendor/SMCalloutView"] path = platform/ios/vendor/SMCalloutView diff --git a/.travis.yml b/.travis.yml index 690b2b1b6..71936b872 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,6 +57,7 @@ env: - 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 @@ -68,6 +69,7 @@ before_install: - ./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 install: - ulimit -c @@ -88,6 +90,9 @@ script: after_script: - ./scripts/ios_travis/remove-key.sh +after_failure: +- if [[ ${TRAVIS_OS_NAME} == "osx" && ${TEST_OS} == "ios" ]]; then ./scripts/ios_travis/upload_screenshots.sh; fi + notifications: slack: secure: HHQYr7sF8M1SzoWSqgKVYtwAgGdLLCyTMsQjFhEEQNYO92ZwURE5s03qWTGH5k8+4Yqn26yrXt3NztLC4JIOpcGervN2mSZyq4dZgFTcWEd61igw0qwSenlwvFfbE1ASK/KYCzfyn9MIfHN+ovwLoRxXZkPwinKDvl3DXjBaFNg= diff --git a/Makefile b/Makefile index 14f78ed0f..d0cf4407c 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,9 @@ styles/styles: SMCalloutView: git submodule update --init platform/ios/vendor/SMCalloutView +KIF: + git submodule update --init test/ios/KIF + #### Library builds ############################################################ .PRECIOUS: Makefile/mbgl @@ -129,6 +132,9 @@ isim: Xcode/ios ipackage: clean Xcode/ios ./scripts/package_ios.sh +itest: ipackage KIF + ./scripts/test_ios.sh + # Legacy name iproj: ios-proj diff --git a/README.md b/README.md index c423c21b5..a44b13861 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ If you merely want to install the library for iOS and try it out as an Objective If you want to build from source and/or contribute to development of the project, run `make iproj`, which will create and open an Xcode project which can build the entire library from source as well as an Objective-C test app. +You can also run `make itest` to run the included tests. Requires `brew install xcpretty`. + Target devices: iPhone 4S and above (5, 5c, 5s, 6, 6 Plus) and iPad 2 and above (3, 4, Mini, Air, Mini 2, Air 2). Target iOS: 7.0 through 8.1 diff --git a/scripts/ios_travis/upload_screenshots.sh b/scripts/ios_travis/upload_screenshots.sh new file mode 100755 index 000000000..88a6427f7 --- /dev/null +++ b/scripts/ios_travis/upload_screenshots.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -u + +ls $KIF_SCREENSHOTS/ + +REPO_NAME=$(basename $TRAVIS_REPO_SLUG) + +aws s3 cp $KIF_SCREENSHOTS/ s3://mapbox/$REPO_NAME/ios/tests/$TRAVIS_JOB_NUMBER/ --acl public-read --recursive > /dev/null + +echo http://mapbox.s3.amazonaws.com/$REPO_NAME/ios/tests/$TRAVIS_JOB_NUMBER/index.html diff --git a/scripts/package_ios.sh b/scripts/package_ios.sh index da55b297a..a651d2734 100755 --- a/scripts/package_ios.sh +++ b/scripts/package_ios.sh @@ -33,9 +33,10 @@ export BUILDTYPE=${BUILDTYPE:-Release} export HOST=ios make Xcode/mbgl -step "Building iOS targets..." +step "Building iOS device targets..." xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \ ARCHS="arm64 armv7 armv7s" \ + ONLY_ACTIVE_ARCH=NO \ -project ./build/ios/mbgl.xcodeproj \ -configuration ${BUILDTYPE} \ -target everything \ @@ -45,6 +46,7 @@ xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \ step "Building iOS Simulator targets..." xcodebuild -sdk iphonesimulator${IOS_SDK_VERSION} \ ARCHS="x86_64 i386" \ + ONLY_ACTIVE_ARCH=NO \ -project ./build/ios/mbgl.xcodeproj \ -configuration ${BUILDTYPE} \ -target everything \ diff --git a/scripts/test_ios.sh b/scripts/test_ios.sh new file mode 100755 index 000000000..77d4d90ad --- /dev/null +++ b/scripts/test_ios.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -u + +xcodebuild \ + -project ./test/ios/ios-tests.xcodeproj \ + -scheme 'Mapbox GL Tests' \ + -sdk iphonesimulator \ + -destination 'platform=iOS Simulator,name=iPhone 5s,OS=7.1' \ + -destination 'platform=iOS Simulator,name=iPhone 5s,OS=latest' \ + -destination 'platform=iOS Simulator,name=iPad 2,OS=7.1' \ + -destination 'platform=iOS Simulator,name=iPad 2,OS=latest' \ + test \ + | xcpretty diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh index 0351f9414..093b31273 100755 --- a/scripts/travis_script.sh +++ b/scripts/travis_script.sh @@ -48,15 +48,24 @@ elif [[ ${TRAVIS_OS_NAME} == "osx" && ${MASON_PLATFORM} == "osx" ]]; then elif [[ ${TRAVIS_OS_NAME} == "osx" && ${MASON_PLATFORM} == "ios" ]]; then # - # build & package iOS - # - mapbox_time "package_ios" - make ipackage - # - # conditionally deploy iOS build + # 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/test/ios/KIF b/test/ios/KIF index ab5a46ff7..976aafa2e 160000 --- a/test/ios/KIF +++ b/test/ios/KIF @@ -1 +1 @@ -Subproject commit ab5a46ff7e970de5578df48a1e1f013bd5e1bd4e +Subproject commit 976aafa2e211dd095411bfef09da6c0919d70476 diff --git a/test/ios/KIFTestActor+MapboxGL.h b/test/ios/KIFTestActor+MapboxGL.h index 199091b29..df83b2377 100644 --- a/test/ios/KIFTestActor+MapboxGL.h +++ b/test/ios/KIFTestActor+MapboxGL.h @@ -1,3 +1,4 @@ +#import #import @class MGLMapView; diff --git a/test/ios/KIFTestActor+MapboxGL.m b/test/ios/KIFTestActor+MapboxGL.m index b267e0c0b..ef40c1bed 100644 --- a/test/ios/KIFTestActor+MapboxGL.m +++ b/test/ios/KIFTestActor+MapboxGL.m @@ -1,7 +1,8 @@ #import "KIFTestActor+MapboxGL.h" + +#import "MapboxGL.h" + #import -#import -#import "MGLMapView.h" @implementation KIFTestActor (MapboxGL) diff --git a/test/ios/MGLTAppDelegate.h b/test/ios/MGLTAppDelegate.h index e5c459beb..c0025582e 100644 --- a/test/ios/MGLTAppDelegate.h +++ b/test/ios/MGLTAppDelegate.h @@ -2,6 +2,6 @@ @interface MGLTAppDelegate : UIResponder -@property (strong, nonatomic) UIWindow *window; +@property (nonatomic) UIWindow *window; @end diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m index 9caa64c79..e839c4504 100644 --- a/test/ios/MGLTViewController.m +++ b/test/ios/MGLTViewController.m @@ -1,5 +1,5 @@ #import "MGLTViewController.h" -#import "MGLMapView.h" +#import "MapboxGL.h" @implementation MGLTViewController diff --git a/test/ios/MapViewTests.h b/test/ios/MapViewTests.h deleted file mode 100644 index 5057ffd64..000000000 --- a/test/ios/MapViewTests.h +++ /dev/null @@ -1,5 +0,0 @@ -#import - -@interface MapViewTests : KIFTestCase - -@end diff --git a/test/ios/MapViewTests.m b/test/ios/MapViewTests.m index adf3aeba0..deed521b7 100644 --- a/test/ios/MapViewTests.m +++ b/test/ios/MapViewTests.m @@ -1,9 +1,11 @@ -#import "MapViewTests.h" +#import #import -#import "KIFTestActor+MapboxGL.h" -#import "MGLMapView.h" -@interface MapViewTests () +#import "KIFTestActor+MapboxGL.h" + +#import "MapboxGL.h" + +@interface MapViewTests : KIFTestCase @end @@ -11,120 +13,132 @@ - (void)beforeEach { [system simulateDeviceRotationToOrientation:UIDeviceOrientationPortrait]; - tester.mapView.viewControllerForLayoutGuides = tester.viewController; + tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.913175, -77.032458); tester.mapView.zoomLevel = 14; tester.mapView.direction = 0; + tester.mapView.zoomEnabled = YES; tester.mapView.scrollEnabled = YES; tester.mapView.rotateEnabled = YES; + tester.viewController.navigationController.navigationBarHidden = YES; tester.viewController.navigationController.toolbarHidden = YES; + tester.mapView.delegate = self; } - (void)testDirectionSet { tester.mapView.direction = 270; - __KIFAssertEqual(tester.mapView.direction, - 270, - @"setting direction should take effect"); + + XCTAssertEqual(tester.mapView.direction, + 270, + @"setting direction should take effect"); [tester waitForTimeInterval:1]; - __KIFAssertEqual(tester.compass.alpha, - 1, - @"compass should be visible when map is rotated"); - __KIFAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], - [NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation(M_PI * 1.5)], - @"compass rotation should indicate map rotation"); + XCTAssertEqual(tester.compass.alpha, + 1, + @"compass should be visible when map is rotated"); + + XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], + [NSValue valueWithCGAffineTransform:CGAffineTransformMakeRotation(M_PI * 1.5)], + @"compass rotation should indicate map rotation"); } - (void)testCompassTap { tester.mapView.direction = 180; - __KIFAssertEqual(tester.mapView.direction, - 180, - @"setting direction should take effect"); - [tester waitForTimeInterval:1]; + XCTAssertEqual(tester.mapView.direction, + 180, + @"setting direction should take effect"); [tester.compass tap]; [tester waitForTimeInterval:1]; - __KIFAssertEqual(tester.mapView.direction, - 0, - @"tapping compass should reset map direction"); - __KIFAssertEqual(tester.compass.alpha, - 0, - @"compass should not be visible when map is unrotated"); - __KIFAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], - [NSValue valueWithCGAffineTransform:CGAffineTransformIdentity], - @"compass rotation should indicate map rotation"); + XCTAssertEqual(tester.mapView.direction, + 0, + @"tapping compass should reset map direction"); + + XCTAssertEqual(tester.compass.alpha, + 0, + @"compass should not be visible when map is unrotated"); + + XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], + [NSValue valueWithCGAffineTransform:CGAffineTransformIdentity], + @"compass rotation should indicate map rotation"); } - (void)testDirectionReset { - tester.mapView.direction = 100; - __KIFAssertEqual(tester.mapView.direction, - 100, - @"setting direction should take effect"); + tester.mapView.direction = 90; + + XCTAssertEqual(tester.mapView.direction, + 90, + @"setting direction should take effect"); [tester.mapView resetNorth]; [tester waitForTimeInterval:1]; - __KIFAssertEqual(tester.mapView.direction, - 0, - @"resetting north should reset map direction"); - __KIFAssertEqual(tester.compass.alpha, - 0, - @"compass should not be visible when map is unrotated"); - __KIFAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], - [NSValue valueWithCGAffineTransform:CGAffineTransformIdentity], - @"compass rotation should indicate map rotation"); + XCTAssertEqual(tester.mapView.direction, + 0, + @"resetting north should reset map direction"); + + XCTAssertEqual(tester.compass.alpha, + 0, + @"compass should not be visible when map is unrotated"); + + XCTAssertEqualObjects([NSValue valueWithCGAffineTransform:tester.compass.transform], + [NSValue valueWithCGAffineTransform:CGAffineTransformIdentity], + @"compass rotation should indicate map rotation"); } - (void)testZoom { double zoom = tester.mapView.zoomLevel; - [tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, + [tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, tester.mapView.bounds.size.height / 2) distance:50 steps:10]; - XCTAssertTrue(tester.mapView.zoomLevel > zoom, - @"zoom gesture should increase zoom level"); + XCTAssertGreaterThan(tester.mapView.zoomLevel, + zoom, + @"zoom gesture should increase zoom level"); zoom = tester.mapView.zoomLevel; - [tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, + + [tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, tester.mapView.bounds.size.height / 2) distance:50 steps:10]; - XCTAssertTrue(tester.mapView.zoomLevel < zoom, - @"pinch gesture should decrease zoom level"); + XCTAssertLessThan(tester.mapView.zoomLevel, + zoom, + @"pinch gesture should decrease zoom level"); } - (void)testZoomDisabled { tester.mapView.zoomEnabled = NO; double zoom = tester.mapView.zoomLevel; - [tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, + [tester.mapView zoomAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, tester.mapView.bounds.size.height / 2) distance:50 steps:10]; - __KIFAssertEqual(tester.mapView.zoomLevel, - zoom, - @"disabling zoom gesture should disallow zooming"); + XCTAssertEqual(tester.mapView.zoomLevel, + zoom, + @"disabling zoom gesture should disallow zooming"); - [tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, - tester.mapView.bounds.size.height / 2) + [tester.mapView pinchAtPoint:CGPointMake(tester.mapView.bounds.size.width / 2, + tester.mapView.bounds.size.height / 2) distance:50 steps:10]; - __KIFAssertEqual(tester.mapView.zoomLevel, - zoom, - @"disabling zoom gesture should disallow pinching"); + XCTAssertEqual(tester.mapView.zoomLevel, + zoom, + @"disabling zoom gesture should disallow pinching"); } - (void)testPan { @@ -132,10 +146,13 @@ [tester.mapView dragFromPoint:CGPointMake(10, 10) toPoint:CGPointMake(300, 300) steps:10]; - XCTAssertTrue(tester.mapView.centerCoordinate.latitude > centerCoordinate.latitude, - @"panning map down should increase center latitude"); - XCTAssertTrue(tester.mapView.centerCoordinate.longitude < centerCoordinate.longitude, - @"panning map right should decrease center longitude"); + XCTAssertGreaterThan(tester.mapView.centerCoordinate.latitude, + centerCoordinate.latitude, + @"panning map down should increase center latitude"); + + XCTAssertLessThan(tester.mapView.centerCoordinate.longitude, + centerCoordinate.longitude, + @"panning map right should decrease center longitude"); } - (void)testPanDisabled { @@ -144,42 +161,82 @@ [tester.mapView dragFromPoint:CGPointMake(10, 10) toPoint:CGPointMake(300, 300) steps:10]; - __KIFAssertEqual(centerCoordinate.latitude, - tester.mapView.centerCoordinate.latitude, - @"disabling pan gesture should disallow vertical panning"); - __KIFAssertEqual(centerCoordinate.longitude, - tester.mapView.centerCoordinate.longitude, - @"disabling pan gesture should disallow horizontal panning"); + XCTAssertEqualWithAccuracy(centerCoordinate.latitude, + tester.mapView.centerCoordinate.latitude, + 0.005, + @"disabling pan gesture should disallow vertical panning"); + + XCTAssertEqualWithAccuracy(centerCoordinate.longitude, + tester.mapView.centerCoordinate.longitude, + 0.005, + @"disabling pan gesture should disallow horizontal panning"); +} + +- (void)testRotate { + CLLocationDirection startAngle = tester.mapView.direction; + + XCTAssertNotEqual(startAngle, + 45, + @"start angle must not be destination angle"); + + [tester.mapView twoFingerRotateAtPoint:tester.mapView.center angle:45]; + + XCTAssertGreaterThanOrEqual(fabs(tester.mapView.direction - startAngle), + 20, + @"rotating map should change angle"); +} + +- (void)testRotateDisabled { + tester.mapView.rotateEnabled = NO; + CLLocationDirection startAngle = tester.mapView.direction; + + XCTAssertNotEqual(startAngle, + 45, + @"start angle must not be destination angle"); + + [tester.mapView twoFingerRotateAtPoint:tester.mapView.center angle:45]; + + XCTAssertEqualWithAccuracy(tester.mapView.direction, + startAngle, + 0.005, + @"disabling rotation show disallow rotation gestures"); } - (void)testCenterSet { CLLocationCoordinate2D newCenterCoordinate = CLLocationCoordinate2DMake(45.23237263, -122.23287129); + XCTAssertNotEqual(tester.mapView.centerCoordinate.latitude, newCenterCoordinate.latitude, @"initial setup should have differing center latitude"); + XCTAssertNotEqual(tester.mapView.centerCoordinate.longitude, newCenterCoordinate.longitude, @"initial setup should have differing center longitude"); - [tester.mapView setCenterCoordinate:newCenterCoordinate]; + tester.mapView.centerCoordinate = newCenterCoordinate; - XCTAssertTrue(tester.mapView.centerCoordinate.latitude == newCenterCoordinate.latitude, - @"setting center should change latitude"); - XCTAssertTrue(tester.mapView.centerCoordinate.longitude == newCenterCoordinate.longitude, - @"setting center should change longitude"); + XCTAssertEqual(tester.mapView.centerCoordinate.latitude, + newCenterCoordinate.latitude, + @"setting center should change latitude"); + + XCTAssertEqual(tester.mapView.centerCoordinate.longitude, + newCenterCoordinate.longitude, + @"setting center should change longitude"); } - (void)testZoomSet { double newZoom = 11.65; + XCTAssertNotEqual(tester.mapView.zoomLevel, newZoom, @"initial setup should have differing zoom"); tester.mapView.zoomLevel = newZoom; - __KIFAssertEqual(tester.mapView.zoomLevel, - newZoom, - @"setting zoom should take effect"); + XCTAssertEqualWithAccuracy(tester.mapView.zoomLevel, + newZoom, + 0.01, + @"setting zoom should take effect"); } - (void)testTopLayoutGuide { @@ -233,7 +290,7 @@ logoBugFrame = [logoBug.superview convertRect:logoBug.frame toView:nil]; toolbarFrame = [tester.window convertRect:toolbar.frame toView:nil]; XCTAssertFalse(CGRectIntersectsRect(logoBugFrame, toolbarFrame), - @"rotated device should not have logo buy under toolbar"); + @"rotated device should not have logo bug under toolbar"); attributionButtonFrame = [attributionButton.superview convertRect:attributionButton.frame toView:nil]; XCTAssertFalse(CGRectIntersectsRect(attributionButtonFrame, toolbarFrame), @@ -241,11 +298,11 @@ } - (void)testDelegateRegionWillChange { - __block NSUInteger unanimatedCount = 0; - __block NSUInteger animatedCount = 0; + __block NSUInteger unanimatedCount; + __block NSUInteger animatedCount; [[NSNotificationCenter defaultCenter] addObserverForName:@"regionWillChangeAnimated" object:tester.mapView - queue:[NSOperationQueue mainQueue] + queue:nil usingBlock:^(NSNotification *note) { if ([note.userInfo[@"animated"] boolValue]) { animatedCount++; @@ -254,35 +311,40 @@ } }]; + [tester waitForTimeInterval:1]; + + unanimatedCount = 0; + animatedCount = 0; + NSNotification *notification = [system waitForNotificationName:@"regionWillChangeAnimated" object:tester.mapView whileExecutingBlock:^{ tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 0); }]; + [tester waitForTimeInterval:1]; - XCTAssertNotNil(notification, - @"regionWillChange delegate should produce a notification"); - __KIFAssertEqual([notification.userInfo[@"animated"] boolValue], - NO, - @"regionWillChange delegate should not indicate animated change"); - __KIFAssertEqual(unanimatedCount, - 1, - @"regionWillChange delegate should indicate one unanimated change"); + + XCTAssertEqual([notification.userInfo[@"animated"] boolValue], + NO, + @"regionWillChange delegate should not indicate animated change"); + XCTAssertEqual(unanimatedCount, + 1, + @"regionWillChange delegate should indicate one unanimated change"); notification = [system waitForNotificationName:@"regionWillChangeAnimated" object:tester.mapView whileExecutingBlock:^{ [tester.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45, 100) animated:YES]; }]; + [tester waitForTimeInterval:1]; - XCTAssertNotNil(notification, - @"regionWillChange delegate should produce a notification"); - __KIFAssertEqual([notification.userInfo[@"animated"] boolValue], - YES, - @"regionWillChange delegate should indicate an animated change"); - __KIFAssertEqual(animatedCount, - 1, - @"regionWillChange delegate should indicate one animated change"); + + XCTAssertEqual([notification.userInfo[@"animated"] boolValue], + YES, + @"regionWillChange delegate should indicate an animated change"); + XCTAssertEqual(animatedCount, + 1, + @"regionWillChange delegate should indicate one animated change"); [[NSNotificationCenter defaultCenter] removeObserver:self name:@"regionWillChangeAnimated" @@ -296,11 +358,11 @@ } - (void)testDelegateRegionDidChange { - __block NSUInteger unanimatedCount = 0; - __block NSUInteger animatedCount = 0; + __block NSUInteger unanimatedCount; + __block NSUInteger animatedCount; [[NSNotificationCenter defaultCenter] addObserverForName:@"regionDidChangeAnimated" object:tester.mapView - queue:[NSOperationQueue mainQueue] + queue:nil usingBlock:^(NSNotification *note) { if ([note.userInfo[@"animated"] boolValue]) { animatedCount++; @@ -309,35 +371,40 @@ } }]; + [tester waitForTimeInterval:1]; + + unanimatedCount = 0; + animatedCount = 0; + NSNotification *notification = [system waitForNotificationName:@"regionDidChangeAnimated" object:tester.mapView whileExecutingBlock:^{ tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 0); }]; + [tester waitForTimeInterval:1]; - XCTAssertNotNil(notification, - @"regionDidChange delegate should produce a notification"); - __KIFAssertEqual([notification.userInfo[@"animated"] boolValue], - NO, - @"regionDidChange delegate should not indicate animated change"); - __KIFAssertEqual(unanimatedCount, - 1, - @"regionDidChange delegate should indicate one unanimated change"); + + XCTAssertEqual([notification.userInfo[@"animated"] boolValue], + NO, + @"regionDidChange delegate should not indicate animated change"); + XCTAssertEqual(unanimatedCount, + 1, + @"regionDidChange delegate should indicate one unanimated change"); notification = [system waitForNotificationName:@"regionDidChangeAnimated" object:tester.mapView whileExecutingBlock:^{ [tester.mapView setCenterCoordinate:CLLocationCoordinate2DMake(45, 100) animated:YES]; }]; + [tester waitForTimeInterval:1]; - XCTAssertNotNil(notification, - @"regionDidChange delegate should produce a notification"); - __KIFAssertEqual([notification.userInfo[@"animated"] boolValue], - YES, - @"regionDidChange delegate should indicate animated change"); - __KIFAssertEqual(animatedCount, - 1, - @"regionDidChange delegate should indicate one animated change"); + + XCTAssertEqual([notification.userInfo[@"animated"] boolValue], + YES, + @"regionDidChange delegate should indicate animated change"); + XCTAssertEqual(animatedCount, + 1, + @"regionDidChange delegate should indicate one animated change"); [[NSNotificationCenter defaultCenter] removeObserver:self name:@"regionDidChangeAnimated" diff --git a/test/ios/README.md b/test/ios/README.md deleted file mode 100644 index 21975e177..000000000 --- a/test/ios/README.md +++ /dev/null @@ -1,9 +0,0 @@ -This is a harness app for integration testing of Mapbox GL Cocoa. It uses the static library build of Mapbox GL Cocoa in order to be entirely self-contained and not need the `mapbox-gl-native` upstream C++ project. - -To run tests, either open the enclosed `ios-tests.xcodeproj` and run the tests or use `xcodebuild test` at the command line from this directory. For example: - -```bash -xcodebuild -scheme 'Mapbox GL Tests' \ - -destination 'platform=iOS Simulator,name=iPad,OS=7.1' \ - test -``` diff --git a/test/ios/ios-tests.xcodeproj/project.pbxproj b/test/ios/ios-tests.xcodeproj/project.pbxproj index 86f125132..f644d912d 100644 --- a/test/ios/ios-tests.xcodeproj/project.pbxproj +++ b/test/ios/ios-tests.xcodeproj/project.pbxproj @@ -7,27 +7,24 @@ objects = { /* Begin PBXBuildFile section */ - DD043327196DB9BC00E6F39D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043326196DB9BC00E6F39D /* Foundation.framework */; }; - DD043329196DB9BC00E6F39D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043328196DB9BC00E6F39D /* CoreGraphics.framework */; }; - DD04332B196DB9BC00E6F39D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD04332A196DB9BC00E6F39D /* UIKit.framework */; }; DD043363196DBBD500E6F39D /* MGLTAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DD04335F196DBBD500E6F39D /* MGLTAppDelegate.m */; }; DD043364196DBBD500E6F39D /* MGLTViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DD043360196DBBD500E6F39D /* MGLTViewController.m */; }; DD043366196DBBE000E6F39D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DD043365196DBBE000E6F39D /* main.m */; }; - DD1A9EA8199BEA0D007BC651 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD1A9EA7199BEA0D007BC651 /* libc++.dylib */; }; - DD61240819CCF06E006845B1 /* libMapboxGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD61240619CCF06E006845B1 /* libMapboxGL.a */; }; - DD61240919CCF06E006845B1 /* MapboxGL.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DD61240719CCF06E006845B1 /* MapboxGL.bundle */; }; - DD8A790D196DC0A900FAD883 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD8A790C196DC0A900FAD883 /* libz.dylib */; }; - DD8A790F196DC0AD00FAD883 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD8A790E196DC0AD00FAD883 /* GLKit.framework */; }; - DD8A7911196DC0BB00FAD883 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD8A7910196DC0BB00FAD883 /* CoreLocation.framework */; }; - DD96917919F1C08400729E7D /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD96917819F1C08400729E7D /* libsqlite3.dylib */; }; - DD96918119F1C09200729E7D /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD96918019F1C09200729E7D /* SystemConfiguration.framework */; }; - DDBD0154196DC3D70033959E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBD0153196DC3D70033959E /* XCTest.framework */; }; - DDBD0155196DC3D70033959E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043326196DB9BC00E6F39D /* Foundation.framework */; }; - DDBD0156196DC3D70033959E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD04332A196DB9BC00E6F39D /* UIKit.framework */; }; + DD0580E81ACB628200B112C9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0580E71ACB628200B112C9 /* IOKit.framework */; }; + DD0581041ACB661200B112C9 /* Headers in Resources */ = {isa = PBXBuildFile; fileRef = DD0581031ACB661200B112C9 /* Headers */; }; + DD0581061ACB661C00B112C9 /* MapboxGL.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DD0581051ACB661C00B112C9 /* MapboxGL.bundle */; }; + DD0581081ACB663200B112C9 /* libMapboxGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0581071ACB663200B112C9 /* libMapboxGL.a */; }; + DD41CE091ACB5DBC00FA7979 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE081ACB5DBC00FA7979 /* CoreTelephony.framework */; }; + DD41CE0B1ACB5DC400FA7979 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE0A1ACB5DC400FA7979 /* SystemConfiguration.framework */; }; + DD41CE0D1ACB5DCB00FA7979 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE0C1ACB5DCB00FA7979 /* libc++.dylib */; }; + DD41CE0F1ACB5DD000FA7979 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE0E1ACB5DD000FA7979 /* libsqlite3.dylib */; }; + DD41CE111ACB5DD500FA7979 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE101ACB5DD500FA7979 /* libz.dylib */; }; + DD41CE131ACB5DDA00FA7979 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE121ACB5DDA00FA7979 /* MobileCoreServices.framework */; }; + DD41CE151ACB5DE000FA7979 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE141ACB5DE000FA7979 /* ImageIO.framework */; }; + DD41CE171ACB5DE700FA7979 /* GLKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD41CE161ACB5DE700FA7979 /* GLKit.framework */; }; DDBD016C196DC4740033959E /* MapViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DDBD0168196DC4740033959E /* MapViewTests.m */; }; DDBD016D196DC4740033959E /* KIFTestActor+MapboxGL.m in Sources */ = {isa = PBXBuildFile; fileRef = DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */; }; DDBD016E196DC4A10033959E /* libKIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBD0144196DC3AE0033959E /* libKIF.a */; }; - DDBD016F196DC4A90033959E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD043328196DB9BC00E6F39D /* CoreGraphics.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -77,35 +74,30 @@ /* Begin PBXFileReference section */ DD043323196DB9BC00E6F39D /* Mapbox GL Tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL Tests.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - DD043326196DB9BC00E6F39D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - DD043328196DB9BC00E6F39D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - DD04332A196DB9BC00E6F39D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; DD04335F196DBBD500E6F39D /* MGLTAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLTAppDelegate.m; sourceTree = SOURCE_ROOT; }; DD043360196DBBD500E6F39D /* MGLTViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLTViewController.m; sourceTree = SOURCE_ROOT; }; DD043361196DBBD500E6F39D /* MGLTViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTViewController.h; sourceTree = SOURCE_ROOT; }; DD043362196DBBD500E6F39D /* MGLTAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTAppDelegate.h; sourceTree = SOURCE_ROOT; }; DD043365196DBBE000E6F39D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = SOURCE_ROOT; }; DD043367196DBCC200E6F39D /* App-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "App-Info.plist"; sourceTree = SOURCE_ROOT; }; - DD1A9EA7199BEA0D007BC651 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; }; - DD61240019CCF06E006845B1 /* MGLMapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLMapView.h; path = ../dist/static/Headers/MGLMapView.h; sourceTree = SOURCE_ROOT; }; - DD61240119CCF06E006845B1 /* MGLStyleFunctionValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLStyleFunctionValue.h; path = ../dist/static/Headers/MGLStyleFunctionValue.h; sourceTree = SOURCE_ROOT; }; - DD61240219CCF06E006845B1 /* MGLTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLTypes.h; path = ../dist/static/Headers/MGLTypes.h; sourceTree = SOURCE_ROOT; }; - DD61240319CCF06E006845B1 /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+MGLAdditions.h"; path = "../dist/static/Headers/NSArray+MGLAdditions.h"; sourceTree = SOURCE_ROOT; }; - DD61240419CCF06E006845B1 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+MGLAdditions.h"; path = "../dist/static/Headers/NSDictionary+MGLAdditions.h"; sourceTree = SOURCE_ROOT; }; - DD61240519CCF06E006845B1 /* UIColor+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+MGLAdditions.h"; path = "../dist/static/Headers/UIColor+MGLAdditions.h"; sourceTree = SOURCE_ROOT; }; - DD61240619CCF06E006845B1 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../dist/static/libMapboxGL.a; sourceTree = SOURCE_ROOT; }; - DD61240719CCF06E006845B1 /* MapboxGL.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = MapboxGL.bundle; path = ../dist/static/MapboxGL.bundle; sourceTree = SOURCE_ROOT; }; - DD8A790C196DC0A900FAD883 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; - DD8A790E196DC0AD00FAD883 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; }; - DD8A7910196DC0BB00FAD883 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; - DD96917819F1C08400729E7D /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; - DD96918019F1C09200729E7D /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + DD0580E71ACB628200B112C9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; }; + DD0580EF1ACB62BE00B112C9 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + DD0581031ACB661200B112C9 /* Headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Headers; path = ../../build/ios/pkg/static/Headers; sourceTree = SOURCE_ROOT; }; + DD0581051ACB661C00B112C9 /* MapboxGL.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = MapboxGL.bundle; path = ../../build/ios/pkg/static/MapboxGL.bundle; sourceTree = SOURCE_ROOT; }; + DD0581071ACB663200B112C9 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../../build/ios/pkg/static/libMapboxGL.a; sourceTree = SOURCE_ROOT; }; + DD41CE061ACB5DB300FA7979 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../../build/ios/pkg/static/libMapboxGL.a; sourceTree = ""; }; + DD41CE081ACB5DBC00FA7979 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + DD41CE0A1ACB5DC400FA7979 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + DD41CE0C1ACB5DCB00FA7979 /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; }; + DD41CE0E1ACB5DD000FA7979 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; + DD41CE101ACB5DD500FA7979 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + DD41CE121ACB5DDA00FA7979 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + DD41CE141ACB5DE000FA7979 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; + DD41CE161ACB5DE700FA7979 /* GLKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GLKit.framework; path = System/Library/Frameworks/GLKit.framework; sourceTree = SDKROOT; }; DDBD013A196DC3AE0033959E /* KIF.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = KIF.xcodeproj; path = KIF/KIF.xcodeproj; sourceTree = SOURCE_ROOT; }; DDBD0152196DC3D70033959E /* Test Bundle.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Test Bundle.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - DDBD0153196DC3D70033959E /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; DDBD0165196DC4560033959E /* Bundle-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Bundle-Info.plist"; sourceTree = SOURCE_ROOT; }; DDBD0168196DC4740033959E /* MapViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewTests.m; sourceTree = SOURCE_ROOT; }; - DDBD0169196DC4740033959E /* MapViewTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapViewTests.h; sourceTree = SOURCE_ROOT; }; DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KIFTestActor+MapboxGL.m"; sourceTree = SOURCE_ROOT; }; DDBD016B196DC4740033959E /* KIFTestActor+MapboxGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KIFTestActor+MapboxGL.h"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -115,16 +107,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DD043329196DB9BC00E6F39D /* CoreGraphics.framework in Frameworks */, - DD8A7911196DC0BB00FAD883 /* CoreLocation.framework in Frameworks */, - DD043327196DB9BC00E6F39D /* Foundation.framework in Frameworks */, - DD8A790F196DC0AD00FAD883 /* GLKit.framework in Frameworks */, - DD96918119F1C09200729E7D /* SystemConfiguration.framework in Frameworks */, - DD04332B196DB9BC00E6F39D /* UIKit.framework in Frameworks */, - DD61240819CCF06E006845B1 /* libMapboxGL.a in Frameworks */, - DD1A9EA8199BEA0D007BC651 /* libc++.dylib in Frameworks */, - DD96917919F1C08400729E7D /* libsqlite3.dylib in Frameworks */, - DD8A790D196DC0A900FAD883 /* libz.dylib in Frameworks */, + DD41CE091ACB5DBC00FA7979 /* CoreTelephony.framework in Frameworks */, + DD41CE171ACB5DE700FA7979 /* GLKit.framework in Frameworks */, + DD41CE151ACB5DE000FA7979 /* ImageIO.framework in Frameworks */, + DD41CE131ACB5DDA00FA7979 /* MobileCoreServices.framework in Frameworks */, + DD41CE0B1ACB5DC400FA7979 /* SystemConfiguration.framework in Frameworks */, + DD0581081ACB663200B112C9 /* libMapboxGL.a in Frameworks */, + DD41CE0D1ACB5DCB00FA7979 /* libc++.dylib in Frameworks */, + DD41CE0F1ACB5DD000FA7979 /* libsqlite3.dylib in Frameworks */, + DD41CE111ACB5DD500FA7979 /* libz.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -132,10 +123,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DDBD016F196DC4A90033959E /* CoreGraphics.framework in Frameworks */, - DDBD0155196DC3D70033959E /* Foundation.framework in Frameworks */, - DDBD0156196DC3D70033959E /* UIKit.framework in Frameworks */, - DDBD0154196DC3D70033959E /* XCTest.framework in Frameworks */, + DD0580E81ACB628200B112C9 /* IOKit.framework in Frameworks */, DDBD016E196DC4A10033959E /* libKIF.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -165,16 +153,17 @@ DD043325196DB9BC00E6F39D /* Frameworks */ = { isa = PBXGroup; children = ( - DD96918019F1C09200729E7D /* SystemConfiguration.framework */, - DD96917819F1C08400729E7D /* libsqlite3.dylib */, - DD043328196DB9BC00E6F39D /* CoreGraphics.framework */, - DD8A7910196DC0BB00FAD883 /* CoreLocation.framework */, - DD043326196DB9BC00E6F39D /* Foundation.framework */, - DD8A790E196DC0AD00FAD883 /* GLKit.framework */, - DD04332A196DB9BC00E6F39D /* UIKit.framework */, - DDBD0153196DC3D70033959E /* XCTest.framework */, - DD1A9EA7199BEA0D007BC651 /* libc++.dylib */, - DD8A790C196DC0A900FAD883 /* libz.dylib */, + DD0580EF1ACB62BE00B112C9 /* CoreGraphics.framework */, + DD41CE081ACB5DBC00FA7979 /* CoreTelephony.framework */, + DD41CE161ACB5DE700FA7979 /* GLKit.framework */, + DD0580E71ACB628200B112C9 /* IOKit.framework */, + DD41CE141ACB5DE000FA7979 /* ImageIO.framework */, + DD41CE121ACB5DDA00FA7979 /* MobileCoreServices.framework */, + DD41CE0A1ACB5DC400FA7979 /* SystemConfiguration.framework */, + DD41CE061ACB5DB300FA7979 /* libMapboxGL.a */, + DD41CE0C1ACB5DCB00FA7979 /* libc++.dylib */, + DD41CE0E1ACB5DD000FA7979 /* libsqlite3.dylib */, + DD41CE101ACB5DD500FA7979 /* libz.dylib */, ); name = Frameworks; sourceTree = ""; @@ -186,7 +175,7 @@ DD04335F196DBBD500E6F39D /* MGLTAppDelegate.m */, DD043361196DBBD500E6F39D /* MGLTViewController.h */, DD043360196DBBD500E6F39D /* MGLTViewController.m */, - DD8A77AD196DBFDA00FAD883 /* GL Library */, + DDAE739B1ACB557500E1A793 /* GL Library */, DD04332D196DB9BC00E6F39D /* Supporting Files */, ); name = App; @@ -202,26 +191,12 @@ name = "Supporting Files"; sourceTree = ""; }; - DD6123FF19CCF06E006845B1 /* Headers */ = { + DDAE739B1ACB557500E1A793 /* GL Library */ = { isa = PBXGroup; children = ( - DD61240019CCF06E006845B1 /* MGLMapView.h */, - DD61240119CCF06E006845B1 /* MGLStyleFunctionValue.h */, - DD61240219CCF06E006845B1 /* MGLTypes.h */, - DD61240319CCF06E006845B1 /* NSArray+MGLAdditions.h */, - DD61240419CCF06E006845B1 /* NSDictionary+MGLAdditions.h */, - DD61240519CCF06E006845B1 /* UIColor+MGLAdditions.h */, - ); - name = Headers; - path = ../../dist/static/Headers; - sourceTree = SOURCE_ROOT; - }; - DD8A77AD196DBFDA00FAD883 /* GL Library */ = { - isa = PBXGroup; - children = ( - DD6123FF19CCF06E006845B1 /* Headers */, - DD61240619CCF06E006845B1 /* libMapboxGL.a */, - DD61240719CCF06E006845B1 /* MapboxGL.bundle */, + DD0581031ACB661200B112C9 /* Headers */, + DD0581071ACB663200B112C9 /* libMapboxGL.a */, + DD0581051ACB661C00B112C9 /* MapboxGL.bundle */, ); name = "GL Library"; sourceTree = ""; @@ -231,7 +206,6 @@ children = ( DDBD016B196DC4740033959E /* KIFTestActor+MapboxGL.h */, DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */, - DDBD0169196DC4740033959E /* MapViewTests.h */, DDBD0168196DC4740033959E /* MapViewTests.m */, DDBD0167196DC46B0033959E /* Supporting Files */, DDBD014D196DC3B00033959E /* KIF */, @@ -313,7 +287,7 @@ isa = PBXProject; attributes = { CLASSPREFIX = MGLT; - LastUpgradeCheck = 0510; + LastUpgradeCheck = 0620; ORGANIZATIONNAME = Mapbox; TargetAttributes = { DDBD0151196DC3D70033959E = { @@ -389,7 +363,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - DD61240919CCF06E006845B1 /* MapboxGL.bundle in Resources */, + DD0581041ACB661200B112C9 /* Headers in Resources */, + DD0581061ACB661C00B112C9 /* MapboxGL.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -407,9 +382,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DD043364196DBBD500E6F39D /* MGLTViewController.m in Sources */, DD043366196DBBE000E6F39D /* main.m in Sources */, DD043363196DBBD500E6F39D /* MGLTAppDelegate.m in Sources */, + DD043364196DBBD500E6F39D /* MGLTViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -508,26 +483,20 @@ DD043359196DB9BC00E6F39D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv7, - armv7s, - arm64, - i386, - x86_64, - ); ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - ../dist/static/Headers, + "../../build/ios/pkg/static/**", ); INFOPLIST_FILE = "$(SRCROOT)/App-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - ../dist/static, + ../../build/ios/pkg/static, ); + OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; @@ -537,26 +506,20 @@ DD04335A196DB9BC00E6F39D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv7, - armv7s, - arm64, - i386, - x86_64, - ); ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - ../dist/static/Headers, + "../../build/ios/pkg/static/**", ); INFOPLIST_FILE = "$(SRCROOT)/App-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", - ../dist/static, + ../../build/ios/pkg/static, ); + OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; WRAPPER_EXTENSION = app; @@ -571,6 +534,7 @@ "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks", ); GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -580,7 +544,7 @@ HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - ../dist/static/Headers, + "../../build/ios/pkg/static/**", ); INFOPLIST_FILE = "Bundle-Info.plist"; OTHER_LDFLAGS = ( @@ -603,12 +567,13 @@ "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(DEVELOPER_DIR)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks", ); GCC_PREPROCESSOR_DEFINITIONS = "KIF_XCTEST=1"; HEADER_SEARCH_PATHS = ( "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - ../dist/static/Headers, + "../../build/ios/pkg/static/**", ); INFOPLIST_FILE = "Bundle-Info.plist"; OTHER_LDFLAGS = ( diff --git a/test/ios/ios-tests.xcodeproj/project.xcworkspace/xcshareddata/ios-tests.xccheckout b/test/ios/ios-tests.xcodeproj/project.xcworkspace/xcshareddata/ios-tests.xccheckout index 8f3ca408b..e2f98de8f 100644 --- a/test/ios/ios-tests.xcodeproj/project.xcworkspace/xcshareddata/ios-tests.xccheckout +++ b/test/ios/ios-tests.xcodeproj/project.xcworkspace/xcshareddata/ios-tests.xccheckout @@ -14,26 +14,22 @@ https://github.com/mapbox/KIF.git 7E68CB584078A487C0535CC191D3B7551EEE2095 github.com:mapbox/mapbox-gl-native.git - FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF - github.com:mapbox/mapbox-gl-cocoa.git IDESourceControlProjectPath - test/ios-tests.xcodeproj + test/ios/ios-tests.xcodeproj IDESourceControlProjectRelativeInstallPathDictionary 10265E242415D473A6A613214DB7AC3EE3D43F93 - ../../..test/KIF/ + ../../../..test/ios/KIF 7E68CB584078A487C0535CC191D3B7551EEE2095 - ../../../../.. - FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF - ../../.. + ../../../.. IDESourceControlProjectURL - github.com:mapbox/mapbox-gl-cocoa.git + github.com:mapbox/mapbox-gl-native.git IDESourceControlProjectVersion 111 IDESourceControlProjectWCCIdentifier - FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF + 7E68CB584078A487C0535CC191D3B7551EEE2095 IDESourceControlProjectWCConfigurations @@ -42,7 +38,7 @@ IDESourceControlWCCIdentifierKey 7E68CB584078A487C0535CC191D3B7551EEE2095 IDESourceControlWCCName - .. + gl-native IDESourceControlRepositoryExtensionIdentifierKey @@ -52,14 +48,6 @@ IDESourceControlWCCName KIF - - IDESourceControlRepositoryExtensionIdentifierKey - public.vcs.git - IDESourceControlWCCIdentifierKey - FC967DACF69B3B67E6F2E9FBE56B64B73B118AFF - IDESourceControlWCCName - mapbox-gl-cocoa - diff --git a/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme b/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme index f3c2bd7ff..911f949fa 100644 --- a/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme +++ b/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -72,7 +77,8 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" allowLocationSimulation = "YES"> - + - + Date: Tue, 21 Apr 2015 11:57:08 +0200 Subject: [PATCH 13/27] merge build targets so we only have one build file per platform previously, we used multiple different projects for various targets (app, test, render) that overwrote each other, so it was impossible to have one project to build them all, one project to compile them, one project to run them all and in the darkness bind them --- Makefile | 119 +++++++----------- bin/{render.gyp => render.gypi} | 0 gyp/project.gyp | 19 +++ linux/{mapboxgl-app.gyp => mapboxgl-app.gypi} | 0 .../{mapboxgl-app.gyp => mapboxgl-app.gypi} | 2 +- scripts/package_ios.sh | 2 +- test/{test.gyp => test.gypi} | 2 +- 7 files changed, 65 insertions(+), 79 deletions(-) rename bin/{render.gyp => render.gypi} (100%) create mode 100644 gyp/project.gyp rename linux/{mapboxgl-app.gyp => mapboxgl-app.gypi} (100%) rename macosx/{mapboxgl-app.gyp => mapboxgl-app.gypi} (96%) rename test/{test.gyp => test.gypi} (98%) diff --git a/Makefile b/Makefile index d0cf4407c..11eb5e530 100644 --- a/Makefile +++ b/Makefile @@ -4,11 +4,16 @@ PREFIX ?= /usr/local ANDROID_ABI ?= arm-v7 ifeq ($(shell uname -s), Darwin) -HOST ?= osx -HEADLESS ?= cgl +HOST = osx +HEADLESS = cgl JOBS ?= $(shell sysctl -n hw.ncpu) endif -HOST ?= linux + +ifeq ($(shell uname -s), Linux) +HOST = linux +JOBS ?= $(shell sysctl -n hw.ncpu) +endif + JOBS ?= 1 all: mbgl @@ -32,49 +37,42 @@ SMCalloutView: KIF: git submodule update --init test/ios/KIF + +#### Build files ############################################################### + +.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 + +.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 + + #### Library builds ############################################################ -.PRECIOUS: Makefile/mbgl -Makefile/mbgl: config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make - -mbgl: Makefile/mbgl +mbgl: Makefile/project $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) everything -standalone: Makefile/mbgl +standalone: Makefile/project LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) standalone -install: Makefile/mbgl +install: Makefile/project LINK=`pwd`/gyp/link.py $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) install -.PRECIOUS: Xcode/mbgl -Xcode/mbgl: config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp mbgl.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f xcode ##### Test builds ############################################################## -.PRECIOUS: Makefile/test -Makefile/test: test/test.gyp config/$(HOST).gypi styles/styles SMCalloutView - deps/run_gyp test/test.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make - .PHONY: test -test: Makefile/test +test: Makefile/project $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) test test-%: test ./scripts/run_tests.sh "build/$(HOST)/$(BUILDTYPE)/test" --gtest_filter=$* - -.PRECIOUS: Xcode/test -Xcode/test: test/test.gyp config/osx.gypi styles/styles SMCalloutView - deps/run_gyp test/test.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode - -.PHONY: lproj lbuild run-xlinux -xtest-proj: Xcode/test - open ./build/osx/test/test.xcodeproj - -xtest: Xcode/test - xcodebuild -project ./build/osx/test/test.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) +.PHONY: xtest +xtest: Xcode/project + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target test -jobs $(JOBS) xtest-%: xtest ./scripts/run_tests.sh "build/osx/Build/Products/$(BUILDTYPE)/test" --gtest_filter=$* @@ -82,31 +80,22 @@ xtest-%: xtest #### Mac OS X application builds ############################################### -.PRECIOUS: Makefile/osx -Makefile/osx: macosx/mapboxgl-app.gyp config/osx.gypi styles/styles - deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f make - .PHONY: osx run-osx -osx: Makefile/osx +osx: Makefile/project $(MAKE) -C build/osx BUILDTYPE=$(BUILDTYPE) osxapp run-osx: osx "build/osx/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" - -.PRECIOUS: Xcode/osx -Xcode/osx: macosx/mapboxgl-app.gyp config/osx.gypi styles/styles - deps/run_gyp macosx/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode - .PHONY: xosx-proj xosx run-xosx -xosx-proj: Xcode/osx - open ./build/osx/macosx/mapboxgl-app.xcodeproj +xosx-proj: Xcode/project + open ./build/osx/gyp/project.xcodeproj -xosx: Xcode/osx - xcodebuild -project ./build/osx/macosx/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) +xosx: Xcode/project + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target osxapp -jobs $(JOBS) run-xosx: xosx - "build/osx/Build/Products/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" + "gyp/build/$(BUILDTYPE)/Mapbox GL.app/Contents/MacOS/Mapbox GL" # Legacy name xproj: xosx-proj @@ -141,34 +130,19 @@ iproj: ios-proj #### Linux application builds ################################################## -.PRECIOUS: Makefile/linux -Makefile/linux: linux/mapboxgl-app.gyp config/$(HOST).gypi styles/styles - deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_$(HOST)) $(LIBS_linux) --generator-output=./build/$(HOST) -f make - .PHONY: linux run-linux -linux: Makefile/linux +linux: Makefile/project $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) linuxapp run-linux: linux (cd build/$(HOST)/$(BUILDTYPE) && ./mapbox-gl) - -.PRECIOUS: Xcode/linux -Xcode/linux: linux/mapboxgl-app.gyp config/osx.gypi styles/styles - deps/run_gyp linux/mapboxgl-app.gyp $(CONFIG_osx) $(LIBS_linux) --generator-output=./build/osx -f xcode - -.PHONY: lproj lbuild run-xlinux -xlinux-proj: Xcode/linux - open ./build/osx/linux/mapboxgl-app.xcodeproj - -xlinux: Xcode/linux - xcodebuild -project ./build/osx/linux/mapboxgl-app.xcodeproj -configuration $(BUILDTYPE) -target linuxapp +.PHONY: xlinux run-xlinux +xlinux: Xcode/project + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target linuxapp -jobs $(JOBS) run-xlinux: xlinux - "build/osx/Build/Products/$(BUILDTYPE)/mapbox-gl" - -# Legacy name -lproj: xlinux-proj + "gyp/build/$(BUILDTYPE)/mapbox-gl" #### Android libaries ######################################################### @@ -200,22 +174,15 @@ android-deploy: $(ANDROID_ABIS) android-project: android-lib + ##### Render builds ############################################################ -.PRECIOUS: Makefile/render -Makefile/render: bin/render.gyp config/$(HOST).gypi - deps/run_gyp bin/render.gyp $(CONFIG_$(HOST)) $(LIBS_$(HOST)) --generator-output=./build/$(HOST) -f make - -render: Makefile/render +render: Makefile/project $(MAKE) -C build/$(HOST) BUILDTYPE=$(BUILDTYPE) mbgl-render -.PRECIOUS: Xcode/render -Xcode/render: bin/render.gyp config/osx.gypi styles/styles - deps/run_gyp bin/render.gyp $(CONFIG_osx) $(LIBS_osx) --generator-output=./build/osx -f xcode - -.PHONY: xrender-proj -xrender-proj: Xcode/render - open ./build/osx/bin/render.xcodeproj +.PHONY: xrender run-xrender +xrender: Xcode/project + xcodebuild -project ./build/osx/gyp/project.xcodeproj -configuration $(BUILDTYPE) -target mbgl-render -jobs $(JOBS) ##### Maintenace operations #################################################### diff --git a/bin/render.gyp b/bin/render.gypi similarity index 100% rename from bin/render.gyp rename to bin/render.gypi diff --git a/gyp/project.gyp b/gyp/project.gyp new file mode 100644 index 000000000..9f53eef51 --- /dev/null +++ b/gyp/project.gyp @@ -0,0 +1,19 @@ +{ + '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/linux/mapboxgl-app.gyp b/linux/mapboxgl-app.gypi similarity index 100% rename from linux/mapboxgl-app.gyp rename to linux/mapboxgl-app.gypi diff --git a/macosx/mapboxgl-app.gyp b/macosx/mapboxgl-app.gypi similarity index 96% rename from macosx/mapboxgl-app.gyp rename to macosx/mapboxgl-app.gypi index 9817f9d97..381795404 100644 --- a/macosx/mapboxgl-app.gyp +++ b/macosx/mapboxgl-app.gypi @@ -53,7 +53,7 @@ 'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ], 'OTHER_LDFLAGS': [ '<@(ldflags)' ], 'SDKROOT': 'macosx', - 'INFOPLIST_FILE': 'Info.plist', + 'INFOPLIST_FILE': '../macosx/Info.plist', 'CLANG_ENABLE_OBJC_ARC': 'YES' }, } diff --git a/scripts/package_ios.sh b/scripts/package_ios.sh index a651d2734..07e568faa 100755 --- a/scripts/package_ios.sh +++ b/scripts/package_ios.sh @@ -31,7 +31,7 @@ step "Creating build files..." export MASON_PLATFORM=ios export BUILDTYPE=${BUILDTYPE:-Release} export HOST=ios -make Xcode/mbgl +make Xcode/ios step "Building iOS device targets..." xcodebuild -sdk iphoneos${IOS_SDK_VERSION} \ diff --git a/test/test.gyp b/test/test.gypi similarity index 98% rename from test/test.gyp rename to test/test.gypi index 2e89db58b..40cd3d506 100644 --- a/test/test.gyp +++ b/test/test.gypi @@ -9,7 +9,7 @@ 'actions': [ { 'action_name': 'Symlink Fixture Directory', - 'inputs': [' Date: Fri, 24 Apr 2015 13:06:54 -0700 Subject: [PATCH 14/27] Made user dot accessible Added an accessibility label to the user dot. --- platform/ios/MGLUserLocationAnnotationView.m | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/ios/MGLUserLocationAnnotationView.m b/platform/ios/MGLUserLocationAnnotationView.m index 779382b5e..c130582d6 100644 --- a/platform/ios/MGLUserLocationAnnotationView.m +++ b/platform/ios/MGLUserLocationAnnotationView.m @@ -30,6 +30,7 @@ const CGFloat MGLTrackingDotRingWidth = 24.0; self.annotation.mapView = mapView; _mapView = mapView; [self setupLayers]; + self.accessibilityLabel = @"User location"; } return self; } From 1dc2cbc280292c76eaca21fde9dddfbd30060fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 24 Apr 2015 13:30:50 -0700 Subject: [PATCH 15/27] Test inset MGLMapView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verify that the ornaments hug the `MGLMapView` when it’s smaller than the view controller’s root view. --- test/ios/KIFTestActor+MapboxGL.h | 4 ++-- test/ios/KIFTestActor+MapboxGL.m | 4 ++-- test/ios/MGLTViewController.h | 2 ++ test/ios/MGLTViewController.m | 16 ++++++++++++---- test/ios/MapViewTests.m | 23 +++++++++++++++++++++++ 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/test/ios/KIFTestActor+MapboxGL.h b/test/ios/KIFTestActor+MapboxGL.h index df83b2377..d16e34848 100644 --- a/test/ios/KIFTestActor+MapboxGL.h +++ b/test/ios/KIFTestActor+MapboxGL.h @@ -1,12 +1,12 @@ #import #import -@class MGLMapView; +@class MGLTViewController, MGLMapView; @interface KIFTestActor (MapboxGL) @property (nonatomic, readonly) UIWindow *window; -@property (nonatomic, readonly) UIViewController *viewController; +@property (nonatomic, readonly) MGLTViewController *viewController; @property (nonatomic, readonly) MGLMapView *mapView; @property (nonatomic, readonly) UIView *compass; diff --git a/test/ios/KIFTestActor+MapboxGL.m b/test/ios/KIFTestActor+MapboxGL.m index ef40c1bed..330adfdc2 100644 --- a/test/ios/KIFTestActor+MapboxGL.m +++ b/test/ios/KIFTestActor+MapboxGL.m @@ -10,8 +10,8 @@ return [[UIApplication sharedApplication] statusBarWindow]; } -- (UIViewController *)viewController { - return (UIViewController *)[[tester.mapView nextResponder] nextResponder]; +- (MGLTViewController *)viewController { + return (MGLTViewController *)[[tester.mapView nextResponder] nextResponder]; } - (MGLMapView *)mapView { diff --git a/test/ios/MGLTViewController.h b/test/ios/MGLTViewController.h index 39df59bb5..f8d561899 100644 --- a/test/ios/MGLTViewController.h +++ b/test/ios/MGLTViewController.h @@ -2,4 +2,6 @@ @interface MGLTViewController : UIViewController +- (void)insetMapView; + @end diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m index e839c4504..2cb2b939c 100644 --- a/test/ios/MGLTViewController.m +++ b/test/ios/MGLTViewController.m @@ -2,17 +2,25 @@ #import "MapboxGL.h" @implementation MGLTViewController +{ + MGLMapView *_mapView; +} - (void)viewDidLoad { [super viewDidLoad]; - MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds + _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:@"pk.eyJ1IjoianVzdGluIiwiYSI6Ik9RX3RRQzAifQ.dmOg_BAp1ywuDZMM7YsXRg"]; - mapView.viewControllerForLayoutGuides = self; - mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _mapView.viewControllerForLayoutGuides = self; + _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self.view addSubview:mapView]; + [self.view addSubview:_mapView]; +} + +- (void)insetMapView +{ + _mapView.frame = CGRectInset(_mapView.frame, 50, 50); } @end diff --git a/test/ios/MapViewTests.m b/test/ios/MapViewTests.m index deed521b7..2d87b43c1 100644 --- a/test/ios/MapViewTests.m +++ b/test/ios/MapViewTests.m @@ -4,6 +4,7 @@ #import "KIFTestActor+MapboxGL.h" #import "MapboxGL.h" +#import "MGLTViewController.h" @interface MapViewTests : KIFTestCase @@ -297,6 +298,28 @@ @"rotated device should not have attribution button under toolbar"); } +- (void)testInsetMapView { + [tester.viewController insetMapView]; + [tester waitForAnimationsToFinish]; + + UIView *logoBug = (UIView *)[tester waitForViewWithAccessibilityLabel:@"Mapbox logo"]; + UIView *attributionButton = (UIView *)[tester waitForViewWithAccessibilityLabel:@"Attribution info"]; + + CGRect mapViewFrame = [tester.mapView.superview convertRect:tester.mapView.frame toView:nil]; + + CGRect logoBugFrame = [logoBug.superview convertRect:logoBug.frame toView:nil]; + XCTAssertTrue(CGRectIntersectsRect(logoBugFrame, mapViewFrame), + @"logo bug should lie inside shrunken map view"); + + CGRect attributionButtonFrame = [attributionButton.superview convertRect:attributionButton.frame toView:nil]; + XCTAssertTrue(CGRectIntersectsRect(attributionButtonFrame, mapViewFrame), + @"attribution button should lie inside shrunken map view"); + + CGRect compassFrame = [tester.compass.superview convertRect:tester.compass.frame toView:nil]; + XCTAssertTrue(CGRectIntersectsRect(compassFrame, mapViewFrame), + @"compass should lie inside shrunken map view"); +} + - (void)testDelegateRegionWillChange { __block NSUInteger unanimatedCount; __block NSUInteger animatedCount; From f9c544a9ea0f9a321616fbc7147f67b5c90b7832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguy=E1=BB=85n?= Date: Fri, 24 Apr 2015 14:27:25 -0700 Subject: [PATCH 16/27] Reset map view frame on every test To counteract the call to `-insetMapView` in `-testInsetMapView`. --- test/ios/MGLTViewController.h | 1 + test/ios/MGLTViewController.m | 5 +++++ test/ios/MapViewTests.m | 1 + 3 files changed, 7 insertions(+) diff --git a/test/ios/MGLTViewController.h b/test/ios/MGLTViewController.h index f8d561899..0be0e1ff2 100644 --- a/test/ios/MGLTViewController.h +++ b/test/ios/MGLTViewController.h @@ -3,5 +3,6 @@ @interface MGLTViewController : UIViewController - (void)insetMapView; +- (void)resetMapView; @end diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m index 2cb2b939c..e8b500b43 100644 --- a/test/ios/MGLTViewController.m +++ b/test/ios/MGLTViewController.m @@ -23,4 +23,9 @@ _mapView.frame = CGRectInset(_mapView.frame, 50, 50); } +- (void)resetMapView +{ + _mapView.frame = self.view.bounds; +} + @end diff --git a/test/ios/MapViewTests.m b/test/ios/MapViewTests.m index 2d87b43c1..fff52adc0 100644 --- a/test/ios/MapViewTests.m +++ b/test/ios/MapViewTests.m @@ -14,6 +14,7 @@ - (void)beforeEach { [system simulateDeviceRotationToOrientation:UIDeviceOrientationPortrait]; + [tester.viewController resetMapView]; tester.mapView.centerCoordinate = CLLocationCoordinate2DMake(38.913175, -77.032458); tester.mapView.zoomLevel = 14; From 17010bfd73f2c8e94318fece0b216ec4f91b6f91 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 24 Apr 2015 14:27:50 -0700 Subject: [PATCH 17/27] make text-max-size not affect rendering size This way it matches -js. The real fix will eventually be https://github.com/mapbox/mapbox-gl-style-spec/issues/255 --- src/mbgl/renderer/painter_symbol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index 2785e8bae..79ad50e75 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -35,7 +35,7 @@ void Painter::renderSDF(SymbolBucket &bucket, } // If layerStyle.size > bucket.info.fontSize then labels may collide - float fontSize = std::fmin(styleProperties.size, bucketProperties.max_size); + float fontSize = styleProperties.size; float fontScale = fontSize / sdfFontSize; matrix::scale(exMatrix, exMatrix, fontScale, fontScale, 1.0f); From 65306490dd074a268d4041a98302f54eaf82242f Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 24 Apr 2015 14:54:04 -0700 Subject: [PATCH 18/27] icon-rotate is not a paint property issue #1173 --- src/mbgl/style/property_fallback.cpp | 1 - src/mbgl/style/style_layer.cpp | 1 - src/mbgl/style/style_parser.cpp | 1 - src/mbgl/style/style_properties.hpp | 1 - 4 files changed, 4 deletions(-) diff --git a/src/mbgl/style/property_fallback.cpp b/src/mbgl/style/property_fallback.cpp index dce226cde..655a75df9 100644 --- a/src/mbgl/style/property_fallback.cpp +++ b/src/mbgl/style/property_fallback.cpp @@ -22,7 +22,6 @@ const std::map PropertyFallbackValue::properties = { { PropertyKey::LineBlur, defaultStyleProperties().blur }, { PropertyKey::IconOpacity, defaultStyleProperties().icon.opacity }, - { PropertyKey::IconRotate, defaultStyleProperties().icon.rotate }, { PropertyKey::IconSize, defaultStyleProperties().icon.size }, { PropertyKey::IconColor, defaultStyleProperties().icon.color }, { PropertyKey::IconHaloColor, defaultStyleProperties().icon.halo_color }, diff --git a/src/mbgl/style/style_layer.cpp b/src/mbgl/style/style_layer.cpp index 542c4eb8a..e9c301d8c 100644 --- a/src/mbgl/style/style_layer.cpp +++ b/src/mbgl/style/style_layer.cpp @@ -194,7 +194,6 @@ void StyleLayer::applyStyleProperties(const float z, const Tim properties.set(); SymbolProperties &symbol = properties.get(); applyTransitionedStyleProperty(PropertyKey::IconOpacity, symbol.icon.opacity, z, now, zoomHistory); - applyTransitionedStyleProperty(PropertyKey::IconRotate, symbol.icon.rotate, z, now, zoomHistory); applyTransitionedStyleProperty(PropertyKey::IconSize, symbol.icon.size, z, now, zoomHistory); applyTransitionedStyleProperty(PropertyKey::IconColor, symbol.icon.color, z, now, zoomHistory); applyTransitionedStyleProperty(PropertyKey::IconHaloColor, symbol.icon.halo_color, z, now, zoomHistory); diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp index afed2eeee..dc91c250c 100644 --- a/src/mbgl/style/style_parser.cpp +++ b/src/mbgl/style/style_parser.cpp @@ -811,7 +811,6 @@ void StyleParser::parsePaint(JSVal value, ClassProperties &klass) { parseOptionalProperty>("icon-opacity", Key::IconOpacity, klass, value); parseOptionalProperty("icon-opacity-transition", Key::IconOpacity, klass, value); - parseOptionalProperty>("icon-rotate", Key::IconRotate, klass, value); parseOptionalProperty>("icon-size", Key::IconSize, klass, value); parseOptionalProperty("icon-size-transition", Key::IconSize, klass, value); parseOptionalProperty>("icon-color", Key::IconColor, klass, value); diff --git a/src/mbgl/style/style_properties.hpp b/src/mbgl/style/style_properties.hpp index f50722542..8e8619fb9 100644 --- a/src/mbgl/style/style_properties.hpp +++ b/src/mbgl/style/style_properties.hpp @@ -51,7 +51,6 @@ struct SymbolProperties { struct { float opacity = 1.0f; - float rotate = 0.0f; float size = 1.0f; Color color = {{ 0, 0, 0, 1 }}; Color halo_color = {{ 0, 0, 0, 0 }}; From 8aa2e2fef76eb4dfdb6e5b28a815babd27647322 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 24 Apr 2015 14:39:04 -0700 Subject: [PATCH 19/27] Don't wrap line labels. fixes #1332 https://github.com/mapbox/mapbox-gl-js/blob/98af02492183975f1f17e089a7a4118ac1ec6ddf/js/data/symbol_bucket.js#L74 --- src/mbgl/renderer/symbol_bucket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 517c8835c..4563cf647 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -183,7 +183,8 @@ void SymbolBucket::addFeatures(const GeometryTileLayer& layer, if (feature.label.length()) { shaping = fontStack->getShaping( /* string */ feature.label, - /* maxWidth: ems */ layout.text.max_width * 24, + /* maxWidth: ems */ layout.placement != PlacementType::Line ? + layout.text.max_width * 24 : 0, /* lineHeight: ems */ layout.text.line_height * 24, /* horizontalAlign */ horizontalAlign, /* verticalAlign */ verticalAlign, From ad1cc3f1ad62c75409617e22c14e2985c43092b6 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sat, 25 Apr 2015 10:25:47 -0700 Subject: [PATCH 20/27] 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 af1537ca79a0f90612154dd466845c574586195e Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 24 Apr 2015 12:54:52 -0700 Subject: [PATCH 21/27] port LineBucket::addLine from -js --- include/mbgl/util/math.hpp | 10 + include/mbgl/util/vec.hpp | 8 +- src/mbgl/renderer/line_bucket.cpp | 373 +++++++++++++++--------------- src/mbgl/renderer/line_bucket.hpp | 13 ++ src/mbgl/style/types.hpp | 4 +- 5 files changed, 221 insertions(+), 187 deletions(-) diff --git a/include/mbgl/util/math.hpp b/include/mbgl/util/math.hpp index 647fa5e67..6dea628e9 100644 --- a/include/mbgl/util/math.hpp +++ b/include/mbgl/util/math.hpp @@ -74,6 +74,11 @@ inline vec2 normal(const S1& a, const S2& b) { return { dx / c, dy / c }; } +template +inline T perp(const T& a) { + return T(-a.y, a.x); +} + template inline T dist(const S1& a, const S2& b) { T dx = b.x - a.x; @@ -93,6 +98,11 @@ inline T mag(const S& a) { return std::sqrt(a.x * a.x + a.y * a.y); } +template +inline S unit(const S& a) { + return a * (1 / mag(a)); +} + template T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); diff --git a/include/mbgl/util/vec.hpp b/include/mbgl/util/vec.hpp index 32de85275..052dffcfa 100644 --- a/include/mbgl/util/vec.hpp +++ b/include/mbgl/util/vec.hpp @@ -61,7 +61,13 @@ struct vec2 { template inline typename std::enable_if::value, vec2>::type operator-(const O &o) const { - return {x - o.x, y - o.y}; + return vec2(x - o.x, y - o.y); + } + + template + inline typename std::enable_if::value, vec2>::type + operator+(const O &o) const { + return vec2(x + o.x, y + o.y); } template diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 4e09b7464..d6159df01 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -14,6 +14,7 @@ using namespace mbgl; + LineBucket::LineBucket(LineVertexBuffer &vertexBuffer_, TriangleElementsBuffer &triangleElementsBuffer_, PointElementsBuffer &pointElementsBuffer_) @@ -29,10 +30,6 @@ LineBucket::~LineBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } -struct TriangleElement { - TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {} - uint16_t a, b, c; -}; typedef uint16_t PointElement; @@ -43,249 +40,227 @@ void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { } void LineBucket::addGeometry(const std::vector& vertices) { - // TODO: use roundLimit - // const float roundLimit = geometry.round_limit; - if (vertices.size() < 2) { + auto len = vertices.size(); + // If the line has duplicate vertices at the end, adjust length to remove them. + while (len > 2 && vertices[len - 1] == vertices[len - 2]) { + len--; + } + + if (len < 2) { // fprintf(stderr, "a line must have at least two vertices\n"); return; } - Coordinate firstVertex = vertices.front(); - Coordinate lastVertex = vertices.back(); - bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y; + const float miterLimit = layout.join == JoinType::Bevel ? 1.05f : layout.miter_limit; - if (vertices.size() == 2 && closed) { + Coordinate firstVertex = vertices.front(); + Coordinate lastVertex = vertices[len - 1]; + bool closed = firstVertex == lastVertex; + + if (len == 2 && closed) { // fprintf(stderr, "a line may not have coincident points\n"); return; } CapType beginCap = layout.cap; CapType endCap = closed ? CapType::Butt : layout.cap; - - JoinType currentJoin = JoinType::Miter; - + int8_t flip = 1; + double distance = 0; + bool startOfLine = true; Coordinate currentVertex = Coordinate::null(), prevVertex = Coordinate::null(), nextVertex = Coordinate::null(); vec2 prevNormal = vec2::null(), nextNormal = vec2::null(); - int32_t e1 = -1, e2 = -1, e3 = -1; - - int8_t flip = 1; - double distance = 0; + // the last three vertices added + e1 = e2 = e3 = -1; if (closed) { - currentVertex = vertices[vertices.size() - 2]; - nextNormal = util::normal(currentVertex, lastVertex); + currentVertex = vertices[len - 2]; + nextNormal = util::perp(util::unit(vec2(firstVertex - currentVertex))); } - int32_t start_vertex = (int32_t)vertexBuffer.index(); + int32_t startVertex = (int32_t)vertexBuffer.index(); + std::vector triangleStore; - std::vector triangle_store; - std::vector point_store; + for (size_t i = 0; i < len; ++i) { - for (size_t i = 0; i < vertices.size(); ++i) { - if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; - if (currentVertex) prevVertex = currentVertex; - - currentVertex = vertices[i]; - currentJoin = layout.join; - - if (prevVertex) distance += util::dist(currentVertex, prevVertex); - - // Find the next vertex. - if (i + 1 < vertices.size()) { + if (closed && i == len - 1) { + // if the line is closed, we treat the last vertex like the first + nextVertex = vertices[i]; + } else if (i + 1 < len) { + // just the next vertex nextVertex = vertices[i + 1]; } else { + // there is no next vertex nextVertex = Coordinate::null(); } - // If the line is closed, we treat the last vertex like the first vertex. - if (!nextVertex && closed) { - nextVertex = vertices[1]; - } + // if two consecutive vertices exist, skip the current one + if (nextVertex && vertices[i] == nextVertex) continue; - if (nextVertex) { - // if two consecutive vertices exist, skip one - if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; - } + if (nextNormal) prevNormal = nextNormal; + if (currentVertex) prevVertex = currentVertex; + + currentVertex = vertices[i]; + + // Calculate how far along the line the currentVertex is + if (prevVertex) distance += util::dist(currentVertex, prevVertex); // Calculate the normal towards the next vertex in this line. In case // there is no next vertex, pretend that the line is continuing straight, - // meaning that we are just reversing the previous normal - if (nextVertex) { - nextNormal = util::normal(currentVertex, nextVertex); - } else { - nextNormal = { -prevNormal.x, -prevNormal.y }; - } + // meaning that we are just using the previous normal. + nextNormal = nextVertex ? util::perp(util::unit(vec2(nextVertex - currentVertex))) : prevNormal; // If we still don't have a previous normal, this is the beginning of a // non-closed line, so we're doing a straight "join". - if (!prevNormal) { - prevNormal = { -nextNormal.x, -nextNormal.y }; - } + if (!prevNormal) prevNormal = nextNormal; // Determine the normal of the join extrusion. It is the angle bisector // of the segments between the previous line and the next line. - vec2 joinNormal = { - prevNormal.x + nextNormal.x, - prevNormal.y + nextNormal.y - }; - - // Cross product yields 0..1 depending on whether they are parallel - // or perpendicular. - double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x; - joinNormal.x /= joinAngularity; - joinNormal.y /= joinAngularity; - double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y)); + vec2 joinNormal = util::unit(prevNormal + nextNormal); - // Switch to miter joins if the angle is very low. - if (currentJoin != JoinType::Miter) { - if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) { + /* joinNormal prevNormal + * ↖ ↑ + * .________. prevVertex + * | + * nextNormal ← | currentVertex + * | + * nextVertex ! + * + */ + + // Calculate the length of the miter (the ratio of the miter to the width). + // Find the cosine of the angle between the next and join normals + // using dot product. The inverse of that is the miter length. + const float cosHalfAngle = joinNormal.x * nextNormal.x + joinNormal.y * nextNormal.y; + const float miterLength = 1 / cosHalfAngle; + + // The join if a middle vertex, otherwise the cap + const bool middleVertex = prevVertex && nextVertex; + JoinType currentJoin = layout.join; + CapType currentCap = nextVertex ? beginCap : endCap; + + if (middleVertex) { + if (currentJoin == JoinType::Round && miterLength < layout.round_limit) { currentJoin = JoinType::Miter; } - } - // Add offset square begin cap. - if (!prevVertex && beginCap == CapType::Square) { - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal - 0, 0, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal - 0, 1, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } - - // Add offset square end cap. - else if (!nextVertex && endCap == CapType::Square) { - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal - 0, 0, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal - 0, 1, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } - - else if (currentJoin == JoinType::Miter) { - // MITER JOIN - if (std::fabs(joinAngularity) < 0.01) { - // The two normals are almost parallel. - joinNormal.x = -nextNormal.y; - joinNormal.y = nextNormal.x; - } else if (roundness > layout.miter_limit) { - // If the miter grows too large, flip the direction to make a - // bevel join. - joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity; - joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity; + if (currentJoin == JoinType::Miter && miterLength > miterLimit) { + currentJoin = JoinType::Bevel; } - if (roundness > layout.miter_limit) { - flip = -flip; - } + if (currentJoin == JoinType::Bevel) { + // The maximum extrude length is 128 / 63 = 2 times the width of the line + // so if miterLength >= 2 we need to draw a different type of bevel where. + if (miterLength > 2) currentJoin = JoinType::FlipBevel; - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * joinNormal.x, flip * joinNormal.y, // extrude normal - 0, 0, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal - 0, 1, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { - point_store.emplace_back(e1); + // If the miterLength is really small and the line bevel wouldn't be visible, + // just draw a miter join to save a triangle. + if (miterLength < miterLimit) currentJoin = JoinType::Miter; } } - else { - // Close up the previous line - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * prevNormal.y, -flip * prevNormal.x, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + if (middleVertex && currentJoin == JoinType::Miter) { + joinNormal = joinNormal * miterLength; + addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex, triangleStore); - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + } else if (middleVertex && currentJoin == JoinType::FlipBevel) { + // miter is too big, flip the direction to make a beveled join - // Add second vertex. - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * prevNormal.y, flip * prevNormal.x, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + if (miterLength > 100) { + // Almost parallel lines + joinNormal = nextNormal; + } else { + const float bevelLength = miterLength * util::mag(prevNormal + nextNormal) / util::mag(prevNormal - nextNormal); + joinNormal = util::perp(joinNormal) * bevelLength; + } - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex, triangleStore); + flip = -flip; - prevNormal = { -nextNormal.x, -nextNormal.y }; - flip = 1; + } else if (middleVertex && currentJoin == JoinType::Bevel) { + const float dir = prevNormal.x * nextNormal.y - prevNormal.y * nextNormal.x; + const float offset = -std::sqrt(miterLength * miterLength - 1); + float offsetA; + float offsetB; + if (flip * dir > 0) { + offsetB = 0; + offsetA = offset; + } else { + offsetA = 0; + offsetB = offset; + } - // begin/end caps - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { - point_store.emplace_back(e1); + // Close previous segement with bevel + if (!startOfLine) { + addCurrentVertex(currentVertex, flip, distance, prevNormal, offsetA, offsetB, false, startVertex, triangleStore); + } + + // Start next segment + if (nextVertex) { + addCurrentVertex(currentVertex, flip, distance, nextNormal, -offsetA, -offsetB, false, startVertex, triangleStore); + } + + } else if (!middleVertex && currentCap == CapType::Butt) { + if (!startOfLine) { + // Close previous segment with a butt + addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false, startVertex, triangleStore); + } + + // Start next segment with a butt + if (nextVertex) { + addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false, startVertex, triangleStore); + } + + } else if (!middleVertex && currentCap == CapType::Square) { + if (!startOfLine) { + // Close previous segment with a square cap + addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, false, startVertex, triangleStore); + + // The segment is done. Unset vertices to disconnect segments. + e1 = e2 = -1; + flip = 1; + } + + // Start next segment + if (nextVertex) { + addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, false, startVertex, triangleStore); + } + + } else if (middleVertex ? currentJoin == JoinType::Round : currentCap == CapType::Round) { + if (!startOfLine) { + // Close previous segment with a butt + addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false, startVertex, triangleStore); + + // Add round cap or linejoin at end of segment + addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, true , startVertex, triangleStore); + + // The segment is done. Unset vertices to disconnect segments. + e1 = e2 = -1; + flip = 1; + + } else if (beginCap == CapType::Round) { + // Add round cap before first segment + addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, true, startVertex, triangleStore); } - if (currentJoin == JoinType::Round) { - if (prevVertex && nextVertex && (!closed || i > 0)) { - point_store.emplace_back(e1); - } - - // Reset the previous vertices so that we don't accidentally create - // any triangles. - e1 = -1; e2 = -1; e3 = -1; + // Start next segment with a butt + if (nextVertex) { + addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false, startVertex, triangleStore); } - - // Start the new quad. - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * nextNormal.y, flip * nextNormal.x, // extrude normal - 0, 0, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * nextNormal.y, -flip * nextNormal.x, // extrude normal - 0, 1, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; } + + startOfLine = false; } size_t end_vertex = vertexBuffer.index(); - size_t vertex_count = end_vertex - start_vertex; + size_t vertex_count = end_vertex - startVertex; // Store the triangle/line groups. { @@ -296,7 +271,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { assert(triangleGroups.back()); triangle_group_type& group = *triangleGroups.back(); - for (const auto& triangle : triangle_store) { + for (const auto& triangle : triangleStore) { triangleElementsBuffer.add( group.vertex_length + triangle.a, group.vertex_length + triangle.b, @@ -305,8 +280,9 @@ void LineBucket::addGeometry(const std::vector& vertices) { } group.vertex_length += vertex_count; - group.elements_length += triangle_store.size(); + group.elements_length += triangleStore.size(); } + /* // Store the line join/cap groups. { @@ -324,6 +300,33 @@ void LineBucket::addGeometry(const std::vector& vertices) { group.vertex_length += vertex_count; group.elements_length += point_store.size(); } + */ +} + +void LineBucket::addCurrentVertex(const Coordinate& currentVertex, float flip, double distance, + const vec2& normal, float endLeft, float endRight, bool round, + int32_t startVertex, std::vector& triangleStore) { + int8_t tx = round ? 1 : 0; + + vec2 extrude = normal * flip; + if (endLeft) extrude = extrude - (util::perp(normal) * endLeft); + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, + extrude.x, extrude.y, tx, 0, distance) - startVertex; + if (e1 >= 0 && e2 >= 0) { + triangleStore.emplace_back(e1, e2, e3); + } + e1 = e2; + e2 = e3; + + extrude = normal * (-flip); + if (endRight) extrude = extrude - (util::perp(normal) * endRight); + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, + extrude.x, extrude.y, tx, 1, distance) - startVertex; + if (e1 >= 0 && e2 >= 0) { + triangleStore.emplace_back(e1, e2, e3); + } + e1 = e2; + e2 = e3; } void LineBucket::render(Painter &painter, const StyleLayer &layer_desc, const TileID &id, diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index d70801e0b..3e9626219 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -46,6 +46,15 @@ public: void drawLinePatterns(LinepatternShader& shader); void drawPoints(LinejoinShader& shader); +private: + struct TriangleElement { + TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {} + uint16_t a, b, c; + }; + void addCurrentVertex(const Coordinate& currentVertex, float flip, double distance, + const vec2& normal, float endLeft, float endRight, bool round, + int32_t startVertex, std::vector& triangleStore); + public: StyleLayoutLine layout; @@ -58,6 +67,10 @@ private: const size_t triangle_elements_start; const size_t point_elements_start; + int32_t e1; + int32_t e2; + int32_t e3; + std::vector> triangleGroups; std::vector> pointGroups; }; diff --git a/src/mbgl/style/types.hpp b/src/mbgl/style/types.hpp index 3b24d6399..f6ffcd686 100644 --- a/src/mbgl/style/types.hpp +++ b/src/mbgl/style/types.hpp @@ -91,13 +91,15 @@ MBGL_DEFINE_ENUM_CLASS(CapTypeClass, CapType, { enum class JoinType : uint8_t { Miter, Bevel, - Round + Round, + FlipBevel }; MBGL_DEFINE_ENUM_CLASS(JoinTypeClass, JoinType, { { JoinType::Miter, "miter" }, { JoinType::Bevel, "bevel" }, { JoinType::Round, "round" }, + { JoinType::FlipBevel, "flipbevel" }, }); // ------------------------------------------------------------------------------------------------- From f1edce8e213ddb595512d7d0d4bade7879aa03ff Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Fri, 24 Apr 2015 13:06:01 -0700 Subject: [PATCH 22/27] remove linejoin shader The previous commit switched to using triangles for drawing round joins. --- src/mbgl/geometry/elements_buffer.cpp | 5 --- src/mbgl/geometry/elements_buffer.hpp | 10 ----- src/mbgl/map/tile_parser.cpp | 3 +- src/mbgl/map/vector_tile_data.hpp | 1 - src/mbgl/renderer/line_bucket.cpp | 59 ++------------------------ src/mbgl/renderer/line_bucket.hpp | 12 +----- src/mbgl/renderer/painter.cpp | 3 -- src/mbgl/renderer/painter.hpp | 2 - src/mbgl/renderer/painter_line.cpp | 23 ---------- src/mbgl/shader/linejoin.fragment.glsl | 14 ------ src/mbgl/shader/linejoin.vertex.glsl | 13 ------ src/mbgl/shader/linejoin_shader.cpp | 22 ---------- src/mbgl/shader/linejoin_shader.hpp | 27 ------------ 13 files changed, 6 insertions(+), 188 deletions(-) delete mode 100644 src/mbgl/shader/linejoin.fragment.glsl delete mode 100644 src/mbgl/shader/linejoin.vertex.glsl delete mode 100644 src/mbgl/shader/linejoin_shader.cpp delete mode 100644 src/mbgl/shader/linejoin_shader.hpp diff --git a/src/mbgl/geometry/elements_buffer.cpp b/src/mbgl/geometry/elements_buffer.cpp index 79af1b7e3..3e2e2794d 100644 --- a/src/mbgl/geometry/elements_buffer.cpp +++ b/src/mbgl/geometry/elements_buffer.cpp @@ -14,8 +14,3 @@ void LineElementsBuffer::add(element_type a, element_type b) { elements[0] = a; elements[1] = b; } - -void PointElementsBuffer::add(element_type a) { - uint16_t *data = static_cast(addElement()); - data[0] = a; -} diff --git a/src/mbgl/geometry/elements_buffer.hpp b/src/mbgl/geometry/elements_buffer.hpp index 5c1b421d3..24753ebaf 100644 --- a/src/mbgl/geometry/elements_buffer.hpp +++ b/src/mbgl/geometry/elements_buffer.hpp @@ -44,16 +44,6 @@ public: void add(element_type a, element_type b); }; -class PointElementsBuffer : public Buffer< - 2, // bytes per point (1 unsigned short) - GL_ELEMENT_ARRAY_BUFFER -> { -public: - typedef uint16_t element_type; - - void add(element_type a); -}; - } #endif diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index 275b77be9..d0d17aaf3 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -172,8 +172,7 @@ std::unique_ptr TileParser::createFillBucket(const GeometryTileLayer& la std::unique_ptr TileParser::createLineBucket(const GeometryTileLayer& layer, const StyleBucket& bucket_desc) { auto bucket = util::make_unique(tile.lineVertexBuffer, - tile.triangleElementsBuffer, - tile.pointElementsBuffer); + tile.triangleElementsBuffer); const float z = tile.id.z; auto& layout = bucket->layout; diff --git a/src/mbgl/map/vector_tile_data.hpp b/src/mbgl/map/vector_tile_data.hpp index 4e2f252f8..e87978c24 100644 --- a/src/mbgl/map/vector_tile_data.hpp +++ b/src/mbgl/map/vector_tile_data.hpp @@ -50,7 +50,6 @@ protected: TriangleElementsBuffer triangleElementsBuffer; LineElementsBuffer lineElementsBuffer; - PointElementsBuffer pointElementsBuffer; // Holds the buckets of this tile. // They contain the location offsets in the buffers stored above diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index d6159df01..9184a2d51 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -16,23 +16,18 @@ using namespace mbgl; LineBucket::LineBucket(LineVertexBuffer &vertexBuffer_, - TriangleElementsBuffer &triangleElementsBuffer_, - PointElementsBuffer &pointElementsBuffer_) + TriangleElementsBuffer &triangleElementsBuffer_) : vertexBuffer(vertexBuffer_), triangleElementsBuffer(triangleElementsBuffer_), - pointElementsBuffer(pointElementsBuffer_), vertex_start(vertexBuffer_.index()), - triangle_elements_start(triangleElementsBuffer_.index()), - point_elements_start(pointElementsBuffer_.index()) { -} + triangle_elements_start(triangleElementsBuffer_.index()) { +}; LineBucket::~LineBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } -typedef uint16_t PointElement; - void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { for (auto& line : geometryCollection) { addGeometry(line); @@ -282,25 +277,6 @@ void LineBucket::addGeometry(const std::vector& vertices) { group.vertex_length += vertex_count; group.elements_length += triangleStore.size(); } - /* - - // Store the line join/cap groups. - { - if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) { - // Move to a new group because the old one can't hold the geometry. - pointGroups.emplace_back(util::make_unique()); - } - - assert(pointGroups.back()); - point_group_type& group = *pointGroups.back(); - for (const auto point : point_store) { - pointElementsBuffer.add(group.vertex_length + point); - } - - group.vertex_length += vertex_count; - group.elements_length += point_store.size(); - } - */ } void LineBucket::addCurrentVertex(const Coordinate& currentVertex, float flip, double distance, @@ -335,19 +311,7 @@ void LineBucket::render(Painter &painter, const StyleLayer &layer_desc, const Ti } bool LineBucket::hasData() const { - return !triangleGroups.empty() || !pointGroups.empty(); -} - -bool LineBucket::hasPoints() const { - if (!pointGroups.empty()) { - for (const auto& group : pointGroups) { - assert(group); - if (group->elements_length) { - return true; - } - } - } - return false; + return !triangleGroups.empty(); } void LineBucket::drawLines(LineShader& shader) { @@ -394,18 +358,3 @@ void LineBucket::drawLinePatterns(LinepatternShader& shader) { elements_index += group->elements_length * triangleElementsBuffer.itemSize; } } - -void LineBucket::drawPoints(LinejoinShader& shader) { - char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); - char *elements_index = BUFFER_OFFSET(point_elements_start * pointElementsBuffer.itemSize); - for (auto& group : pointGroups) { - assert(group); - if (!group->elements_length) { - continue; - } - group->array[0].bind(shader, vertexBuffer, pointElementsBuffer, vertex_index); - MBGL_CHECK_ERROR(glDrawElements(GL_POINTS, group->elements_length, GL_UNSIGNED_SHORT, elements_index)); - vertex_index += group->vertex_length * vertexBuffer.itemSize; - elements_index += group->elements_length * pointElementsBuffer.itemSize; - } -} diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 3e9626219..85b1ea78f 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -18,18 +18,14 @@ class Style; class LineVertexBuffer; class TriangleElementsBuffer; class LineShader; -class LinejoinShader; class LineSDFShader; class LinepatternShader; class LineBucket : public Bucket { typedef ElementGroup<3> triangle_group_type; - typedef ElementGroup<1> point_group_type; public: - LineBucket(LineVertexBuffer &vertexBuffer, - TriangleElementsBuffer &triangleElementsBuffer, - PointElementsBuffer &pointElementsBuffer); + LineBucket(LineVertexBuffer &vertexBuffer, TriangleElementsBuffer &triangleElementsBuffer); ~LineBucket() override; void render(Painter &painter, const StyleLayer &layer_desc, const TileID &id, @@ -39,12 +35,9 @@ public: void addGeometry(const GeometryCollection&); void addGeometry(const std::vector& line); - bool hasPoints() const; - void drawLines(LineShader& shader); void drawLineSDF(LineSDFShader& shader); void drawLinePatterns(LinepatternShader& shader); - void drawPoints(LinejoinShader& shader); private: struct TriangleElement { @@ -61,18 +54,15 @@ public: private: LineVertexBuffer& vertexBuffer; TriangleElementsBuffer& triangleElementsBuffer; - PointElementsBuffer& pointElementsBuffer; const size_t vertex_start; const size_t triangle_elements_start; - const size_t point_elements_start; int32_t e1; int32_t e2; int32_t e3; std::vector> triangleGroups; - std::vector> pointGroups; }; } diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index cafd61424..1e34f5320 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -62,7 +62,6 @@ void Painter::setup() { assert(plainShader); assert(outlineShader); assert(lineShader); - assert(linejoinShader); assert(linepatternShader); assert(patternShader); assert(rasterShader); @@ -96,7 +95,6 @@ void Painter::setupShaders() { if (!plainShader) plainShader = util::make_unique(); if (!outlineShader) outlineShader = util::make_unique(); if (!lineShader) lineShader = util::make_unique(); - if (!linejoinShader) linejoinShader = util::make_unique(); if (!linesdfShader) linesdfShader = util::make_unique(); if (!linepatternShader) linepatternShader = util::make_unique(); if (!patternShader) patternShader = util::make_unique(); @@ -112,7 +110,6 @@ void Painter::deleteShaders() { plainShader = nullptr; outlineShader = nullptr; lineShader = nullptr; - linejoinShader = nullptr; linepatternShader = nullptr; patternShader = nullptr; iconShader = nullptr; diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index cf01c0391..76cacba43 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -199,7 +198,6 @@ public: std::unique_ptr plainShader; std::unique_ptr outlineShader; std::unique_ptr lineShader; - std::unique_ptr linejoinShader; std::unique_ptr linesdfShader; std::unique_ptr linepatternShader; std::unique_ptr patternShader; diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 2f8c3face..57690da46 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -51,29 +51,6 @@ void Painter::renderLine(LineBucket& bucket, const StyleLayer &layer_desc, const depthRange(strata, 1.0f); - // We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway. - if (bucket.hasPoints() && outset > 1.0f) { - useProgram(linejoinShader->program); - linejoinShader->u_matrix = vtxMatrix; - linejoinShader->u_color = color; - linejoinShader->u_world = {{ - state.getFramebufferWidth() * 0.5f, - state.getFramebufferHeight() * 0.5f - }}; - linejoinShader->u_linewidth = {{ - ((outset - 0.25f) * state.getPixelRatio()), - ((inset - 0.25f) * state.getPixelRatio()) - }}; - - float pointSize = std::ceil(state.getPixelRatio() * outset * 2.0); -#if defined(GL_ES_VERSION_2_0) - linejoinShader->u_size = pointSize; -#else - MBGL_CHECK_ERROR(glPointSize(pointSize)); -#endif - bucket.drawPoints(*linejoinShader); - } - if (properties.dash_array.from.size()) { useProgram(linesdfShader->program); diff --git a/src/mbgl/shader/linejoin.fragment.glsl b/src/mbgl/shader/linejoin.fragment.glsl deleted file mode 100644 index 705a57766..000000000 --- a/src/mbgl/shader/linejoin.fragment.glsl +++ /dev/null @@ -1,14 +0,0 @@ -uniform vec4 u_color; -uniform vec2 u_linewidth; - -varying vec2 v_pos; - -void main() { - float dist = length(v_pos - gl_FragCoord.xy); - - // Calculate the antialiasing fade factor. This is either when fading in - // the line in case of an offset line (v_linewidth.t) or when fading out - // (v_linewidth.s) - float alpha = clamp(min(dist - (u_linewidth.t - 1.0), u_linewidth.s - dist), 0.0, 1.0); - gl_FragColor = u_color * alpha; -} diff --git a/src/mbgl/shader/linejoin.vertex.glsl b/src/mbgl/shader/linejoin.vertex.glsl deleted file mode 100644 index 2e03561e5..000000000 --- a/src/mbgl/shader/linejoin.vertex.glsl +++ /dev/null @@ -1,13 +0,0 @@ -attribute vec2 a_pos; - -uniform mat4 u_matrix; -uniform vec2 u_world; -uniform float u_size; - -varying vec2 v_pos; - -void main() { - gl_Position = u_matrix * vec4(floor(a_pos / 2.0), 0.0, 1.0); - v_pos = (gl_Position.xy + 1.0) * u_world; - gl_PointSize = u_size; -} diff --git a/src/mbgl/shader/linejoin_shader.cpp b/src/mbgl/shader/linejoin_shader.cpp deleted file mode 100644 index b3c5638b5..000000000 --- a/src/mbgl/shader/linejoin_shader.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -#include - -using namespace mbgl; - -LinejoinShader::LinejoinShader() - : Shader( - "linejoin", - shaders[LINEJOIN_SHADER].vertex, - shaders[LINEJOIN_SHADER].fragment - ) { - a_pos = MBGL_CHECK_ERROR(glGetAttribLocation(program, "a_pos")); -} - -void LinejoinShader::bind(char *offset) { - MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos)); - // Note: We're referring to the vertices in a line array, which are 8 bytes long! - MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset)); -} diff --git a/src/mbgl/shader/linejoin_shader.hpp b/src/mbgl/shader/linejoin_shader.hpp deleted file mode 100644 index 61406fd45..000000000 --- a/src/mbgl/shader/linejoin_shader.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef MBGL_SHADER_SHADER_LINEJOIN -#define MBGL_SHADER_SHADER_LINEJOIN - -#include -#include - -namespace mbgl { - -class LinejoinShader : public Shader { -public: - LinejoinShader(); - - void bind(char *offset); - - UniformMatrix<4> u_matrix = {"u_matrix", *this}; - Uniform> u_color = {"u_color", *this}; - Uniform> u_world = {"u_world", *this}; - Uniform> u_linewidth = {"u_linewidth", *this}; - Uniform u_size = {"u_size", *this}; - -private: - int32_t a_pos = -1; -}; - -} - -#endif From feade7b4e42bf8d293d5023dc12ea2f9106e3b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Mon, 27 Apr 2015 11:31:44 +0200 Subject: [PATCH 23/27] const + code style --- src/mbgl/renderer/line_bucket.cpp | 198 ++++++++++++++++++------------ src/mbgl/renderer/line_bucket.hpp | 4 +- 2 files changed, 120 insertions(+), 82 deletions(-) diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 9184a2d51..78da158f1 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -8,26 +8,25 @@ #include #include -#define BUFFER_OFFSET(i) ((char *)nullptr + (i)) +#ifndef BUFFER_OFFSET +#define BUFFER_OFFSET(i) ((char*)nullptr + (i)) +#endif #include using namespace mbgl; - -LineBucket::LineBucket(LineVertexBuffer &vertexBuffer_, - TriangleElementsBuffer &triangleElementsBuffer_) +LineBucket::LineBucket(LineVertexBuffer& vertexBuffer_, + TriangleElementsBuffer& triangleElementsBuffer_) : vertexBuffer(vertexBuffer_), triangleElementsBuffer(triangleElementsBuffer_), vertex_start(vertexBuffer_.index()), - triangle_elements_start(triangleElementsBuffer_.index()) { -}; + triangle_elements_start(triangleElementsBuffer_.index()){}; LineBucket::~LineBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } - void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { for (auto& line : geometryCollection) { addGeometry(line); @@ -35,12 +34,14 @@ void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { } void LineBucket::addGeometry(const std::vector& vertices) { - - auto len = vertices.size(); - // If the line has duplicate vertices at the end, adjust length to remove them. - while (len > 2 && vertices[len - 1] == vertices[len - 2]) { - len--; - } + const auto len = [&vertices] { + auto l = vertices.size(); + // If the line has duplicate vertices at the end, adjust length to remove them. + while (l > 2 && vertices[l - 1] == vertices[l - 2]) { + l--; + } + return l; + }(); if (len < 2) { // fprintf(stderr, "a line must have at least two vertices\n"); @@ -49,25 +50,24 @@ void LineBucket::addGeometry(const std::vector& vertices) { const float miterLimit = layout.join == JoinType::Bevel ? 1.05f : layout.miter_limit; - Coordinate firstVertex = vertices.front(); - Coordinate lastVertex = vertices[len - 1]; - bool closed = firstVertex == lastVertex; + const Coordinate firstVertex = vertices.front(); + const Coordinate lastVertex = vertices[len - 1]; + const bool closed = firstVertex == lastVertex; if (len == 2 && closed) { // fprintf(stderr, "a line may not have coincident points\n"); return; } - CapType beginCap = layout.cap; - CapType endCap = closed ? CapType::Butt : layout.cap; + const CapType beginCap = layout.cap; + const CapType endCap = closed ? CapType::Butt : layout.cap; + int8_t flip = 1; double distance = 0; bool startOfLine = true; - Coordinate currentVertex = Coordinate::null(), - prevVertex = Coordinate::null(), + Coordinate currentVertex = Coordinate::null(), prevVertex = Coordinate::null(), nextVertex = Coordinate::null(); - vec2 prevNormal = vec2::null(), - nextNormal = vec2::null(); + vec2 prevNormal = vec2::null(), nextNormal = vec2::null(); // the last three vertices added e1 = e2 = e3 = -1; @@ -77,11 +77,10 @@ void LineBucket::addGeometry(const std::vector& vertices) { nextNormal = util::perp(util::unit(vec2(firstVertex - currentVertex))); } - int32_t startVertex = (int32_t)vertexBuffer.index(); - std::vector triangleStore; + const int32_t startVertex = (int32_t)vertexBuffer.index(); + std::vector triangleStore; for (size_t i = 0; i < len; ++i) { - if (closed && i == len - 1) { // if the line is closed, we treat the last vertex like the first nextVertex = vertices[i]; @@ -94,30 +93,39 @@ void LineBucket::addGeometry(const std::vector& vertices) { } // if two consecutive vertices exist, skip the current one - if (nextVertex && vertices[i] == nextVertex) continue; + if (nextVertex && vertices[i] == nextVertex) { + continue; + } - if (nextNormal) prevNormal = nextNormal; - if (currentVertex) prevVertex = currentVertex; + if (nextNormal) { + prevNormal = nextNormal; + } + if (currentVertex) { + prevVertex = currentVertex; + } currentVertex = vertices[i]; // Calculate how far along the line the currentVertex is - if (prevVertex) distance += util::dist(currentVertex, prevVertex); + if (prevVertex) + distance += util::dist(currentVertex, prevVertex); // Calculate the normal towards the next vertex in this line. In case // there is no next vertex, pretend that the line is continuing straight, // meaning that we are just using the previous normal. - nextNormal = nextVertex ? util::perp(util::unit(vec2(nextVertex - currentVertex))) : prevNormal; + nextNormal = nextVertex ? util::perp(util::unit(vec2(nextVertex - currentVertex))) + : prevNormal; // If we still don't have a previous normal, this is the beginning of a // non-closed line, so we're doing a straight "join". - if (!prevNormal) prevNormal = nextNormal; + if (!prevNormal) { + prevNormal = nextNormal; + } // Determine the normal of the join extrusion. It is the angle bisector // of the segments between the previous line and the next line. vec2 joinNormal = util::unit(prevNormal + nextNormal); - /* joinNormal prevNormal * ↖ ↑ * .________. prevVertex @@ -137,7 +145,7 @@ void LineBucket::addGeometry(const std::vector& vertices) { // The join if a middle vertex, otherwise the cap const bool middleVertex = prevVertex && nextVertex; JoinType currentJoin = layout.join; - CapType currentCap = nextVertex ? beginCap : endCap; + const CapType currentCap = nextVertex ? beginCap : endCap; if (middleVertex) { if (currentJoin == JoinType::Round && miterLength < layout.round_limit) { @@ -151,17 +159,22 @@ void LineBucket::addGeometry(const std::vector& vertices) { if (currentJoin == JoinType::Bevel) { // The maximum extrude length is 128 / 63 = 2 times the width of the line // so if miterLength >= 2 we need to draw a different type of bevel where. - if (miterLength > 2) currentJoin = JoinType::FlipBevel; + if (miterLength > 2) { + currentJoin = JoinType::FlipBevel; + } // If the miterLength is really small and the line bevel wouldn't be visible, // just draw a miter join to save a triangle. - if (miterLength < miterLimit) currentJoin = JoinType::Miter; + if (miterLength < miterLimit) { + currentJoin = JoinType::Miter; + } } } if (middleVertex && currentJoin == JoinType::Miter) { joinNormal = joinNormal * miterLength; - addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex, + triangleStore); } else if (middleVertex && currentJoin == JoinType::FlipBevel) { // miter is too big, flip the direction to make a beveled join @@ -170,11 +183,13 @@ void LineBucket::addGeometry(const std::vector& vertices) { // Almost parallel lines joinNormal = nextNormal; } else { - const float bevelLength = miterLength * util::mag(prevNormal + nextNormal) / util::mag(prevNormal - nextNormal); + const float bevelLength = miterLength * util::mag(prevNormal + nextNormal) / + util::mag(prevNormal - nextNormal); joinNormal = util::perp(joinNormal) * bevelLength; } - addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, joinNormal, 0, 0, false, startVertex, + triangleStore); flip = -flip; } else if (middleVertex && currentJoin == JoinType::Bevel) { @@ -193,29 +208,34 @@ void LineBucket::addGeometry(const std::vector& vertices) { // Close previous segement with bevel if (!startOfLine) { - addCurrentVertex(currentVertex, flip, distance, prevNormal, offsetA, offsetB, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, prevNormal, offsetA, offsetB, false, + startVertex, triangleStore); } // Start next segment if (nextVertex) { - addCurrentVertex(currentVertex, flip, distance, nextNormal, -offsetA, -offsetB, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, nextNormal, -offsetA, -offsetB, + false, startVertex, triangleStore); } } else if (!middleVertex && currentCap == CapType::Butt) { if (!startOfLine) { // Close previous segment with a butt - addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false, + startVertex, triangleStore); } // Start next segment with a butt if (nextVertex) { - addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false, + startVertex, triangleStore); } } else if (!middleVertex && currentCap == CapType::Square) { if (!startOfLine) { // Close previous segment with a square cap - addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, false, + startVertex, triangleStore); // The segment is done. Unset vertices to disconnect segments. e1 = e2 = -1; @@ -224,16 +244,19 @@ void LineBucket::addGeometry(const std::vector& vertices) { // Start next segment if (nextVertex) { - addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, false, + startVertex, triangleStore); } } else if (middleVertex ? currentJoin == JoinType::Round : currentCap == CapType::Round) { if (!startOfLine) { // Close previous segment with a butt - addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, prevNormal, 0, 0, false, + startVertex, triangleStore); // Add round cap or linejoin at end of segment - addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, true , startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, prevNormal, 1, 1, true, startVertex, + triangleStore); // The segment is done. Unset vertices to disconnect segments. e1 = e2 = -1; @@ -241,53 +264,61 @@ void LineBucket::addGeometry(const std::vector& vertices) { } else if (beginCap == CapType::Round) { // Add round cap before first segment - addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, true, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, nextNormal, -1, -1, true, + startVertex, triangleStore); } - // Start next segment with a butt if (nextVertex) { - addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(currentVertex, flip, distance, nextNormal, 0, 0, false, + startVertex, triangleStore); } } startOfLine = false; } - size_t end_vertex = vertexBuffer.index(); - size_t vertex_count = end_vertex - startVertex; + const size_t endVertex = vertexBuffer.index(); + const size_t vertexCount = endVertex - startVertex; // Store the triangle/line groups. { - if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) { + if (!triangleGroups.size() || + (triangleGroups.back()->vertex_length + vertexCount > 65535)) { // Move to a new group because the old one can't hold the geometry. - triangleGroups.emplace_back(util::make_unique()); + triangleGroups.emplace_back(util::make_unique()); } assert(triangleGroups.back()); - triangle_group_type& group = *triangleGroups.back(); + auto& group = *triangleGroups.back(); for (const auto& triangle : triangleStore) { - triangleElementsBuffer.add( - group.vertex_length + triangle.a, - group.vertex_length + triangle.b, - group.vertex_length + triangle.c - ); + triangleElementsBuffer.add(group.vertex_length + triangle.a, + group.vertex_length + triangle.b, + group.vertex_length + triangle.c); } - group.vertex_length += vertex_count; + group.vertex_length += vertexCount; group.elements_length += triangleStore.size(); } } -void LineBucket::addCurrentVertex(const Coordinate& currentVertex, float flip, double distance, - const vec2& normal, float endLeft, float endRight, bool round, - int32_t startVertex, std::vector& triangleStore) { +void LineBucket::addCurrentVertex(const Coordinate& currentVertex, + float flip, + double distance, + const vec2& normal, + float endLeft, + float endRight, + bool round, + int32_t startVertex, + std::vector& triangleStore) { int8_t tx = round ? 1 : 0; vec2 extrude = normal * flip; - if (endLeft) extrude = extrude - (util::perp(normal) * endLeft); - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, - extrude.x, extrude.y, tx, 0, distance) - startVertex; + if (endLeft) + extrude = extrude - (util::perp(normal) * endLeft); + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0, + distance) - + startVertex; if (e1 >= 0 && e2 >= 0) { triangleStore.emplace_back(e1, e2, e3); } @@ -295,9 +326,11 @@ void LineBucket::addCurrentVertex(const Coordinate& currentVertex, float flip, d e2 = e3; extrude = normal * (-flip); - if (endRight) extrude = extrude - (util::perp(normal) * endRight); - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, - extrude.x, extrude.y, tx, 1, distance) - startVertex; + if (endRight) + extrude = extrude - (util::perp(normal) * endRight); + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1, + distance) - + startVertex; if (e1 >= 0 && e2 >= 0) { triangleStore.emplace_back(e1, e2, e3); } @@ -305,8 +338,10 @@ void LineBucket::addCurrentVertex(const Coordinate& currentVertex, float flip, d e2 = e3; } -void LineBucket::render(Painter &painter, const StyleLayer &layer_desc, const TileID &id, - const mat4 &matrix) { +void LineBucket::render(Painter& painter, + const StyleLayer& layer_desc, + const TileID& id, + const mat4& matrix) { painter.renderLine(*this, layer_desc, id, matrix); } @@ -315,45 +350,48 @@ bool LineBucket::hasData() const { } void LineBucket::drawLines(LineShader& shader) { - char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); - char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize); + char* vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); + char* elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize); for (auto& group : triangleGroups) { assert(group); if (!group->elements_length) { continue; } group->array[0].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); - MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); + MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, + elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; elements_index += group->elements_length * triangleElementsBuffer.itemSize; } } void LineBucket::drawLineSDF(LineSDFShader& shader) { - char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); - char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize); + char* vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); + char* elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize); for (auto& group : triangleGroups) { assert(group); if (!group->elements_length) { continue; } group->array[2].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); - MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); + MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, + elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; elements_index += group->elements_length * triangleElementsBuffer.itemSize; } } void LineBucket::drawLinePatterns(LinepatternShader& shader) { - char *vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); - char *elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize); + char* vertex_index = BUFFER_OFFSET(vertex_start * vertexBuffer.itemSize); + char* elements_index = BUFFER_OFFSET(triangle_elements_start * triangleElementsBuffer.itemSize); for (auto& group : triangleGroups) { assert(group); if (!group->elements_length) { continue; } group->array[1].bind(shader, vertexBuffer, triangleElementsBuffer, vertex_index); - MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elements_index)); + MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, + elements_index)); vertex_index += group->vertex_length * vertexBuffer.itemSize; elements_index += group->elements_length * triangleElementsBuffer.itemSize; } diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 85b1ea78f..64f353d7c 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -22,7 +22,7 @@ class LineSDFShader; class LinepatternShader; class LineBucket : public Bucket { - typedef ElementGroup<3> triangle_group_type; + using TriangleGroup = ElementGroup<3>; public: LineBucket(LineVertexBuffer &vertexBuffer, TriangleElementsBuffer &triangleElementsBuffer); @@ -62,7 +62,7 @@ private: int32_t e2; int32_t e3; - std::vector> triangleGroups; + std::vector> triangleGroups; }; } From 86e90da6d506dc89c315a6ea407df89eae0b4729 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Mon, 27 Apr 2015 10:55:12 -0400 Subject: [PATCH 24/27] #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 25/27] #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 26/27] #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 27/27] #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