From 1c9d314236736bf47e33fb95d2b457a5650fc519 Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Mon, 14 Nov 2016 15:50:33 -0800 Subject: [PATCH] [ios, macos] Take back source and layer ownership on removal (#7048) If a source or layer is removed from the style, recapture the unique pointer ownership. This makes it safe to add back sources and layers after they have been removed. --- .../darwin/src/MGLBackgroundStyleLayer.mm | 42 +++++++++++-------- platform/darwin/src/MGLCircleStyleLayer.mm | 42 +++++++++++-------- platform/darwin/src/MGLFillStyleLayer.mm | 42 +++++++++++-------- platform/darwin/src/MGLGeoJSONSource.mm | 8 ++++ platform/darwin/src/MGLLineStyleLayer.mm | 42 +++++++++++-------- platform/darwin/src/MGLRasterSource.mm | 8 ++++ platform/darwin/src/MGLRasterStyleLayer.mm | 42 +++++++++++-------- platform/darwin/src/MGLSource_Private.h | 9 ++++ platform/darwin/src/MGLStyle.mm | 9 +--- platform/darwin/src/MGLStyleLayer.mm.ejs | 42 +++++++++++-------- platform/darwin/src/MGLStyleLayer_Private.h | 11 ++++- platform/darwin/src/MGLSymbolStyleLayer.mm | 42 +++++++++++-------- platform/darwin/src/MGLVectorSource.mm | 8 ++++ 13 files changed, 219 insertions(+), 128 deletions(-) diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm index 38c97e8d4..a4914d324 100644 --- a/platform/darwin/src/MGLBackgroundStyleLayer.mm +++ b/platform/darwin/src/MGLBackgroundStyleLayer.mm @@ -32,6 +32,31 @@ } + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_cast &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + #pragma mark - Accessing the Paint Attributes - (void)setBackgroundColor:(MGLStyleValue *)backgroundColor { @@ -65,21 +90,4 @@ } -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm index 13eedf3f9..13262a8c9 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ b/platform/darwin/src/MGLCircleStyleLayer.mm @@ -53,6 +53,31 @@ return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; } + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_cast &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + #pragma mark - Accessing the Paint Attributes - (void)setCircleRadius:(MGLStyleValue *)circleRadius { @@ -126,21 +151,4 @@ } -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm index 1f8b7402d..5aed779c8 100644 --- a/platform/darwin/src/MGLFillStyleLayer.mm +++ b/platform/darwin/src/MGLFillStyleLayer.mm @@ -53,6 +53,31 @@ return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; } + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_cast &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + #pragma mark - Accessing the Paint Attributes - (void)setFillAntialias:(MGLStyleValue *)fillAntialias { @@ -126,21 +151,4 @@ } -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLGeoJSONSource.mm b/platform/darwin/src/MGLGeoJSONSource.mm index 0dbe1030c..0213b6a27 100644 --- a/platform/darwin/src/MGLGeoJSONSource.mm +++ b/platform/darwin/src/MGLGeoJSONSource.mm @@ -64,6 +64,14 @@ const MGLGeoJSONSourceOption MGLGeoJSONSourceOptionSimplificationTolerance = @"M mapView.mbglMap->addSource(std::move(_pendingSource)); } +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String); + + _pendingSource = std::move(reinterpret_cast &>(removedSource)); + self.rawSource = _pendingSource.get(); +} + - (void)commonInit { auto source = std::make_unique(self.identifier.UTF8String, self.geoJSONOptions); diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm index aa699ea37..c7509e287 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -53,6 +53,31 @@ return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; } + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_cast &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + #pragma mark - Accessing the Layout Attributes - (void)setLineCap:(MGLStyleValue *)lineCap { @@ -198,21 +223,4 @@ } -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLRasterSource.mm b/platform/darwin/src/MGLRasterSource.mm index fc47c2385..92494febf 100644 --- a/platform/darwin/src/MGLRasterSource.mm +++ b/platform/darwin/src/MGLRasterSource.mm @@ -65,4 +65,12 @@ mapView.mbglMap->addSource(std::move(_pendingSource)); } +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String); + + _pendingSource = std::move(reinterpret_cast &>(removedSource)); + self.rawSource = _pendingSource.get(); +} + @end diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm index ba1df40f9..063f5e338 100644 --- a/platform/darwin/src/MGLRasterStyleLayer.mm +++ b/platform/darwin/src/MGLRasterStyleLayer.mm @@ -32,6 +32,31 @@ } + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_cast &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + #pragma mark - Accessing the Paint Attributes - (void)setRasterOpacity:(MGLStyleValue *)rasterOpacity { @@ -105,21 +130,4 @@ } -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h index dff230ede..d360e71f3 100644 --- a/platform/darwin/src/MGLSource_Private.h +++ b/platform/darwin/src/MGLSource_Private.h @@ -28,4 +28,13 @@ */ - (void)addToMapView:(MGLMapView *)mapView; +/** + Removes the mbgl source that this object represents from the mbgl map. + + When a mbgl source is removed, ownership of the object is transferred back + to the `MGLSource` instance and the unique_ptr reference is valid again. It is + safe to add the source back to the style after it is removed. + */ +- (void)removeFromMapView:(MGLMapView *)mapView; + @end diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index d59194725..7e67273a3 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -168,7 +168,7 @@ static NSURL *MGLStyleURL_emerald; - (void)removeLayer:(MGLStyleLayer *)layer { - self.mapView.mbglMap->removeLayer(layer.identifier.UTF8String); + [layer removeFromMapView:self.mapView]; } - (void)addLayer:(MGLStyleLayer *)layer @@ -209,12 +209,7 @@ static NSURL *MGLStyleURL_emerald; - (void)removeSource:(MGLSource *)source { - self.mapView.mbglMap->removeSource(source.identifier.UTF8String); - - // Once a mbgl source is removed from the map, ownership does not return - // to the MGL source. Therefore, the rawSource pointer is set to NULL - // so that the implementation of MGL source can avoid using it again. - source.rawSource = NULL; + [source removeFromMapView:self.mapView]; } - (NS_ARRAY_OF(NSString *) *)styleClasses diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs index 48d013d48..d366a1955 100644 --- a/platform/darwin/src/MGLStyleLayer.mm.ejs +++ b/platform/darwin/src/MGLStyleLayer.mm.ejs @@ -73,6 +73,31 @@ } <% } -%> + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_castLayer> &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + <% if (layoutProperties.length) { -%> #pragma mark - Accessing the Layout Attributes @@ -106,21 +131,4 @@ <% } -%> <% } -%> -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h index f61630b8c..bfce452a4 100644 --- a/platform/darwin/src/MGLStyleLayer_Private.h +++ b/platform/darwin/src/MGLStyleLayer_Private.h @@ -29,11 +29,18 @@ */ - (void)addToMapView:(MGLMapView *)mapView; - +/** + Removes the mbgl style layer that this object represents from the mbgl map. + + When a mbgl style layer is removed, ownership of the object is transferred back + to the `MGLStyleLayer` instance and the unique_ptr reference is valid again. It + is safe to add the layer back to the style after it is removed. + */ +- (void)removeFromMapView:(MGLMapView *)mapView; /** Adds the mbgl style layer that this object represents to the mbgl map below the specified `otherLayer`. - + Once a mbgl style layer is added, ownership of the object is transferred to the `mbgl::Map` and this object no longer has an active unique_ptr reference to the `mbgl::style::Layer`. diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index 539e0f2cc..082743be5 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -53,6 +53,31 @@ return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; } + +#pragma mark - Adding to and removing from a map view + +- (void)addToMapView:(MGLMapView *)mapView +{ + [self addToMapView:mapView belowLayer:nil]; +} + +- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +{ + if (otherLayer) { + const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; + mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + } else { + mapView.mbglMap->addLayer(std::move(_pendingLayer)); + } +} + +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + _pendingLayer = std::move(reinterpret_cast &>(removedLayer)); + self.rawLayer = _pendingLayer.get(); +} + #pragma mark - Accessing the Layout Attributes - (void)setSymbolPlacement:(MGLStyleValue *)symbolPlacement { @@ -538,21 +563,4 @@ } -#pragma mark - Add style layer to map - -- (void)addToMapView:(MGLMapView *)mapView -{ - [self addToMapView:mapView belowLayer:nil]; -} - -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer -{ - if (otherLayer) { - const mbgl::optional belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); - } -} - @end diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm index 995565419..2c7b529d7 100644 --- a/platform/darwin/src/MGLVectorSource.mm +++ b/platform/darwin/src/MGLVectorSource.mm @@ -64,4 +64,12 @@ static NSString *MGLVectorSourceType = @"vector"; mapView.mbglMap->addSource(std::move(_pendingSource)); } +- (void)removeFromMapView:(MGLMapView *)mapView +{ + auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String); + + _pendingSource = std::move(reinterpret_cast &>(removedSource)); + self.rawSource = _pendingSource.get(); +} + @end