This repository has been archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[core] Don't allow style mutations to be overwritten by revalidation #5753
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
6bbb2e4
[tests] Merge single test in set_style.cpp with other Map tests
jfirebaugh 5511e9a
[tests] Fix a subtle ordering bug in StubFileSource
jfirebaugh 86cccc4
[core] Don't allow style mutations to be overwritten by revalidation
jfirebaugh eb9fe89
[tests] Test that style mutations due to annotations don't cancel sty…
jfirebaugh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,6 +67,7 @@ class Map::Impl : public style::Observer { | |
|
||
std::string styleURL; | ||
std::string styleJSON; | ||
bool styleMutated = false; | ||
|
||
std::unique_ptr<AsyncRequest> styleRequest; | ||
|
||
|
@@ -293,10 +294,21 @@ void Map::setStyleURL(const std::string& url) { | |
impl->styleRequest = nullptr; | ||
impl->styleURL = url; | ||
impl->styleJSON.clear(); | ||
impl->styleMutated = false; | ||
|
||
impl->style = std::make_unique<Style>(impl->fileSource, impl->pixelRatio); | ||
|
||
impl->styleRequest = impl->fileSource.request(Resource::style(impl->styleURL), [this](Response res) { | ||
// Once we get a fresh style, or the style is mutated, stop revalidating. | ||
if (res.isFresh() || impl->styleMutated) { | ||
impl->styleRequest.reset(); | ||
} | ||
|
||
// Don't allow a loaded, mutated style to be overwritten with a new version. | ||
if (impl->styleMutated && impl->style->loaded) { | ||
return; | ||
} | ||
|
||
if (res.error) { | ||
if (res.error->reason == Response::Error::Reason::NotFound && | ||
util::mapbox::isMapboxURL(impl->styleURL)) { | ||
|
@@ -323,6 +335,8 @@ void Map::setStyleJSON(const std::string& json) { | |
|
||
impl->styleURL.clear(); | ||
impl->styleJSON.clear(); | ||
impl->styleMutated = false; | ||
|
||
impl->style = std::make_unique<Style>(impl->fileSource, impl->pixelRatio); | ||
|
||
impl->loadStyleJSON(json); | ||
|
@@ -746,22 +760,27 @@ AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) { | |
#pragma mark - Style API | ||
|
||
style::Source* Map::getSource(const std::string& sourceID) { | ||
impl->styleMutated = true; | ||
return impl->style ? impl->style->getSource(sourceID) : nullptr; | ||
} | ||
|
||
void Map::addSource(std::unique_ptr<style::Source> source) { | ||
impl->styleMutated = true; | ||
impl->style->addSource(std::move(source)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just realized that if checks for if the style is !null on the getters but not on the setters. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I opened #6121 as a followup issue for handling attempts to mutate an unloaded style. |
||
} | ||
|
||
void Map::removeSource(const std::string& sourceID) { | ||
impl->styleMutated = true; | ||
impl->style->removeSource(sourceID); | ||
} | ||
|
||
style::Layer* Map::getLayer(const std::string& layerID) { | ||
impl->styleMutated = true; | ||
return impl->style ? impl->style->getLayer(layerID) : nullptr; | ||
} | ||
|
||
void Map::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& before) { | ||
impl->styleMutated = true; | ||
impl->view.activate(); | ||
|
||
impl->style->addLayer(std::move(layer), before); | ||
|
@@ -772,6 +791,7 @@ void Map::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& be | |
} | ||
|
||
void Map::removeLayer(const std::string& id) { | ||
impl->styleMutated = true; | ||
impl->view.activate(); | ||
|
||
impl->style->removeLayer(id); | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#pragma once | ||
|
||
#include <mbgl/storage/file_source.hpp> | ||
|
||
#include <list> | ||
|
||
namespace mbgl { | ||
|
||
/* | ||
FakeFileSource is similar to StubFileSource, but it follows a post hoc, "push" model rather than | ||
a pre hoc, "pull" model. You pass it to code that makes requests, it records what requests are | ||
made, then you can examine them, make assertions about them, and respond as desired. | ||
|
||
This is particularly useful if you want to simulate multiple responses, e.g. as part of a resource | ||
revalidation flow. StubFileSource allows only a single response. | ||
*/ | ||
class FakeFileSource : public FileSource { | ||
public: | ||
class FakeFileRequest : public AsyncRequest { | ||
public: | ||
Resource resource; | ||
Callback callback; | ||
|
||
std::list<FakeFileRequest*>& list; | ||
std::list<FakeFileRequest*>::iterator link; | ||
|
||
FakeFileRequest(Resource resource_, Callback callback_, std::list<FakeFileRequest*>& list_) | ||
: resource(std::move(resource_)), | ||
callback(std::move(callback_)), | ||
list(list_), | ||
link((list.push_back(this), std::prev(list.end()))) { | ||
} | ||
|
||
~FakeFileRequest() override { | ||
list.erase(link); | ||
} | ||
}; | ||
|
||
std::unique_ptr<AsyncRequest> request(const Resource& resource, Callback callback) override { | ||
return std::make_unique<FakeFileRequest>(resource, callback, requests); | ||
} | ||
|
||
bool respond(Resource::Kind kind, const Response& response) { | ||
auto it = std::find_if(requests.begin(), requests.end(), [&] (FakeFileRequest* request) { | ||
return request->resource.kind == kind; | ||
}); | ||
|
||
if (it != requests.end()) { | ||
// Copy the callback, in case calling it deallocates the AsyncRequest. | ||
Callback callback_ = (*it)->callback; | ||
callback_(response); | ||
} | ||
|
||
return it != requests.end(); | ||
} | ||
|
||
std::list<FakeFileRequest*> requests; | ||
}; | ||
|
||
} // namespace mbgl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this to the
Style
object and have it keep track of whether it was mutated itself?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to do it that way, but the issue is that we want some style mutations to be excluded from this logic, specifically those that
AnnotationManager::updateStyle
performs. Adding annotations should not cancel the initial revalidation. (I'll add a test for this.)