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