[core] make forcing cache/network only more explicit

Previously, we used the existence of a `prior*` field in the Resource object as an indication for whether we should consult the cache or not. However, this is prone to error, since a failed cache lookup won't set any prior fields. Therefore, we manually set `priorExpires` to 0. This in turn triggered another bug where generated wrong expiration timestamps when the server response we got was expired (or expired between sending and receiving).

This commit changes the flags so that we can now explicitly request CacheOnly/NetworkOnly (or All) loading methods, rather than the implicit Optional/Required naming scheme.
This commit is contained in:
Konstantin Käfer
2017-10-09 12:59:27 +02:00
parent 56446c5d17
commit 78ea88d757
25 changed files with 284 additions and 251 deletions

View File

@@ -489,6 +489,7 @@ set(MBGL_CORE_FILES
# tile
include/mbgl/tile/tile_id.hpp
include/mbgl/tile/tile_necessity.hpp
src/mbgl/tile/geojson_tile.cpp
src/mbgl/tile/geojson_tile.hpp
src/mbgl/tile/geojson_tile_data.hpp

View File

@@ -34,7 +34,7 @@ public:
uint64_t maximumCacheSize = util::DEFAULT_MAX_CACHE_SIZE);
~DefaultFileSource() override;
bool supportsOptionalRequests() const override {
bool supportsCacheOnlyRequests() const override {
return true;
}

View File

@@ -24,11 +24,11 @@ public:
// not be executed.
virtual std::unique_ptr<AsyncRequest> request(const Resource&, Callback) = 0;
// When a file source supports optional requests, it must return true.
// Optional requests are requests that aren't as urgent, but could be useful, e.g.
// When a file source supports consulting a local cache only, it must return true.
// Cache-only requests are requests that aren't as urgent, but could be useful, e.g.
// to cover part of the map while loading. The FileSource should only do cheap actions to
// retrieve the data, e.g. load it from a cache, but not from the internet.
virtual bool supportsOptionalRequests() const {
virtual bool supportsCacheOnlyRequests() const {
return false;
}
};

View File

@@ -4,6 +4,8 @@
#include <mbgl/util/optional.hpp>
#include <mbgl/util/font_stack.hpp>
#include <mbgl/util/tileset.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/traits.hpp>
#include <string>
@@ -30,18 +32,28 @@ public:
int8_t z;
};
enum Necessity : bool {
Optional = false,
Required = true,
enum class LoadingMethod : uint8_t {
None = 0b00,
Cache = 0b01,
Network = 0b10,
CacheOnly = Cache,
NetworkOnly = Network,
All = Cache | Network,
};
Resource(Kind kind_, std::string url_, optional<TileData> tileData_ = {}, Necessity necessity_ = Required)
Resource(Kind kind_,
std::string url_,
optional<TileData> tileData_ = {},
LoadingMethod loadingMethod_ = LoadingMethod::All)
: kind(kind_),
necessity(necessity_),
loadingMethod(loadingMethod_),
url(std::move(url_)),
tileData(std::move(tileData_)) {
}
bool hasLoadingMethod(LoadingMethod method);
static Resource style(const std::string& url);
static Resource source(const std::string& url);
static Resource tile(const std::string& urlTemplate,
@@ -50,7 +62,7 @@ public:
int32_t y,
int8_t z,
Tileset::Scheme scheme,
Necessity = Required);
LoadingMethod = LoadingMethod::All);
static Resource glyphs(const std::string& urlTemplate,
const FontStack& fontStack,
const std::pair<uint16_t, uint16_t>& glyphRange);
@@ -59,7 +71,7 @@ public:
static Resource image(const std::string& url);
Kind kind;
Necessity necessity;
LoadingMethod loadingMethod;
std::string url;
// Includes auxiliary data if this is a tile request.
@@ -71,4 +83,21 @@ public:
std::shared_ptr<const std::string> priorData;
};
MBGL_CONSTEXPR Resource::LoadingMethod operator|(Resource::LoadingMethod a, Resource::LoadingMethod b) {
return Resource::LoadingMethod(mbgl::underlying_type(a) | mbgl::underlying_type(b));
}
MBGL_CONSTEXPR Resource::LoadingMethod& operator|=(Resource::LoadingMethod& a, Resource::LoadingMethod b) {
return (a = a | b);
}
MBGL_CONSTEXPR Resource::LoadingMethod operator&(Resource::LoadingMethod a, Resource::LoadingMethod b) {
return Resource::LoadingMethod(mbgl::underlying_type(a) & mbgl::underlying_type(b));
}
inline bool Resource::hasLoadingMethod(Resource::LoadingMethod method) {
return (loadingMethod & method) != Resource::LoadingMethod::None;
}
} // namespace mbgl

View File

@@ -0,0 +1,15 @@
#pragma once
namespace mbgl {
// Tiles can have two states: optional or required.
// - optional means that only low-cost actions should be taken to obtain the data
// (e.g. load from cache, but accept stale data)
// - required means that every effort should be taken to obtain the data (e.g. load
// from internet and keep the data fresh if it expires)
enum class TileNecessity : bool {
Optional = false,
Required = true,
};
} // namespace mbgl

View File

@@ -126,47 +126,41 @@ public:
tasks[req] = localFileSource->request(resource, callback);
} else {
// Try the offline database
const bool hasPrior = resource.priorEtag || resource.priorModified ||
resource.priorExpires || resource.priorData;
if (!hasPrior || resource.necessity == Resource::Optional) {
if (resource.hasLoadingMethod(Resource::LoadingMethod::Cache)) {
auto offlineResponse = offlineDatabase->get(resource);
if (resource.necessity == Resource::Optional && !offlineResponse) {
// Ensure there's always a response that we can send, so the caller knows that
// there's no optional data available in the cache.
offlineResponse.emplace();
offlineResponse->noContent = true;
offlineResponse->error = std::make_unique<Response::Error>(
Response::Error::Reason::NotFound, "Not found in offline database");
}
if (offlineResponse) {
if (resource.loadingMethod == Resource::LoadingMethod::CacheOnly) {
if (!offlineResponse) {
// Ensure there's always a response that we can send, so the caller knows that
// there's no optional data available in the cache, when it's the only place
// we're supposed to load from.
offlineResponse.emplace();
offlineResponse->noContent = true;
offlineResponse->error = std::make_unique<Response::Error>(
Response::Error::Reason::NotFound, "Not found in offline database");
} else if (!offlineResponse->isUsable()) {
// Don't return resources the server requested not to show when they're stale.
// Even if we can't directly use the response, we may still use it to send a
// conditional HTTP request, which is why we're saving it above.
offlineResponse->error = std::make_unique<Response::Error>(
Response::Error::Reason::NotFound, "Cached resource is unusable");
}
callback(*offlineResponse);
} else if (offlineResponse) {
// Copy over the fields so that we can use them when making a refresh request.
resource.priorModified = offlineResponse->modified;
resource.priorExpires = offlineResponse->expires;
resource.priorEtag = offlineResponse->etag;
resource.priorData = offlineResponse->data;
// Don't return resources the server requested not to show when they're stale.
// Even if we can't directly use the response, we may still use it to send a
// conditional HTTP request.
if (offlineResponse->isUsable()) {
callback(*offlineResponse);
} else if (resource.necessity == Resource::Optional) {
// Instead of the data that we got, return a not found error so that
// underlying implementations know about the fact that we couldn't find
// usable cache data.
offlineResponse->error = std::make_unique<Response::Error>(
Response::Error::Reason::NotFound, "Cached resource is unusable");
callback(*offlineResponse);
} else {
// Since we can't return the data immediately, we'll have to hold on so that
// we can return it later in case we get a 304 Not Modified response.
resource.priorData = offlineResponse->data;
}
}
}
// Get from the online file source
if (resource.necessity == Resource::Required) {
if (resource.hasLoadingMethod(Resource::LoadingMethod::Network)) {
tasks[req] = onlineFileSource.request(resource, [=] (Response onlineResponse) mutable {
this->offlineDatabase->put(resource, onlineResponse);
callback(onlineResponse);

View File

@@ -1,8 +1,8 @@
#pragma once
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/tile/tile_necessity.hpp>
#include <mbgl/util/range.hpp>
#include <mbgl/storage/resource.hpp>
#include <unordered_set>
@@ -40,15 +40,15 @@ void updateRenderables(GetTileFn getTile,
// if (source has the tile and bucket is loaded) {
if (tile->isRenderable()) {
retainTile(*tile, Resource::Necessity::Required);
retainTile(*tile, TileNecessity::Required);
renderTile(idealRenderTileID, *tile);
} else {
// We are now attempting to load child and parent tiles.
bool parentHasTriedOptional = tile->hasTriedOptional();
bool parentHasTriedOptional = tile->hasTriedCache();
bool parentIsLoaded = tile->isLoaded();
// The tile isn't loaded yet, but retain it anyway because it's an ideal tile.
retainTile(*tile, Resource::Necessity::Required);
retainTile(*tile, TileNecessity::Required);
covered = true;
overscaledZ = dataTileZoom + 1;
if (overscaledZ > zoomRange.max) {
@@ -56,7 +56,7 @@ void updateRenderables(GetTileFn getTile,
const auto childDataTileID = idealDataTileID.scaledTo(overscaledZ);
tile = getTile(childDataTileID);
if (tile && tile->isRenderable()) {
retainTile(*tile, Resource::Necessity::Optional);
retainTile(*tile, TileNecessity::Optional);
renderTile(idealRenderTileID, *tile);
} else {
covered = false;
@@ -67,7 +67,7 @@ void updateRenderables(GetTileFn getTile,
const OverscaledTileID childDataTileID(overscaledZ, idealRenderTileID.wrap, childTileID);
tile = getTile(childDataTileID);
if (tile && tile->isRenderable()) {
retainTile(*tile, Resource::Necessity::Optional);
retainTile(*tile, TileNecessity::Optional);
renderTile(childDataTileID.toUnwrapped(), *tile);
} else {
// At least one child tile doesn't exist, so we are going to look for
@@ -97,12 +97,19 @@ void updateRenderables(GetTileFn getTile,
}
if (tile) {
retainTile(*tile, parentIsLoaded ? Resource::Necessity::Required
: Resource::Necessity::Optional);
if (!parentIsLoaded) {
// We haven't completed loading the child, so we only do an optional
// (cache) request in an attempt to quickly load data that we can show.
retainTile(*tile, TileNecessity::Optional);
} else {
// Now that we've checked the child and know for sure that we can't load
// it, we attempt to load the parent from the network.
retainTile(*tile, TileNecessity::Required);
}
// Save the current values, since they're the parent of the next iteration
// of the parent tile ascent loop.
parentHasTriedOptional = tile->hasTriedOptional();
parentHasTriedOptional = tile->hasTriedCache();
parentIsLoaded = tile->isLoaded();
if (tile->isRenderable()) {

View File

@@ -19,9 +19,6 @@ AnnotationTile::~AnnotationTile() {
annotationManager.removeTile(*this);
}
void AnnotationTile::setNecessity(Necessity) {
}
class AnnotationTileFeatureData {
public:
AnnotationTileFeatureData(const AnnotationID id_,

View File

@@ -14,8 +14,6 @@ public:
AnnotationTile(const OverscaledTileID&, const TileParameters&);
~AnnotationTile() override;
void setNecessity(Necessity) final;
private:
AnnotationManager& annotationManager;
};

View File

@@ -121,7 +121,7 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
// we're actively using, e.g. as a replacement for tile that aren't loaded yet.
std::set<OverscaledTileID> retain;
auto retainTileFn = [&](Tile& tile, Resource::Necessity necessity) -> void {
auto retainTileFn = [&](Tile& tile, TileNecessity necessity) -> void {
if (retain.emplace(tile.id).second) {
tile.setNecessity(necessity);
}
@@ -179,7 +179,7 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
while (tilesIt != tiles.end()) {
if (retainIt == retain.end() || tilesIt->first < *retainIt) {
if (!needsRelayout) {
tilesIt->second->setNecessity(Tile::Necessity::Optional);
tilesIt->second->setNecessity(TileNecessity::Optional);
cache.add(tilesIt->first, std::move(tilesIt->second));
}
tiles.erase(tilesIt++);

View File

@@ -95,7 +95,7 @@ Resource Resource::tile(const std::string& urlTemplate,
int32_t y,
int8_t z,
Tileset::Scheme scheme,
Necessity necessity) {
LoadingMethod loadingMethod) {
bool supportsRatio = urlTemplate.find("{ratio}") != std::string::npos;
if (scheme == Tileset::Scheme::TMS) {
y = (1 << z) - y - 1;
@@ -131,7 +131,7 @@ Resource Resource::tile(const std::string& urlTemplate,
y,
z
},
necessity
loadingMethod
};
}

View File

@@ -59,7 +59,7 @@ void ImageSource::loadDescription(FileSource& fileSource) {
if (req || loaded) {
return;
}
const Resource imageResource { Resource::Image, *url, {}, Resource::Necessity::Required };
const Resource imageResource { Resource::Image, *url, {} };
req = fileSource.request(imageResource, [this](Response res) {
if (res.error) {

View File

@@ -17,8 +17,6 @@ GeoJSONTile::GeoJSONTile(const OverscaledTileID& overscaledTileID,
void GeoJSONTile::updateData(mapbox::geometry::feature_collection<int16_t> features) {
setData(std::make_unique<GeoJSONTileData>(std::move(features)));
}
void GeoJSONTile::setNecessity(Necessity) {}
void GeoJSONTile::querySourceFeatures(
std::vector<Feature>& result,

View File

@@ -15,8 +15,6 @@ public:
mapbox::geometry::feature_collection<int16_t>);
void updateData(mapbox::geometry::feature_collection<int16_t>);
void setNecessity(Necessity) final;
void querySourceFeatures(
std::vector<Feature>& result,

View File

@@ -32,12 +32,12 @@ void RasterTile::setError(std::exception_ptr err) {
observer->onTileError(*this, err);
}
void RasterTile::setData(std::shared_ptr<const std::string> data,
optional<Timestamp> modified_,
optional<Timestamp> expires_) {
void RasterTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp> expires_) {
modified = modified_;
expires = expires_;
}
void RasterTile::setData(std::shared_ptr<const std::string> data) {
pending = true;
++correlationID;
worker.invoke(&RasterTileWorker::parse, data, correlationID);
@@ -77,7 +77,7 @@ void RasterTile::setMask(TileMask&& mask) {
}
}
void RasterTile::setNecessity(Necessity necessity) {
void RasterTile::setNecessity(TileNecessity necessity) {
loader.setNecessity(necessity);
}

View File

@@ -22,12 +22,11 @@ public:
const Tileset&);
~RasterTile() final;
void setNecessity(Necessity) final;
void setNecessity(TileNecessity) final;
void setError(std::exception_ptr);
void setData(std::shared_ptr<const std::string> data,
optional<Timestamp> modified_,
optional<Timestamp> expires_);
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
void setData(std::shared_ptr<const std::string> data);
void cancel() override;

View File

@@ -18,7 +18,7 @@ void Tile::setObserver(TileObserver* observer_) {
observer = observer_;
}
void Tile::setTriedOptional() {
void Tile::setTriedCache() {
triedOptional = true;
observer->onTileChanged(*this);
}

View File

@@ -6,6 +6,7 @@
#include <mbgl/util/feature.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/tile/tile_necessity.hpp>
#include <mbgl/renderer/tile_mask.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
@@ -38,14 +39,7 @@ public:
void setObserver(TileObserver* observer);
// Tiles can have two states: optional or required.
// - optional means that only low-cost actions should be taken to obtain the data
// (e.g. load from cache, but accept stale data)
// - required means that every effort should be taken to obtain the data (e.g. load
// from internet and keep the data fresh if it expires)
using Necessity = Resource::Necessity;
virtual void setNecessity(Necessity) = 0;
virtual void setNecessity(TileNecessity) {}
// Mark this tile as no longer needed and cancel any pending work.
virtual void cancel() = 0;
@@ -68,11 +62,11 @@ public:
std::vector<Feature>& result,
const SourceQueryOptions&);
void setTriedOptional();
void setTriedCache();
// Returns true when the tile source has received a first response, regardless of whether a load
// error occurred or actual data was loaded.
bool hasTriedOptional() const {
bool hasTriedCache() const {
return triedOptional;
}

View File

@@ -21,12 +21,10 @@ public:
const Tileset&);
~TileLoader();
using Necessity = Resource::Necessity;
void setNecessity(Necessity newNecessity) {
void setNecessity(TileNecessity newNecessity) {
if (newNecessity != necessity) {
necessity = newNecessity;
if (necessity == Necessity::Required) {
if (necessity == TileNecessity::Required) {
makeRequired();
} else {
makeOptional();
@@ -45,12 +43,12 @@ private:
// an up-to-date version or load new data
void makeOptional();
void loadOptional();
void loadFromCache();
void loadedData(const Response&);
void loadRequired();
void loadFromNetwork();
T& tile;
Necessity necessity;
TileNecessity necessity;
Resource resource;
FileSource& fileSource;
std::unique_ptr<AsyncRequest> request;

View File

@@ -15,32 +15,31 @@ TileLoader<T>::TileLoader(T& tile_,
const TileParameters& parameters,
const Tileset& tileset)
: tile(tile_),
necessity(Necessity::Optional),
necessity(TileNecessity::Optional),
resource(Resource::tile(
tileset.tiles.at(0),
parameters.pixelRatio,
id.canonical.x,
id.canonical.y,
id.canonical.z,
tileset.scheme)),
tileset.scheme,
Resource::LoadingMethod::CacheOnly)),
fileSource(parameters.fileSource) {
assert(!request);
if (fileSource.supportsOptionalRequests()) {
if (fileSource.supportsCacheOnlyRequests()) {
// When supported, the first request is always optional, even if the TileLoader
// is marked as required. That way, we can let the first optional request continue
// to load when the TileLoader is later changed from required to optional. If we
// started out with a required request, we'd have to cancel everything, including the
// initial optional part of the request.
loadOptional();
loadFromCache();
} else if (necessity == TileNecessity::Required) {
// When the file source doesn't support cache-only requests, and we definiitely need this
// data, we can start out with a network request immediately.
loadFromNetwork();
} else {
// When the FileSource doesn't support optional requests, we do nothing until the
// When the FileSource doesn't support cache-only requests, we do nothing until the
// data is definitely required.
if (necessity == Necessity::Required) {
loadRequired();
} else {
// We're using this field to check whether the pending request is optional or required.
resource.necessity = Resource::Optional;
}
}
}
@@ -48,29 +47,31 @@ template <typename T>
TileLoader<T>::~TileLoader() = default;
template <typename T>
void TileLoader<T>::loadOptional() {
void TileLoader<T>::loadFromCache() {
assert(!request);
resource.necessity = Resource::Optional;
resource.loadingMethod = Resource::LoadingMethod::CacheOnly;
request = fileSource.request(resource, [this](Response res) {
request.reset();
tile.setTriedOptional();
tile.setTriedCache();
if (res.error && res.error->reason == Response::Error::Reason::NotFound) {
// When the optional request could not be satisfied, don't treat it as an error.
// Instead, we make sure that the next request knows that there has been an optional
// request before by setting one of the prior* fields.
// When the cache-only request could not be satisfied, don't treat it as an error.
// A cache lookup could still return data, _and_ an error, in particular when we were
// able to find the data, but it is expired and the Cache-Control headers indicated that
// we aren't allowed to use expired responses. In this case, we still get the data which
// we can use in our conditional network request.
resource.priorModified = res.modified;
resource.priorExpires = Timestamp{ Seconds::zero() };
resource.priorExpires = res.expires;
resource.priorEtag = res.etag;
resource.priorData = res.data;
} else {
loadedData(res);
}
if (necessity == Necessity::Required) {
loadRequired();
if (necessity == TileNecessity::Required) {
loadFromNetwork();
}
});
}
@@ -78,14 +79,15 @@ void TileLoader<T>::loadOptional() {
template <typename T>
void TileLoader<T>::makeRequired() {
if (!request) {
loadRequired();
loadFromNetwork();
}
}
template <typename T>
void TileLoader<T>::makeOptional() {
if (resource.necessity == Resource::Required && request) {
// Abort a potential HTTP request.
if (resource.loadingMethod == Resource::LoadingMethod::NetworkOnly && request) {
// Abort the current request, but only when we know that we're specifically querying for a
// network resource only.
request.reset();
}
}
@@ -98,19 +100,23 @@ void TileLoader<T>::loadedData(const Response& res) {
resource.priorExpires = res.expires;
// Do not notify the tile; when we get this message, it already has the current
// version of the data.
tile.setMetadata(res.modified, res.expires);
} else {
resource.priorModified = res.modified;
resource.priorExpires = res.expires;
resource.priorEtag = res.etag;
tile.setData(res.noContent ? nullptr : res.data, res.modified, res.expires);
tile.setMetadata(res.modified, res.expires);
tile.setData(res.noContent ? nullptr : res.data);
}
}
template <typename T>
void TileLoader<T>::loadRequired() {
void TileLoader<T>::loadFromNetwork() {
assert(!request);
resource.necessity = Resource::Required;
// Instead of using Resource::LoadingMethod::All, we're first doing a CacheOnly, and then a
// NetworkOnly request.
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
request = fileSource.request(resource, [this](Response res) { loadedData(res); });
}

View File

@@ -12,16 +12,16 @@ VectorTile::VectorTile(const OverscaledTileID& id_,
: GeometryTile(id_, sourceID_, parameters), loader(*this, id_, parameters, tileset) {
}
void VectorTile::setNecessity(Necessity necessity) {
void VectorTile::setNecessity(TileNecessity necessity) {
loader.setNecessity(necessity);
}
void VectorTile::setData(std::shared_ptr<const std::string> data_,
optional<Timestamp> modified_,
optional<Timestamp> expires_) {
void VectorTile::setMetadata(optional<Timestamp> modified_, optional<Timestamp> expires_) {
modified = modified_;
expires = expires_;
}
void VectorTile::setData(std::shared_ptr<const std::string> data_) {
GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(data_) : nullptr);
}

View File

@@ -15,10 +15,9 @@ public:
const TileParameters&,
const Tileset&);
void setNecessity(Necessity) final;
void setData(std::shared_ptr<const std::string> data,
optional<Timestamp> modified,
optional<Timestamp> expires);
void setNecessity(TileNecessity) final;
void setMetadata(optional<Timestamp> modified, optional<Timestamp> expires);
void setData(std::shared_ptr<const std::string> data);
private:
TileLoader<VectorTile> loader;

View File

@@ -26,7 +26,7 @@ struct MockBucket {};
struct MockTileData {
MockTileData(const mbgl::OverscaledTileID& tileID_) : tileID(tileID_) {}
bool hasTriedOptional() const {
bool hasTriedCache() const {
return triedOptional;
}

View File

@@ -45,7 +45,7 @@ std::ostream& operator<<(std::ostream& os, const CreateTileDataAction& action) {
struct RetainTileDataAction {
const OverscaledTileID tileID;
const Resource::Necessity necessity;
const TileNecessity necessity;
bool operator==(const RetainTileDataAction& rhs) const {
return tileID == rhs.tileID && necessity == rhs.necessity;
@@ -56,7 +56,7 @@ std::ostream& operator<<(std::ostream& os, const RetainTileDataAction& action) {
return os << "RetainTileDataAction{ { " << int(action.tileID.overscaledZ) << ", " << int(action.tileID.wrap) << ", { "
<< int(action.tileID.canonical.z) << ", " << action.tileID.canonical.x << ", "
<< action.tileID.canonical.y << " } }, "
<< (action.necessity == Resource::Necessity::Required ? "Required" : "Optional") << " }\n";
<< (action.necessity == TileNecessity::Required ? "Required" : "Optional") << " }\n";
}
struct RenderTileAction {
@@ -102,7 +102,7 @@ auto createTileDataFn(ActionLog& log, T& dataTiles) {
template <typename = int>
auto retainTileDataFn(ActionLog& log) {
return [&](auto& tileData, Resource::Necessity necessity) {
return [&](auto& tileData, TileNecessity necessity) {
log.emplace_back(RetainTileDataAction{ tileData.tileID, necessity });
};
}
@@ -132,7 +132,7 @@ TEST(UpdateRenderables, SingleTile) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render ideal tile
}),
log);
@@ -143,7 +143,7 @@ TEST(UpdateRenderables, SingleTile) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render ideal tile
}),
log);
@@ -156,7 +156,7 @@ TEST(UpdateRenderables, SingleTile) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, NotFound }, // missing ideal tile
CreateTileDataAction{ { 1, 0, { 1, 0, 1 } } }, // create ideal tile
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // four child tiles
GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ...
@@ -164,7 +164,7 @@ TEST(UpdateRenderables, SingleTile) {
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render found tile
}),
log);
@@ -176,17 +176,17 @@ TEST(UpdateRenderables, SingleTile) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // missing ideal tile
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // four child tiles
GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile
CreateTileDataAction{ { 0, 0, { 0, 0, 0 } } }, // load parent tile
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // found ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render found tile
}),
log);
@@ -199,11 +199,11 @@ TEST(UpdateRenderables, SingleTile) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // newly added tile
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // render ideal tile
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render found tile
}),
log);
@@ -218,21 +218,21 @@ TEST(UpdateRenderables, SingleTile) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // found tile, not ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // four child tiles
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
// optional parent tile was already created before, but is not renderable
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // ideal tile
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // render ideal tile
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, // render ideal tile
}),
log);
@@ -244,15 +244,15 @@ TEST(UpdateRenderables, SingleTile) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // found tile, now ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, //
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // ideal tile
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, //
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, Found }, // ideal tile
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 1, 1 }, *tile_1_1_1_1 }, //
}),
log);
@@ -278,24 +278,24 @@ TEST(UpdateRenderables, UseParentTile) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, NotFound }, // missing ideal tile
CreateTileDataAction{ { 1, 0, { 1, 0, 1 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // child tile
GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent found!
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // render parent
GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, NotFound }, // missing ideal tile
CreateTileDataAction{ { 1, 0, { 1, 1, 0 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 2, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 2, 0, { 2, 2, 1 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 3, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 3, 1 } }, NotFound }, // ...
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, NotFound }, // missing tile
CreateTileDataAction{ { 1, 0, { 1, 1, 1 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 1 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 2, 2 } }, NotFound }, // child tile
GetTileDataAction{ { 2, 0, { 2, 2, 3 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 3, 2 } }, NotFound }, // ...
@@ -321,7 +321,7 @@ TEST(UpdateRenderables, DontUseWrongParentTile) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // missing ideal tile
CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // ...
@@ -338,14 +338,14 @@ TEST(UpdateRenderables, DontUseWrongParentTile) {
source.idealTiles, source.zoomRange, 2);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // non-ready ideal tile
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // parent tile, missing
CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, // find optional parent
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // parent tile, missing
}),
log);
@@ -357,25 +357,25 @@ TEST(UpdateRenderables, DontUseWrongParentTile) {
source.idealTiles, source.zoomRange, 2);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // non-ready ideal tile
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
// this tile was added by the previous invocation of updateRenderables
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // parent tile not ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // missing parent tile
GetTileDataAction{ { 2, 0, { 2, 2, 0 } }, NotFound }, // missing ideal tile
CreateTileDataAction{ { 2, 0, { 2, 2, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 2, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 2, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 3, 4, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 3, 0, { 3, 4, 1 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 5, 0 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 5, 1 } }, NotFound }, // ...
GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, Found }, // found parent tile
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 1, 1, 0 }, *tile_1_1_1_0 }, // render parent tile
}),
log);
@@ -402,13 +402,13 @@ TEST(UpdateRenderables, UseParentTileWhenChildNotReady) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // found, but not ready
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 2 } }, NotFound }, // child tile
GetTileDataAction{ { 2, 0, { 2, 0, 3 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 2 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 3 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, ready
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, // render parent tile
}),
log);
@@ -420,7 +420,7 @@ TEST(UpdateRenderables, UseParentTileWhenChildNotReady) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // found and ready
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, // render ideal tile
}),
log);
@@ -448,17 +448,17 @@ TEST(UpdateRenderables, UseOverlappingParentTile) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile not found
CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile found
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, Found }, // ideal tile found
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 1 } }, TileNecessity::Required }, //
RenderTileAction{ { 1, 0, 1 }, *tile_1_1_0_1 }, //
}),
log);
@@ -484,13 +484,13 @@ TEST(UpdateRenderables, UseChildTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ideal tile, missing
CreateTileDataAction{ { 0, 0, { 0, 0, 0 } } }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // child tile found
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, // render child tile
GetTileDataAction{ { 1, 0, { 1, 0, 1 } }, NotFound }, // child tile not found
GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, Found }, // child tile found
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 1, 1, 0 }, *tile_1_1_1_0 }, // render child tile
GetTileDataAction{ { 1, 0, { 1, 1, 1 } }, NotFound }, // child tile not found
// no parent tile of 0 to consider
@@ -518,15 +518,15 @@ TEST(UpdateRenderables, PreferChildTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile, not found
CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, // child tile, not found
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, found
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
}),
log);
@@ -541,17 +541,17 @@ TEST(UpdateRenderables, PreferChildTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready
// ideal tile was added in previous invocation, but is not yet ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, Found }, // ...
RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, Resource::Necessity::Optional }, // ...
RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, TileNecessity::Optional }, // ...
RenderTileAction{ { 2, 0, 1 }, *tile_2_2_0_1 }, //
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, // child tile, not found
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, found
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
}),
log);
@@ -564,19 +564,19 @@ TEST(UpdateRenderables, PreferChildTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready
// ideal tile was added in first invocation, but is not yet ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, Found }, // ...
RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 1 }, *tile_2_2_0_1 }, //
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, Found }, // ...
RetainTileDataAction{ { 2, 0, { 2, 1, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 1, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 1, 0 }, *tile_2_2_1_0 }, //
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, // child tile, not found
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile, found
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
}),
log);
@@ -590,18 +590,18 @@ TEST(UpdateRenderables, PreferChildTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready
// ideal tile was added in first invocation, but is not yet ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile, found
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, Found }, // ...
RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 1 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 1 }, *tile_2_2_0_1 }, //
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, Found }, // ...
RetainTileDataAction{ { 2, 0, { 2, 1, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 1, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 1, 0 }, *tile_2_2_1_0 }, //
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, Found }, // ...
RetainTileDataAction{ { 2, 0, { 2, 1, 1 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 1, 1 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 1, 1 }, *tile_2_2_1_1 }, //
}),
log);
@@ -628,15 +628,15 @@ TEST(UpdateRenderables, UseParentAndChildTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile, missing
CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // child tile
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
}),
log);
@@ -648,13 +648,13 @@ TEST(UpdateRenderables, UseParentAndChildTiles) {
source.idealTiles, source.zoomRange, 1);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, // parent tile
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
}),
log);
@@ -679,7 +679,7 @@ TEST(UpdateRenderables, DontUseTilesLowerThanMinzoom) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ideal tile, missing
CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, //
GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, //
@@ -709,7 +709,7 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) {
ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ideal tile, missing
CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // overzoomed tile, not children!
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, //
@@ -724,11 +724,11 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) {
EXPECT_EQ(
ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // ideal tile, missing
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // overzoomed tile, not children!
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, //
CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, //
}),
log);
@@ -742,10 +742,10 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, // ideal tile, missing
CreateTileDataAction{ { 3, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
}),
log);
@@ -758,7 +758,7 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) {
source.idealTiles, source.zoomRange, 3);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
RenderTileAction{ { 2, 0, 0 }, *tile_3_2_0_0 }, //
}),
log);
@@ -769,7 +769,7 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) {
source.idealTiles, source.zoomRange, 2);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
}),
log);
@@ -785,9 +785,9 @@ TEST(UpdateRenderables, UseOverzoomedTileAfterMaxzoom) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, //
CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // use overzoomed tile!
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_3_2_0_0 }, //
}),
log);
@@ -811,7 +811,7 @@ TEST(UpdateRenderables, AscendToNonOverzoomedTiles) {
source.idealTiles, source.zoomRange, 3);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
RenderTileAction{ { 2, 0, 0 }, *tile_3_2_0_0 }, //
}),
log);
@@ -827,10 +827,10 @@ TEST(UpdateRenderables, AscendToNonOverzoomedTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, NotFound }, //
CreateTileDataAction{ { 3, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, // prefer using a child first
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 2, 0, 0 }, *tile_2_2_0_0 }, //
}),
log);
@@ -845,11 +845,11 @@ TEST(UpdateRenderables, AscendToNonOverzoomedTiles) {
source.idealTiles, source.zoomRange, 3);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, //
}),
log);
@@ -861,13 +861,13 @@ TEST(UpdateRenderables, AscendToNonOverzoomedTiles) {
source.idealTiles, source.zoomRange, 3);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 3, 0, { 2, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 3, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 4, 0, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, //
CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 1, 0, 0 }, *tile_1_1_0_0 }, //
}),
log);
@@ -889,7 +889,7 @@ TEST(UpdateRenderables, DoNotAscendMultipleTimesIfNotFound) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 8, 0, { 8, 0, 0 } }, NotFound }, // ideal tile
CreateTileDataAction{ { 8, 0, { 8, 0, 0 } } }, //
RetainTileDataAction{ { 8, 0, { 8, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 8, 0, { 8, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 9, 0, { 9, 0, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 9, 0, { 9, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 9, 0, { 9, 1, 0 } }, NotFound }, // ...
@@ -905,7 +905,7 @@ TEST(UpdateRenderables, DoNotAscendMultipleTimesIfNotFound) {
GetTileDataAction{ { 8, 0, { 8, 1, 0 } }, NotFound }, // ideal tile
CreateTileDataAction{ { 8, 0, { 8, 1, 0 } } }, //
RetainTileDataAction{ { 8, 0, { 8, 1, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 8, 0, { 8, 1, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 9, 0, { 9, 2, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 9, 0, { 9, 2, 1 } }, NotFound }, // ...
GetTileDataAction{ { 9, 0, { 9, 3, 0 } }, NotFound }, // ...
@@ -923,7 +923,7 @@ TEST(UpdateRenderables, DoNotAscendMultipleTimesIfNotFound) {
source.idealTiles, source.zoomRange, 8);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 8, 0, { 8, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 8, 0, { 8, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 8, 0, { 8, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 9, 0, { 9, 0, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 9, 0, { 9, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 9, 0, { 9, 1, 0 } }, NotFound }, // ...
@@ -932,11 +932,11 @@ TEST(UpdateRenderables, DoNotAscendMultipleTimesIfNotFound) {
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // stops ascent
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 4, 0, 0 }, *tile_4_0_0_0 }, //
GetTileDataAction{ { 8, 0, { 8, 1, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 8, 0, { 8, 1, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 8, 0, { 8, 1, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 9, 0, { 9, 2, 0 } }, NotFound }, // child tile
GetTileDataAction{ { 9, 0, { 9, 2, 1 } }, NotFound }, // ...
GetTileDataAction{ { 9, 0, { 9, 3, 0 } }, NotFound }, // ...
@@ -963,13 +963,13 @@ TEST(UpdateRenderables, DontRetainUnusedNonIdealTiles) {
source.idealTiles, source.zoomRange, 2);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 3, 0, { 3, 0, 1 } }, NotFound }, //
GetTileDataAction{ { 3, 0, { 3, 1, 0 } }, NotFound }, //
GetTileDataAction{ { 3, 0, { 3, 1, 1 } }, NotFound }, //
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, Found }, // parent tile, not ready
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, //
}),
log);
@@ -996,7 +996,7 @@ TEST(UpdateRenderables, WrappedTiles) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 1, -1, { 1, 1, 0 } }, NotFound }, // ideal tile 1/-1/0 (wrapped to -1)
CreateTileDataAction{ { 1, -1, { 1, 1, 0 } } }, //
RetainTileDataAction{ { 1, -1, { 1, 1, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, -1, { 1, 1, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, -1, { 2, 2, 0 } }, NotFound }, //
GetTileDataAction{ { 2, -1, { 2, 2, 1 } }, NotFound }, //
GetTileDataAction{ { 2, -1, { 2, 3, 0 } }, NotFound }, //
@@ -1005,18 +1005,18 @@ TEST(UpdateRenderables, WrappedTiles) {
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ideal tile 1/0/0
CreateTileDataAction{ { 1, 0, { 1, 0, 0 } } }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 0, 1 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 1, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 1, 1 } }, NotFound }, //
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, Found }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 0, 0, { 0, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 0, 0, 0 }, *tile_0_0_0_0 }, //
GetTileDataAction{ { 1, 0, { 1, 1, 0 } }, NotFound }, // ideal tile 1/1/0, doesn't match 1/-/1/0
CreateTileDataAction{ { 1, 0, { 1, 1, 0 } } },
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 0, { 1, 1, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 0, { 2, 2, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 2, 1 } }, NotFound }, //
GetTileDataAction{ { 2, 0, { 2, 3, 0 } }, NotFound }, //
@@ -1025,7 +1025,7 @@ TEST(UpdateRenderables, WrappedTiles) {
GetTileDataAction{ { 1, 1, { 1, 0, 0 } }, NotFound }, // ideal tile 1/2/0 (wrapped to 1)
CreateTileDataAction{ { 1, 1, { 1, 0, 0 } } },
RetainTileDataAction{ { 1, 1, { 1, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 1, 1, { 1, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 2, 1, { 2, 0, 0 } }, NotFound }, //
GetTileDataAction{ { 2, 1, { 2, 0, 1 } }, NotFound }, //
GetTileDataAction{ { 2, 1, { 2, 1, 0 } }, NotFound }, //
@@ -1050,7 +1050,7 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, NotFound }, // ideal tile, not found
CreateTileDataAction{ { 6, 0, { 6, 0, 0 } } }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
@@ -1070,7 +1070,7 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
@@ -1091,14 +1091,14 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ascent
CreateTileDataAction{ { 5, 0, { 5, 0, 0 } } }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ...
@@ -1113,13 +1113,13 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ...
@@ -1135,16 +1135,16 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ...
CreateTileDataAction{ { 4, 0, { 4, 0, 0 } } }, //
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ...
@@ -1159,18 +1159,18 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // ...
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ...
CreateTileDataAction{ { 3, 0, { 3, 0, 0 } } }, //
RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ...
@@ -1184,20 +1184,20 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // ...
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, Found }, // ...
RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ...
CreateTileDataAction{ { 2, 0, { 2, 0, 0 } } }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 2, 0, { 2, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 1, 0, { 1, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 0, 0, { 0, 0, 0 } }, NotFound }, // ...
}),
@@ -1211,17 +1211,17 @@ TEST(UpdateRenderables, RepeatedRenderWithMissingOptionals) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not ready
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 7, 0, 0 } }, NotFound }, // children
GetTileDataAction{ { 7, 0, { 7, 0, 1 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 0 } }, NotFound }, // ...
GetTileDataAction{ { 7, 0, { 7, 1, 1 } }, NotFound }, // ...
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, Found }, // ascent
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, Found }, // ...
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 4, 0, { 4, 0, 0 } }, TileNecessity::Optional }, //
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, Found }, // ...
RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, Resource::Necessity::Optional }, //
RetainTileDataAction{ { 3, 0, { 3, 0, 0 } }, TileNecessity::Optional }, //
RenderTileAction{ { 3, 0, 0 }, *tile_3_3_0_0 }, //
}),
log);
@@ -1246,11 +1246,11 @@ TEST(UpdateRenderables, LoadRequiredIfIdealTileCantBeFound) {
source.idealTiles, source.zoomRange, 6);
EXPECT_EQ(ActionLog({
GetTileDataAction{ { 6, 0, { 6, 0, 0 } }, Found }, // ideal tile, not found
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, Resource::Necessity::Required }, //
RetainTileDataAction{ { 6, 0, { 6, 0, 0 } }, TileNecessity::Required }, //
GetTileDataAction{ { 7, 0, { 6, 0, 0 } }, NotFound }, // overzoomed child
GetTileDataAction{ { 5, 0, { 5, 0, 0 } }, NotFound }, // ascent
CreateTileDataAction{ { 5, 0, { 5, 0, 0 } } },
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, Resource::Necessity::Required },
RetainTileDataAction{ { 5, 0, { 5, 0, 0 } }, TileNecessity::Required },
GetTileDataAction{ { 4, 0, { 4, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 3, 0, { 3, 0, 0 } }, NotFound }, // ...
GetTileDataAction{ { 2, 0, { 2, 0, 0 } }, NotFound }, // ...

View File

@@ -251,7 +251,7 @@ TEST(DefaultFileSource, OptionalNonExpired) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::Optional };
const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::LoadingMethod::CacheOnly };
using namespace std::chrono_literals;
@@ -281,7 +281,7 @@ TEST(DefaultFileSource, OptionalExpired) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::Optional };
const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::LoadingMethod::CacheOnly };
using namespace std::chrono_literals;
@@ -327,7 +327,7 @@ TEST(DefaultFileSource, OptionalNotFound) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::Optional };
const Resource optionalResource { Resource::Unknown, "http://127.0.0.1:3000/test", {}, Resource::LoadingMethod::CacheOnly };
using namespace std::chrono_literals;
@@ -348,13 +348,13 @@ TEST(DefaultFileSource, OptionalNotFound) {
loop.run();
}
// Test that we can make a request with etag data that doesn't first try to load
// from cache like a regular request
// Test that a network only request doesn't attempt to load data from the cache.
TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagNotModified)) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
Resource resource { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" };
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
resource.priorEtag.emplace("snowfall");
using namespace std::chrono_literals;
@@ -383,13 +383,13 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagNotModified)) {
loop.run();
}
// Test that we can make a request with etag data that doesn't first try to load
// from cache like a regular request
// Test that a network only request doesn't attempt to load data from the cache.
TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagModified)) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
Resource resource { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" };
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
resource.priorEtag.emplace("sunshine");
using namespace std::chrono_literals;
@@ -418,15 +418,13 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagModified)) {
loop.run();
}
// Test that we can make a request that doesn't first try to load
// from cache like a regular request.
// Test that a network only request doesn't attempt to load data from the cache.
TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheFull)) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
Resource resource { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" };
// Setting any prior field results in skipping the cache.
resource.priorExpires.emplace(Seconds(0));
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
using namespace std::chrono_literals;
@@ -461,6 +459,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedNotModified))
DefaultFileSource fs(":memory:", ".");
Resource resource { Resource::Unknown, "http://127.0.0.1:3000/revalidate-modified" };
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
resource.priorModified.emplace(Seconds(1420070400)); // January 1, 2015
using namespace std::chrono_literals;
@@ -496,6 +495,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedModified)) {
DefaultFileSource fs(":memory:", ".");
Resource resource { Resource::Unknown, "http://127.0.0.1:3000/revalidate-modified" };
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
resource.priorModified.emplace(Seconds(1417392000)); // December 1, 2014
using namespace std::chrono_literals;
@@ -578,7 +578,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(RespondToStaleMustRevalidate)) {
DefaultFileSource fs(":memory:", ".");
Resource resource { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" };
resource.necessity = Resource::Necessity::Optional;
resource.loadingMethod = Resource::LoadingMethod::CacheOnly;
// using namespace std::chrono_literals;
@@ -621,7 +621,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(RespondToStaleMustRevalidate)) {
// Now run this request again, with the data we gathered from the previous stale/unusable
// request. We're replacing the data so that we can check that the DefaultFileSource doesn't
// attempt another database access if we already have the value.
resource.necessity = Resource::Necessity::Required;
resource.loadingMethod = Resource::LoadingMethod::NetworkOnly;
resource.priorData = std::make_shared<std::string>("Prior value");
req = fs.request(resource, [&](Response res) {