summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2018-04-26 19:10:27 -0400
committerJulian Rex <julian.rex@mapbox.com>2018-05-21 13:26:49 -0400
commit1af29e2118a6585109936ebc4b613c0010e9a382 (patch)
tree44beff199c22be3878ee42fb6151f620dd472013
parent9accdee5d8da29481e400276d1ee10c431575356 (diff)
downloadqtlocation-mapboxgl-1af29e2118a6585109936ebc4b613c0010e9a382.tar.gz
Added additional test for interrupting a transition, and associated fix.
Added failing (currently disabled) test, where the interruption still triggers an infinite loop.
-rw-r--r--platform/ios/Integration Tests/MGLCameraTransitionTests.mm78
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/Integration Test Harness.xcscheme5
-rw-r--r--platform/ios/src/MGLCameraChangeReason.h6
-rw-r--r--platform/ios/src/MGLMapView.mm34
-rw-r--r--src/mbgl/map/transform.cpp2
5 files changed, 109 insertions, 16 deletions
diff --git a/platform/ios/Integration Tests/MGLCameraTransitionTests.mm b/platform/ios/Integration Tests/MGLCameraTransitionTests.mm
index c895f47983..b95ac6613f 100644
--- a/platform/ios/Integration Tests/MGLCameraTransitionTests.mm
+++ b/platform/ios/Integration Tests/MGLCameraTransitionTests.mm
@@ -64,6 +64,84 @@
[self waitForExpectations:@[expectation] timeout:1.5];
}
+- (void)testInterruptingAndResetNorthOnlyOnceInIsChanging {
+
+ // Reset to non-zero, prior to testing
+ [self.mapView setDirection:45 animated:NO];
+
+ XCTestExpectation *expectation = [self expectationWithDescription:@"regionDidChange expectation"];
+ expectation.expectedFulfillmentCount = 1;
+ expectation.assertForOverFulfill = YES;
+
+ __weak typeof(self) weakself = self;
+ __block BOOL startedReset = NO;
+ __block BOOL finishedReset = NO;
+
+ self.regionIsChanging = ^(MGLMapView *mapView) {
+ MBCameraTransitionTests *strongSelf = weakself;
+ if (!strongSelf) return;
+
+ if (!startedReset) {
+ NSLog(@"Reset to north, interrupting the previous transition");
+ startedReset = YES;
+ [mapView resetNorth];
+ finishedReset = YES;
+ }
+ };
+
+ self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) {
+ MBCameraTransitionTests *strongSelf = weakself;
+ if (!strongSelf) return;
+
+ MGLTestAssert(strongSelf, startedReset);
+
+ if (finishedReset) {
+ MGLTestAssert(strongSelf, !(reason & MGLCameraChangeReasonTransitionCancelled));
+ [expectation fulfill];
+ }
+ else {
+ MGLTestAssert(strongSelf, reason & MGLCameraChangeReasonTransitionCancelled);
+ }
+ };
+
+ [self.mapView setDirection:90 animated:YES];
+ [self waitForExpectations:@[expectation] timeout:1.5];
+
+ XCTAssertEqualWithAccuracy(self.mapView.direction, 0.0, 0.001, @"Camera should have reset to north. %0.3f", self.mapView.direction);
+}
+
+- (void)testContinuallyResettingNorthInIsChanging {
+
+ // Reset to non-zero, prior to testing
+ [self.mapView setDirection:45 animated:NO];
+
+ XCTestExpectation *expectation = [self expectationWithDescription:@"regionDidChange expectation"];
+ expectation.expectedFulfillmentCount = 1;
+ expectation.assertForOverFulfill = YES;
+
+ __weak typeof(self) weakself = self;
+
+ self.regionIsChanging = ^(MGLMapView *mapView) {
+ MBCameraTransitionTests *strongSelf = weakself;
+ if (!strongSelf) return;
+
+ [mapView resetNorth];
+ };
+
+ self.regionDidChange = ^(MGLMapView *mapView, MGLCameraChangeReason reason, BOOL animated) {
+ MBCameraTransitionTests *strongSelf = weakself;
+ if (!strongSelf) return;
+
+ MGLTestAssert(strongSelf, reason & MGLCameraChangeReasonTransitionCancelled);
+ };
+
+ [self.mapView setDirection:90 animated:YES];
+ [self waitForExpectations:@[expectation] timeout:1.5];
+
+ XCTAssertEqualWithAccuracy(self.mapView.direction, 0.0, 0.001, @"Camera should have reset to north. %0.3f", self.mapView.direction);
+}
+
+
- (void)testSetCenterCancelsTransitions {
XCTestExpectation *cameraIsInDCExpectation = [self expectationWithDescription:@"camera reset to DC"];
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/Integration Test Harness.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/Integration Test Harness.xcscheme
index 1638592557..2a37b73caa 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/Integration Test Harness.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/Integration Test Harness.xcscheme
@@ -37,6 +37,11 @@
BlueprintName = "integration"
ReferencedContainer = "container:ios.xcodeproj">
</BuildableReference>
+ <SkippedTests>
+ <Test
+ Identifier = "MBCameraTransitionTests/testContinuallyResettingNorthInIsChanging">
+ </Test>
+ </SkippedTests>
</TestableReference>
</Testables>
<MacroExpansion>
diff --git a/platform/ios/src/MGLCameraChangeReason.h b/platform/ios/src/MGLCameraChangeReason.h
index 6c6b3636ba..f439d3e7ea 100644
--- a/platform/ios/src/MGLCameraChangeReason.h
+++ b/platform/ios/src/MGLCameraChangeReason.h
@@ -57,5 +57,9 @@ typedef NS_OPTIONS(NSUInteger, MGLCameraChangeReason)
MGLCameraChangeReasonGestureOneFingerZoom = 1 << 7,
// :nodoc: The user panned with two fingers to tilt the map (two finger drag).
- MGLCameraChangeReasonGestureTilt = 1 << 8
+ MGLCameraChangeReasonGestureTilt = 1 << 8,
+
+ // :nodoc: Cancelled
+ MGLCameraChangeReasonTransitionCancelled = 1 << 16
+
};
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 26b23abb4e..e16411f2c5 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1271,7 +1271,7 @@ public:
{
[self setUserTrackingMode:MGLUserTrackingModeNone animated:NO];
}
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
}
- (void)notifyGestureDidBegin {
@@ -1321,7 +1321,7 @@ public:
{
if ( ! self.isScrollEnabled) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
MGLMapCamera *oldCamera = self.camera;
@@ -1390,7 +1390,7 @@ public:
{
if ( ! self.isZoomEnabled) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
CGPoint centerPoint = [self anchorPointForGesture:pinch];
MGLMapCamera *oldCamera = self.camera;
@@ -1491,7 +1491,7 @@ public:
{
if ( ! self.isRotateEnabled) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
CGPoint centerPoint = [self anchorPointForGesture:rotate];
MGLMapCamera *oldCamera = self.camera;
@@ -1696,7 +1696,7 @@ public:
{
if ( ! self.isZoomEnabled) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
if (doubleTap.state == UIGestureRecognizerStateEnded)
{
@@ -1737,7 +1737,7 @@ public:
if (_mbglMap->getZoom() == _mbglMap->getMinZoom()) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonGestureZoomOut;
@@ -1776,7 +1776,7 @@ public:
{
if ( ! self.isZoomEnabled) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonGestureOneFingerZoom;
@@ -1821,7 +1821,7 @@ public:
{
if ( ! self.isPitchEnabled) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonGestureTilt;
@@ -2981,7 +2981,7 @@ public:
return;
}
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic;
@@ -3006,7 +3006,7 @@ public:
- (void)setZoomLevel:(double)zoomLevel animated:(BOOL)animated
{
if (zoomLevel == self.zoomLevel) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic;
@@ -3149,7 +3149,7 @@ public:
}
[self willChangeValueForKey:@"visibleCoordinateBounds"];
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic;
@@ -3182,7 +3182,7 @@ public:
- (void)_setDirection:(CLLocationDirection)direction animated:(BOOL)animated
{
if (direction == self.direction) return;
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
CGFloat duration = animated ? MGLAnimationDuration : 0;
@@ -3271,7 +3271,7 @@ public:
}
[self willChangeValueForKey:@"camera"];
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic;
@@ -3330,7 +3330,7 @@ public:
}
[self willChangeValueForKey:@"camera"];
- _mbglMap->cancelTransitions();
+ [self cancelTransitions];
self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic;
@@ -3339,6 +3339,12 @@ public:
[self didChangeValueForKey:@"camera"];
}
+- (void)cancelTransitions {
+ self.cameraChangeReasonBitmask |= MGLCameraChangeReasonTransitionCancelled;
+ _mbglMap->cancelTransitions();
+ self.cameraChangeReasonBitmask &= ~MGLCameraChangeReasonTransitionCancelled;
+}
+
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds
{
return [self cameraThatFitsCoordinateBounds:bounds edgePadding:UIEdgeInsetsZero];
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 79815d9398..77dcd69972 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -655,7 +655,7 @@ void Transform::updateTransitions(const TimePoint& now) {
finish();
}
}
- else {
+ else if (!transitionFrameFn) {
transitionFrameFn = std::move(transition);
}
}