Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Check for duplicate layer IDs #7257

Merged
merged 4 commits into from
Dec 12, 2016
Merged

Check for duplicate layer IDs #7257

merged 4 commits into from
Dec 12, 2016

Conversation

ivovandongen
Copy link
Contributor

Fixes #7254

@ivovandongen ivovandongen added Core The cross-platform C++ core, aka mbgl ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold labels Dec 1, 2016
@ivovandongen ivovandongen self-assigned this Dec 1, 2016
@mention-bot
Copy link

@ivovandongen, thanks for your PR! By analyzing this pull request, we identified @jfirebaugh, @boundsj and @tmpsantos to be potential reviewers.

@ivovandongen ivovandongen removed the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Dec 1, 2016
@ivovandongen
Copy link
Contributor Author

cc @1ec5 @jfirebaugh

@@ -190,7 +190,11 @@ - (void)addLayer:(MGLStyleLayer *)layer
layer];
}

self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer));
try {
self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer));
Copy link
Contributor

@1ec5 1ec5 Dec 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the other addLayer() call in this class? (There’s also one in MGLMapView.mm, but that’ll go away as part of #7250.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added (tests) for MGLStyle#insertLayer and and MGLMapView#insertCustomStyleLayerWithIdentifier.

try {
self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer));
} catch (std::runtime_error & err) {
[NSException raise:@"Could not add layer" format:@"%s", err.what()];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reminds me that we need to be more disciplined about exception names in the SDK: #7258. (Not required for this PR.)

@@ -0,0 +1,25 @@
#import "MGLMapViewTests.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this file isn’t specific to iOS, it should live in platform/darwin/test/ and also be included in macos.xcodeproj. (This is the theme of our contributing documentation, although we neglected to point out that tests should be shared too when possible.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the files and added to macos as well. Excluded the custom layer tests for macos as the header is ios specific. Also changed the source test according to #7203 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s fine; the custom style layer API is getting folded into the normal style layer API in #7250, so soon there won’t be anything extra to test.

@ivovandongen ivovandongen force-pushed the 7254-duplicate-layers branch 4 times, most recently from 1008bbe to 89bfd97 Compare December 1, 2016 14:14
Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Once we merge release-ios-v3.4.0 back to master, the particular call sites you’re wrapping in try-catch blocks will be replaced by new call sites in MGLStyle and the various MGLStyleLayer classes, due to #6793, #6793, #6097, and #7250. So we’ll need to be vigilant with that merge.

/cc @boundsj

MGLCustomStyleLayerPreparationHandler preparationHandler = ^{};
MGLCustomStyleLayerDrawingHandler drawingHandler = ^(CGSize size, CLLocationCoordinate2D centerCoordinate, double zoomLevel, CLLocationDirection direction, CGFloat pitch, CGFloat perspectiveSkew) {
};
MGLCustomStyleLayerCompletionHandler completionHander = ^{};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, feel free to inline these blocks into the method call. Long lines are par for the course in Objective-C. 😉

@1ec5
Copy link
Contributor

1ec5 commented Dec 1, 2016

The iOS test failure appears to be what I fixed in #7228 on the release-ios-v3.4.0 branch.

@ivovandongen
Copy link
Contributor Author

The iOS test failure appears to be what I fixed in #7228 on the release-ios-v3.4.0 branch.

@1ec5 Could you merge this into master so I can rebase this pr on it?

@@ -211,7 +215,11 @@ - (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLaye
}

const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer), belowLayerId);
try {
self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer), belowLayerId);
Copy link
Contributor

@1ec5 1ec5 Dec 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that #7282 has landed – including the changes in #6793, #6793, #6097, and #7250 – you’ll need to wrap any call to -[MGLStyleLayer addToMapView:] in this try-catch block or alternatively move this try-catch block to every implementation of -addToMapView: in the concrete subclasses of MGLStyleLayer.

@ivovandongen ivovandongen force-pushed the 7254-duplicate-layers branch 2 times, most recently from 04cbd5b to c005962 Compare December 6, 2016 10:53
@ivovandongen
Copy link
Contributor Author

@1ec5 I've rebased and updated the ios handling/tests: c005962

Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once #7250 lands, we’ll want to push these try-catch blocks into -addToMapView:belowLayer: and -removeFromMapView:, and the separate code path for custom layers will go away, but this is the best we can do for now.

MGLDrawCustomStyleLayer, MGLFinishCustomStyleLayer, context),
otherIdentifier ? mbgl::optional<std::string>(otherIdentifier.UTF8String) : mbgl::optional<std::string>());
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentiferException" format:@"%s", err.what()];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized we’ve been saying “identifer” instead of “identifier”, both for layers and sources. I can fix that typo in a separate PR, since we also need to add a note to the documentation for the affected methods about MGLRedundantLayerIdentifierException (prior art involving sources).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you’re in a good spot to do it, can you rename MGLRedundantLayerIdentiferException to MGLRedundantLayerIdentiferException? I don’t think we have any instances of it in the release branch, so this is a good branch to do it in. I can take care of MGLRedundantSourceIdentiferException separately: #7314.

@ivovandongen
Copy link
Contributor Author

@kkaefer I've added the backend guard in 3f0c6c8 as you suggested and made activate/deactivate protected.

[layer addToMapView:self.mapView];
try {
[layer addToMapView:self.mapView];
} catch (std::runtime_error & err) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're catching a generic exception here, but always forward a MGLRedundantLayerIdentifierException. What we should do long term is to convert all of the generic std::runtime_error into individual exception types, and to exception-specific catches that we can then forward.

@@ -198,6 +198,16 @@ Layer* Style::getLayer(const std::string& id) const {
Layer* Style::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
// TODO: verify source

//Guard against duplicate layer ids
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code style is to have a space after //.


if (it != layers.end()) {
std::string msg = "Layer " + layer->getID() + " already exists";
throw std::runtime_error(msg.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to to c_str() here; std::runtime_error also accepts std::string. You could change this to something like this;

throw std::runtime_error(std::string{"Layer "} + layer->getID() + " already exists");

style.addLayer(std::make_unique<LineLayer>("line", "unusedsource"));
FAIL() << "Should not have been allowed to add a duplicate layer id";
} catch (std::runtime_error) {
//Expected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check message here

try {
style.addLayer(std::make_unique<LineLayer>("line", "unusedsource"));
FAIL() << "Should not have been allowed to add a duplicate layer id";
} catch (std::runtime_error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rule for exceptions in C++ is to throw by value and catch a const reference

[styleLayer addToMapView:self.mapView];
try {
[styleLayer addToMapView:self.mapView];
} catch (std::runtime_error & err) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const

XCTAssertThrowsSpecificNamed([self.mapView.style insertLayer:[[MGLFillStyleLayer alloc] initWithIdentifier:@"my-layer" source:source] aboveLayer:initial], NSException, @"MGLRedundantLayerIdentifierException");
XCTAssertThrowsSpecificNamed([self.mapView.style insertLayer:[[MGLFillStyleLayer alloc] initWithIdentifier:@"my-layer" source:source] atIndex:0], NSException, @"MGLRedundantLayerIdentifierException");

#if TARGET_OS_IPHONE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Macros are not indented

@ivovandongen
Copy link
Contributor Author

@kkaefer Thanks for the review, I've addressed your notes.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants