Change StyleBucket::source to indirect reference
This eliminates a reference loop: VectorTileData holds StyleLayers which hold StyleBuckets which held Sources which hold VectorTileDatas. This breaks the StyleBucket -> Source link in favor of manually resolving the reference where necessary.
This commit is contained in:
@@ -139,13 +139,7 @@ void MapContext::updateAnnotationTiles(const std::unordered_set<TileID, TileID::
|
||||
|
||||
// grab existing, single shape annotations source
|
||||
const auto& shapeID = AnnotationManager::ShapeLayerID;
|
||||
|
||||
const auto source_it = std::find_if(style->sources.begin(), style->sources.end(),
|
||||
[&shapeID](util::ptr<Source> source) {
|
||||
return (source->info.source_id == shapeID);
|
||||
});
|
||||
assert(source_it != style->sources.end());
|
||||
source_it->get()->enabled = true;
|
||||
style->getSource(shapeID)->enabled = true;
|
||||
|
||||
// create (if necessary) layers and buckets for each shape
|
||||
for (const auto &shapeAnnotationID : data.annotationManager.getOrderedShapeAnnotations()) {
|
||||
@@ -202,8 +196,8 @@ void MapContext::updateAnnotationTiles(const std::unordered_set<TileID, TileID::
|
||||
// create shape bucket & connect to source
|
||||
util::ptr<StyleBucket> shapeBucket = std::make_shared<StyleBucket>(shapeLayer->type);
|
||||
shapeBucket->name = shapeLayer->id;
|
||||
shapeBucket->source = shapeID;
|
||||
shapeBucket->source_layer = shapeLayer->id;
|
||||
shapeBucket->source = *source_it;
|
||||
|
||||
// apply line layout properties to bucket
|
||||
if (shapeStyle.is<LineProperties>()) {
|
||||
|
||||
@@ -323,7 +323,8 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!layer.bucket->source) {
|
||||
util::ptr<Source> source = style.getSource(layer.bucket->source);
|
||||
if (!source) {
|
||||
Log::Warning(Event::Render, "can't find source for layer '%s'", layer.id.c_str());
|
||||
continue;
|
||||
}
|
||||
@@ -345,7 +346,7 @@ std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {
|
||||
// Determine what render passes we need for this layer.
|
||||
const RenderPass passes = determineRenderPasses(layer);
|
||||
|
||||
const auto& tiles = layer.bucket->source->getTiles();
|
||||
const auto& tiles = source->getTiles();
|
||||
for (auto tile : tiles) {
|
||||
assert(tile);
|
||||
if (!tile->data && !tile->data->isReady()) {
|
||||
|
||||
@@ -110,12 +110,27 @@ void Style::recalculate(float z, TimePoint now) {
|
||||
|
||||
for (const auto& layer : layers) {
|
||||
layer->updateProperties(z, now, zoomHistory);
|
||||
if (layer->bucket && layer->bucket->source) {
|
||||
layer->bucket->source->enabled = true;
|
||||
if (!layer->bucket) {
|
||||
continue;
|
||||
}
|
||||
|
||||
util::ptr<Source> source = getSource(layer->bucket->source);
|
||||
if (!source) {
|
||||
continue;
|
||||
}
|
||||
|
||||
source->enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
util::ptr<Source> Style::getSource(const std::string& id) const {
|
||||
const auto it = std::find_if(sources.begin(), sources.end(), [&](util::ptr<Source> source) {
|
||||
return source->info.source_id == id;
|
||||
});
|
||||
|
||||
return it != sources.end() ? *it : nullptr;
|
||||
}
|
||||
|
||||
void Style::setDefaultTransitionDuration(Duration duration) {
|
||||
defaultTransition.duration = duration;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ public:
|
||||
return lastError;
|
||||
}
|
||||
|
||||
util::ptr<Source> getSource(const std::string& id) const;
|
||||
|
||||
std::unique_ptr<GlyphStore> glyphStore;
|
||||
std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Source;
|
||||
|
||||
class StyleBucket : public util::noncopyable {
|
||||
public:
|
||||
typedef util::ptr<StyleBucket> Ptr;
|
||||
@@ -20,7 +18,7 @@ public:
|
||||
|
||||
const StyleLayerType type;
|
||||
std::string name;
|
||||
util::ptr<Source> source;
|
||||
std::string source;
|
||||
std::string source_layer;
|
||||
FilterExpression filter;
|
||||
ClassProperties layout;
|
||||
|
||||
@@ -57,6 +57,7 @@ void StyleParser::parse(JSVal document) {
|
||||
// create point annotations symbol bucket
|
||||
util::ptr<StyleBucket> pointBucket = std::make_shared<StyleBucket>(pointAnnotationsLayer->type);
|
||||
pointBucket->name = pointAnnotationsLayer->id;
|
||||
pointBucket->source = pointID;
|
||||
pointBucket->source_layer = pointAnnotationsLayer->id;
|
||||
|
||||
// build up point annotations style
|
||||
@@ -74,7 +75,6 @@ void StyleParser::parse(JSVal document) {
|
||||
sources.emplace_back(pointAnnotationsSource);
|
||||
pointAnnotationsSource->info.type = SourceType::Annotations;
|
||||
pointAnnotationsSource->info.source_id = pointID;
|
||||
pointBucket->source = pointAnnotationsSource;
|
||||
pointAnnotationsLayer->bucket = pointBucket;
|
||||
}
|
||||
|
||||
@@ -231,6 +231,7 @@ void StyleParser::parseSources(JSVal value) {
|
||||
parseRenderProperty<SourceTypeClass>(itr->value, source->info.type, "type");
|
||||
parseRenderProperty(itr->value, source->info.url, "url");
|
||||
parseRenderProperty(itr->value, source->info.tile_size, "tileSize");
|
||||
source->info.source_id = name;
|
||||
source->info.parseTileJSONProperties(itr->value);
|
||||
sources.emplace_back(source);
|
||||
sourcesMap.emplace(name, source);
|
||||
@@ -947,12 +948,10 @@ void StyleParser::parseBucket(JSVal value, util::ptr<StyleLayer> &layer) {
|
||||
if (value.HasMember("source")) {
|
||||
JSVal value_source = replaceConstant(value["source"]);
|
||||
if (value_source.IsString()) {
|
||||
const std::string source_name = { value_source.GetString(), value_source.GetStringLength() };
|
||||
auto source_it = sourcesMap.find(source_name);
|
||||
if (source_it != sourcesMap.end()) {
|
||||
bucket->source = source_it->second;
|
||||
} else {
|
||||
Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", source_name.c_str(), layer->id.c_str());
|
||||
bucket->source = { value_source.GetString(), value_source.GetStringLength() };
|
||||
auto source_it = sourcesMap.find(bucket->source);
|
||||
if (source_it == sourcesMap.end()) {
|
||||
Log::Warning(Event::ParseStyle, "can't find source '%s' required for layer '%s'", bucket->source.c_str(), layer->id.c_str());
|
||||
}
|
||||
} else {
|
||||
Log::Warning(Event::ParseStyle, "source of layer '%s' must be a string", layer->id.c_str());
|
||||
|
||||
Reference in New Issue
Block a user