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.
91 lines
2.7 KiB
Plaintext
91 lines
2.7 KiB
Plaintext
#import "MGLRasterSource.h"
|
|
|
|
#import "MGLMapView_Private.h"
|
|
#import "MGLSource_Private.h"
|
|
#import "MGLTileSet_Private.h"
|
|
#import "NSURL+MGLAdditions.h"
|
|
|
|
#include <mbgl/style/sources/raster_source.hpp>
|
|
|
|
@interface MGLRasterSource ()
|
|
|
|
@property (nonatomic) mbgl::style::RasterSource *rawSource;
|
|
|
|
@end
|
|
|
|
@implementation MGLRasterSource
|
|
{
|
|
std::unique_ptr<mbgl::style::RasterSource> _pendingSource;
|
|
}
|
|
|
|
- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url tileSize:(CGFloat)tileSize
|
|
{
|
|
if (self = [super initWithIdentifier:identifier]) {
|
|
_URL = url;
|
|
_tileSize = tileSize;
|
|
[self commonInit];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (instancetype)initWithIdentifier:(NSString *)identifier tileSet:(MGLTileSet *)tileSet tileSize:(CGFloat)tileSize;
|
|
{
|
|
if (self = [super initWithIdentifier:identifier])
|
|
{
|
|
_tileSet = tileSet;
|
|
_tileSize = tileSize;
|
|
[self commonInit];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)commonInit
|
|
{
|
|
std::unique_ptr<mbgl::style::RasterSource> source;
|
|
|
|
if (self.URL)
|
|
{
|
|
source = std::make_unique<mbgl::style::RasterSource>(self.identifier.UTF8String,
|
|
self.URL.mgl_URLByStandardizingScheme.absoluteString.UTF8String,
|
|
uint16_t(self.tileSize));
|
|
}
|
|
else
|
|
{
|
|
source = std::make_unique<mbgl::style::RasterSource>(self.identifier.UTF8String,
|
|
self.tileSet.mbglTileset,
|
|
uint16_t(self.tileSize));
|
|
}
|
|
|
|
_pendingSource = std::move(source);
|
|
self.rawSource = _pendingSource.get();
|
|
}
|
|
|
|
- (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));
|
|
}
|
|
|
|
- (void)removeFromMapView:(MGLMapView *)mapView
|
|
{
|
|
auto removedSource = mapView.mbglMap->removeSource(self.identifier.UTF8String);
|
|
|
|
_pendingSource = std::move(reinterpret_cast<std::unique_ptr<mbgl::style::RasterSource> &>(removedSource));
|
|
self.rawSource = _pendingSource.get();
|
|
}
|
|
|
|
- (NSString *)description
|
|
{
|
|
return [NSString stringWithFormat:
|
|
@"<%@: %p; identifier = %@; URL = %@; tileSet = %@; tileSize = %lu>",
|
|
NSStringFromClass([self class]), (void *)self, self.identifier, self.URL,
|
|
self.tileSet, (unsigned long)self.tileSize];
|
|
}
|
|
|
|
@end
|