[ios, macos] Raise NSException if layer or source added more than once
When MGLSource and MGLLayer instances are added to the style, they lose ownership of their std::unique_ptr<T> after it is moved to the mbgl level. Subsequent attempts to add such instances result in a C++ exception. This adds logic in the Darwin platform to raise a NSException if the source and layer addToMapView methods are called more than once and the pointer is invalid. In addition, the documentation in MGLStyle for addSource: and addLayer: has been update to warn developers to avoid adding the same instance twice and, for that matter, instances with the same identifier.
This commit is contained in:
@@ -35,6 +35,12 @@
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,12 @@ namespace mbgl {
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,12 @@ namespace mbgl {
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionSimplificationTolerance = @"M
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingSource == nullptr) {
|
||||
[NSException raise:@"MGLRedundantSourceException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same source instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
mapView.mbglMap->addSource(std::move(_pendingSource));
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,12 @@ namespace mbgl {
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,12 @@
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingSource == nullptr) {
|
||||
[NSException raise:@"MGLRedundantSourceException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same source instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
mapView.mbglMap->addSource(std::move(_pendingSource));
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
|
||||
/**
|
||||
Adds a new source to the current style.
|
||||
|
||||
@note Adding the same source instance more than once or reusing source
|
||||
identifers in the sources you add will trigger exceptions.
|
||||
|
||||
@param source The source to add to the current style.
|
||||
*/
|
||||
- (void)addSource:(MGLSource *)source;
|
||||
@@ -247,6 +250,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
|
||||
/**
|
||||
Adds a new layer on top of existing layers.
|
||||
|
||||
@note Adding the same layer instance more than once or reusing layer
|
||||
identifers in the layers you add will trigger exceptions.
|
||||
|
||||
@param layer The layer object to add to the map view. This object must be an
|
||||
instance of a concrete subclass of `MGLStyleLayer`.
|
||||
*/
|
||||
@@ -255,6 +261,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
|
||||
/**
|
||||
Inserts a new layer into the style at the given index.
|
||||
|
||||
@note Adding the same layer instance more than once or reusing layer
|
||||
identifers in the layers you add will trigger exceptions.
|
||||
|
||||
@param layer The layer to insert.
|
||||
@param index The index at which to insert the layer. An index of 0 would send
|
||||
the layer to the back; an index equal to the number of objects in the
|
||||
@@ -272,6 +281,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
|
||||
inspectable in Interface Builder, or a manually constructed `NSURL`. This
|
||||
approach also avoids layer identifer name changes that will occur in the default
|
||||
style’s layers over time.
|
||||
|
||||
Adding the same layer instance more than once or reusing layer identifers in
|
||||
the layers you add will trigger exceptions.
|
||||
|
||||
@param layer The layer to insert.
|
||||
@param sibling An existing layer in the style.
|
||||
@@ -288,6 +300,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
|
||||
inspectable in Interface Builder, or a manually constructed `NSURL`. This
|
||||
approach also avoids layer identifer name changes that will occur in the default
|
||||
style’s layers over time.
|
||||
|
||||
Adding the same layer instance more than once or reusing layer identifers in
|
||||
the layers you add will trigger exceptions.
|
||||
|
||||
@param layer The layer to insert.
|
||||
@param sibling An existing layer in the style.
|
||||
|
||||
@@ -112,6 +112,12 @@ namespace mbgl {
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -129,6 +129,12 @@ namespace mbgl {
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingLayer == nullptr) {
|
||||
[NSException raise:@"MGLRedundantLayerException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same layer instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
[self addToMapView:mapView belowLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,12 @@
|
||||
|
||||
- (void)addToMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (_pendingSource == nullptr) {
|
||||
[NSException raise:@"MGLRedundantSourceException"
|
||||
format:@"This instance %@ was already added to %@. Adding the same source instance " \
|
||||
"to the style more than once is invalid.", self, mapView.style];
|
||||
}
|
||||
|
||||
mapView.mbglMap->addSource(std::move(_pendingSource));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
#import "MGLStyle.h"
|
||||
#import "MGLMapView.h"
|
||||
#import "MGLStyle_Private.h"
|
||||
|
||||
#import "MGLGeoJSONSource.h"
|
||||
#import "MGLRasterSource.h"
|
||||
#import "MGLVectorSource.h"
|
||||
|
||||
#import "MGLBackgroundStyleLayer.h"
|
||||
#import "MGLCircleStyleLayer.h"
|
||||
#import "MGLFillStyleLayer.h"
|
||||
#import "MGLLineStyleLayer.h"
|
||||
#import "MGLRasterStyleLayer.h"
|
||||
#import "MGLSymbolStyleLayer.h"
|
||||
|
||||
#import "NSBundle+MGLAdditions.h"
|
||||
|
||||
@@ -92,6 +104,53 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)testAddingSourcesTwice {
|
||||
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
MGLStyle *style = [[MGLStyle alloc] initWithMapView:mapView];
|
||||
|
||||
MGLGeoJSONSource *geoJSONSource = [[MGLGeoJSONSource alloc] initWithIdentifier:@"geoJSONSource" features:@[] options:nil];
|
||||
[style addSource:geoJSONSource];
|
||||
XCTAssertThrowsSpecificNamed([style addSource:geoJSONSource], NSException, @"MGLRedundantSourceException");
|
||||
|
||||
MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"rasterSource" URL:[NSURL new] tileSize:42];
|
||||
[style addSource:rasterSource];
|
||||
XCTAssertThrowsSpecificNamed([style addSource:rasterSource], NSException, @"MGLRedundantSourceException");
|
||||
|
||||
MGLVectorSource *vectorSource = [[MGLVectorSource alloc] initWithIdentifier:@"vectorSource" URL:[NSURL new]];
|
||||
[style addSource:vectorSource];
|
||||
XCTAssertThrowsSpecificNamed([style addSource:vectorSource], NSException, @"MGLRedundantSourceException");
|
||||
}
|
||||
|
||||
- (void)testAddingLayersTwice {
|
||||
MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
|
||||
MGLStyle *style = [[MGLStyle alloc] initWithMapView:mapView];
|
||||
MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"geoJSONSource" features:@[] options:nil];
|
||||
|
||||
MGLBackgroundStyleLayer *backgroundLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:@"backgroundLayer"];
|
||||
[style addLayer:backgroundLayer];
|
||||
XCTAssertThrowsSpecificNamed([style addLayer:backgroundLayer], NSException, @"MGLRedundantLayerException");
|
||||
|
||||
MGLCircleStyleLayer *circleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"circleLayer" source:source];
|
||||
[style addLayer:circleLayer];
|
||||
XCTAssertThrowsSpecificNamed([style addLayer:circleLayer], NSException, @"MGLRedundantLayerException");
|
||||
|
||||
MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:source];
|
||||
[style addLayer:fillLayer];
|
||||
XCTAssertThrowsSpecificNamed([style addLayer:fillLayer], NSException, @"MGLRedundantLayerException");
|
||||
|
||||
MGLLineStyleLayer *lineLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"lineLayer" source:source];
|
||||
[style addLayer:lineLayer];
|
||||
XCTAssertThrowsSpecificNamed([style addLayer:lineLayer], NSException, @"MGLRedundantLayerException");
|
||||
|
||||
MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"rasterLayer" source:source];
|
||||
[style addLayer:rasterLayer];
|
||||
XCTAssertThrowsSpecificNamed([style addLayer:rasterLayer], NSException, @"MGLRedundantLayerException");
|
||||
|
||||
MGLSymbolStyleLayer *symbolLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"symbolLayer" source:source];
|
||||
[style addLayer:symbolLayer];
|
||||
XCTAssertThrowsSpecificNamed([style addLayer:symbolLayer], NSException, @"MGLRedundantLayerException");
|
||||
}
|
||||
|
||||
- (NSString *)stringWithContentsOfStyleHeader {
|
||||
NSURL *styleHeaderURL = [[[NSBundle mgl_frameworkBundle].bundleURL
|
||||
URLByAppendingPathComponent:@"Headers" isDirectory:YES]
|
||||
|
||||
Reference in New Issue
Block a user