summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2017-04-04 11:33:22 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2017-04-13 10:33:18 -0700
commit7b041b123cb067d247a727bb3a4563bb2fc575eb (patch)
treecdf9ce1583ef6cc3a16970a7ad9a1527521ecf41 /platform
parentde6c9b35f35f6ec0950529261b207d716c046beb (diff)
downloadqtlocation-mapboxgl-7b041b123cb067d247a727bb3a4563bb2fc575eb.tar.gz
[core, darwin] Object identity for MGLSource*, MGLStyleLayer*
All `MGLSource` pointers referencing the same logical source will now be object identical; similarly for `MGLStyleLayer`.
Diffstat (limited to 'platform')
-rw-r--r--platform/darwin/src/MGLSource.mm1
-rw-r--r--platform/darwin/src/MGLSource_Private.h8
-rw-r--r--platform/darwin/src/MGLStyle.mm41
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm1
-rw-r--r--platform/darwin/src/MGLStyleLayer_Private.h8
-rw-r--r--platform/darwin/test/MGLStyleTests.mm2
6 files changed, 41 insertions, 20 deletions
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index 1940db688c..59c2ae13e6 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -29,6 +29,7 @@
NSString *identifier = @(rawSource->getID().c_str());
if (self = [self initWithIdentifier:identifier]) {
_rawSource = rawSource;
+ _rawSource->peer = SourceWrapper { self };
}
return self;
}
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index 2fc170b86b..6f86e4800b 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -10,6 +10,14 @@ namespace mbgl {
}
}
+// A struct to be stored in the `peer` member of mbgl::style::Source, in order to implement
+// object identity. We don't store a MGLSource pointer directly because that doesn't
+// interoperate with ARC. The inner pointer is weak in order to avoid a reference cycle for
+// "pending" MGLSources, which have a strong owning pointer to the mbgl::style::Source.
+struct SourceWrapper {
+ __weak MGLSource *source;
+};
+
@class MGLMapView;
@interface MGLSource (Private)
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 83ff73e8f9..b01d9aa513 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -166,17 +166,21 @@ static NSURL *MGLStyleURL_emerald;
return rawSource ? [self sourceFromMBGLSource:rawSource] : nil;
}
-- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)source {
+- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)rawSource {
+ if (MGLSource *source = rawSource->peer.empty() ? nil : mbgl::any_cast<SourceWrapper>(rawSource->peer).source) {
+ return source;
+ }
+
// TODO: Fill in options specific to the respective source classes
// https://github.com/mapbox/mapbox-gl-native/issues/6584
- if (auto vectorSource = source->as<mbgl::style::VectorSource>()) {
+ if (auto vectorSource = rawSource->as<mbgl::style::VectorSource>()) {
return [[MGLVectorSource alloc] initWithRawSource:vectorSource];
- } else if (auto geoJSONSource = source->as<mbgl::style::GeoJSONSource>()) {
+ } else if (auto geoJSONSource = rawSource->as<mbgl::style::GeoJSONSource>()) {
return [[MGLShapeSource alloc] initWithRawSource:geoJSONSource];
- } else if (auto rasterSource = source->as<mbgl::style::RasterSource>()) {
+ } else if (auto rasterSource = rawSource->as<mbgl::style::RasterSource>()) {
return [[MGLRasterSource alloc] initWithRawSource:rasterSource];
} else {
- return [[MGLSource alloc] initWithRawSource:source];
+ return [[MGLSource alloc] initWithRawSource:rawSource];
}
}
@@ -319,35 +323,32 @@ static NSURL *MGLStyleURL_emerald;
[styleLayer removeFromMapView:self.mapView];
}
-- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)mbglLayer
+- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)rawLayer
{
- NSParameterAssert(mbglLayer);
+ NSParameterAssert(rawLayer);
- NSString *identifier = @(mbglLayer->getID().c_str());
+ if (MGLStyleLayer *layer = rawLayer->peer.empty() ? nil : mbgl::any_cast<LayerWrapper>(rawLayer->peer).layer) {
+ return layer;
+ }
- if (auto fillLayer = mbglLayer->as<mbgl::style::FillLayer>()) {
+ if (auto fillLayer = rawLayer->as<mbgl::style::FillLayer>()) {
MGLSource *source = [self sourceWithIdentifier:@(fillLayer->getSourceID().c_str())];
return [[MGLFillStyleLayer alloc] initWithRawLayer:fillLayer source:source];
- } else if (auto lineLayer = mbglLayer->as<mbgl::style::LineLayer>()) {
+ } else if (auto lineLayer = rawLayer->as<mbgl::style::LineLayer>()) {
MGLSource *source = [self sourceWithIdentifier:@(lineLayer->getSourceID().c_str())];
return [[MGLLineStyleLayer alloc] initWithRawLayer:lineLayer source:source];
- } else if (auto symbolLayer = mbglLayer->as<mbgl::style::SymbolLayer>()) {
+ } else if (auto symbolLayer = rawLayer->as<mbgl::style::SymbolLayer>()) {
MGLSource *source = [self sourceWithIdentifier:@(symbolLayer->getSourceID().c_str())];
return [[MGLSymbolStyleLayer alloc] initWithRawLayer:symbolLayer source:source];
- } else if (auto rasterLayer = mbglLayer->as<mbgl::style::RasterLayer>()) {
+ } else if (auto rasterLayer = rawLayer->as<mbgl::style::RasterLayer>()) {
MGLSource *source = [self sourceWithIdentifier:@(rasterLayer->getSourceID().c_str())];
return [[MGLRasterStyleLayer alloc] initWithRawLayer:rasterLayer source:source];
- } else if (auto circleLayer = mbglLayer->as<mbgl::style::CircleLayer>()) {
+ } else if (auto circleLayer = rawLayer->as<mbgl::style::CircleLayer>()) {
MGLSource *source = [self sourceWithIdentifier:@(circleLayer->getSourceID().c_str())];
return [[MGLCircleStyleLayer alloc] initWithRawLayer:circleLayer source:source];
- } else if (auto backgroundLayer = mbglLayer->as<mbgl::style::BackgroundLayer>()) {
+ } else if (auto backgroundLayer = rawLayer->as<mbgl::style::BackgroundLayer>()) {
return [[MGLBackgroundStyleLayer alloc] initWithRawLayer:backgroundLayer];
- } else if (auto customLayer = mbglLayer->as<mbgl::style::CustomLayer>()) {
- MGLStyleLayer *styleLayer = self.openGLLayers[identifier];
- if (styleLayer) {
- NSAssert(styleLayer.rawLayer == customLayer, @"%@ wraps a CustomLayer that differs from the one associated with the underlying style.", styleLayer);
- return styleLayer;
- }
+ } else if (auto customLayer = rawLayer->as<mbgl::style::CustomLayer>()) {
return [[MGLOpenGLStyleLayer alloc] initWithRawLayer:customLayer];
} else {
NSAssert(NO, @"Unrecognized layer type");
diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm
index c72541526f..4bfaea934b 100644
--- a/platform/darwin/src/MGLStyleLayer.mm
+++ b/platform/darwin/src/MGLStyleLayer.mm
@@ -18,6 +18,7 @@
if (self = [super init]) {
_identifier = @(rawLayer->getID().c_str());
_rawLayer = rawLayer;
+ _rawLayer->peer = LayerWrapper { self };
}
return self;
}
diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h
index d024a0bb13..ed8ec31755 100644
--- a/platform/darwin/src/MGLStyleLayer_Private.h
+++ b/platform/darwin/src/MGLStyleLayer_Private.h
@@ -7,6 +7,14 @@
NS_ASSUME_NONNULL_BEGIN
+// A struct to be stored in the `peer` member of mbgl::style::Layer, in order to implement
+// object identity. We don't store a MGLStyleLayer pointer directly because that doesn't
+// interoperate with ARC. The inner pointer is weak in order to avoid a reference cycle for
+// "pending" MGLStyleLayers, which have a strong owning pointer to the mbgl::style::Layer.
+struct LayerWrapper {
+ __weak MGLStyleLayer *layer;
+};
+
/**
Assert that the style layer is valid.
diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm
index 36772e556d..f9598a143d 100644
--- a/platform/darwin/test/MGLStyleTests.mm
+++ b/platform/darwin/test/MGLStyleTests.mm
@@ -148,6 +148,7 @@
MGLShapeSource *shapeSource = [[MGLShapeSource alloc] initWithIdentifier:@"shapeSource" shape:nil options:nil];
[self.style addSource:shapeSource];
XCTAssertEqual(self.style.sources.count, initialSources.count + 1);
+ XCTAssertEqual(shapeSource, [self.style sourceWithIdentifier:@"shapeSource"]);
[self.style removeSource:shapeSource];
XCTAssertEqual(self.style.sources.count, initialSources.count);
}
@@ -238,6 +239,7 @@
MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"fillLayer" source:shapeSource];
[self.style addLayer:fillLayer];
XCTAssertEqual(self.style.layers.count, initialLayers.count + 1);
+ XCTAssertEqual(fillLayer, [self.style layerWithIdentifier:@"fillLayer"]);
[self.style removeLayer:fillLayer];
XCTAssertEqual(self.style.layers.count, initialLayers.count);
}