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:
John Firebaugh
2015-06-17 14:08:40 -07:00
parent 0581df8787
commit fd58861fcd
6 changed files with 31 additions and 22 deletions

View File

@@ -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>()) {

View File

@@ -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()) {

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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());