[core] Rationalize Resource initialization

This commit is contained in:
John Firebaugh
2016-01-28 16:29:54 -08:00
parent 849e8b32b4
commit b41a73e1c1
12 changed files with 180 additions and 100 deletions

View File

@@ -20,20 +20,6 @@ public:
SpriteJSON
};
Resource(Kind kind_, const std::string& url_)
: kind(kind_),
url(url_) {
}
const Kind kind;
const std::string url;
optional<SystemTimePoint> priorModified;
optional<SystemTimePoint> priorExpires;
optional<std::string> priorEtag;
// Includes auxiliary data if this is a tile request.
struct TileData {
std::string urlTemplate;
float pixelRatio;
@@ -42,7 +28,34 @@ public:
int8_t z;
};
Resource(Kind kind_, const std::string& url_, optional<TileData> tileData_ = {})
: kind(kind_),
url(url_),
tileData(tileData_) {
}
static Resource style(const std::string& url);
static Resource source(const std::string& url);
static Resource tile(const std::string& urlTemplate,
float pixelRatio,
int32_t x,
int32_t y,
int8_t z);
static Resource glyphs(const std::string& urlTemplate,
const std::string& fontStack,
const std::pair<uint16_t, uint16_t>& glyphRange);
static Resource spriteImage(const std::string& base, float pixelRatio);
static Resource spriteJSON(const std::string& base, float pixelRatio);
const Kind kind;
const std::string url;
// Includes auxiliary data if this is a tile request.
optional<TileData> tileData;
optional<SystemTimePoint> priorModified = {};
optional<SystemTimePoint> priorExpires = {};
optional<std::string> priorEtag = {};
};
} // namespace mbgl

View File

@@ -104,7 +104,7 @@ void MapContext::setStyleURL(const std::string& url) {
}
FileSource* fs = util::ThreadContext::getFileSource();
styleRequest = fs->request({ Resource::Kind::Style, styleURL }, [this, base](Response res) {
styleRequest = fs->request(Resource::style(styleURL), [this, base](Response res) {
if (res.error) {
if (res.error->reason == Response::Error::Reason::NotFound &&
util::mapbox::isMapboxURL(styleURL)) {

View File

@@ -5,7 +5,6 @@
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/worker.hpp>
#include <mbgl/util/work_request.hpp>
#include <mbgl/util/url.hpp>
using namespace mbgl;
@@ -20,19 +19,7 @@ RasterTileData::RasterTileData(const TileID& id_,
worker(worker_) {
state = State::loading;
Resource resource {
Resource::Kind::Tile,
util::templateTileURL(urlTemplate, id, pixelRatio)
};
resource.tileData = Resource::TileData {
urlTemplate,
pixelRatio,
id.x,
id.y,
id.z
};
const Resource resource = Resource::tile(urlTemplate, pixelRatio, id.x, id.y, id.sourceZ);
req = util::ThreadContext::getFileSource()->request(resource, [callback, this](Response res) {
if (res.error) {
std::exception_ptr error;

View File

@@ -91,7 +91,7 @@ void Source::load() {
// URL may either be a TileJSON file, or a GeoJSON file.
FileSource* fs = util::ThreadContext::getFileSource();
req = fs->request({ Resource::Kind::Source, url }, [this](Response res) {
req = fs->request(Resource::source(url), [this](Response res) {
if (res.error) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
return;

View File

@@ -185,19 +185,7 @@ VectorTileMonitor::VectorTileMonitor(const TileID& tileID_, float pixelRatio_, c
}
std::unique_ptr<FileRequest> VectorTileMonitor::monitorTile(const GeometryTileMonitor::Callback& callback) {
Resource resource {
Resource::Kind::Tile,
util::templateTileURL(urlTemplate, tileID, pixelRatio)
};
resource.tileData = Resource::TileData {
urlTemplate,
pixelRatio,
tileID.x,
tileID.y,
tileID.z
};
const Resource resource = Resource::tile(urlTemplate, pixelRatio, tileID.x, tileID.y, tileID.sourceZ);
return util::ThreadContext::getFileSource()->request(resource, [callback, this](Response res) {
if (res.notModified) {
// We got the same data again. Abort early.

View File

@@ -32,14 +32,10 @@ void SpriteStore::setURL(const std::string& url) {
return;
}
std::string spriteURL(url + (pixelRatio > 1 ? "@2x" : "") + ".png");
std::string jsonURL(url + (pixelRatio > 1 ? "@2x" : "") + ".json");
loader = std::make_unique<Loader>();
FileSource* fs = util::ThreadContext::getFileSource();
loader->jsonRequest = fs->request({ Resource::Kind::SpriteJSON, jsonURL },
[this, jsonURL](Response res) {
loader->jsonRequest = fs->request(Resource::spriteJSON(url, pixelRatio), [this](Response res) {
if (res.error) {
observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
return;
@@ -57,24 +53,22 @@ void SpriteStore::setURL(const std::string& url) {
}
});
loader->spriteRequest =
fs->request({ Resource::Kind::SpriteImage, spriteURL },
[this, spriteURL](Response res) {
if (res.error) {
observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
return;
}
loader->spriteRequest = fs->request(Resource::spriteImage(url, pixelRatio), [this](Response res) {
if (res.error) {
observer->onSpriteError(std::make_exception_ptr(std::runtime_error(res.error->message)));
return;
}
if (res.notModified) {
// We got the same data back as last time. Abort early.
return;
}
if (res.notModified) {
// We got the same data back as last time. Abort early.
return;
}
if (!loader->image || *loader->image != *res.data) {
loader->image = res.data;
emitSpriteLoadedIfComplete();
}
});
if (!loader->image || *loader->image != *res.data) {
loader->image = res.data;
emitSpriteLoadedIfComplete();
}
});
}
void SpriteStore::emitSpriteLoadedIfComplete() {

View File

@@ -0,0 +1,82 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/token.hpp>
#include <mbgl/util/url.hpp>
namespace mbgl {
Resource Resource::style(const std::string& url) {
return Resource {
Resource::Kind::Style,
url
};
}
Resource Resource::source(const std::string& url) {
return Resource {
Resource::Kind::Source,
url
};
}
Resource Resource::spriteImage(const std::string& base, float pixelRatio) {
return Resource {
Resource::Kind::SpriteImage,
base + (pixelRatio > 1 ? "@2x" : "") + ".png"
};
}
Resource Resource::spriteJSON(const std::string& base, float pixelRatio) {
return Resource {
Resource::Kind::SpriteJSON,
base + (pixelRatio > 1 ? "@2x" : "") + ".json"
};
}
Resource Resource::glyphs(const std::string& urlTemplate, const std::string& fontStack, const std::pair<uint16_t, uint16_t>& glyphRange) {
return Resource {
Resource::Kind::Glyphs,
util::replaceTokens(urlTemplate, [&](const std::string& token) {
if (token == "fontstack") {
return util::percentEncode(fontStack);
} else if (token == "range") {
return util::toString(glyphRange.first) + "-" + util::toString(glyphRange.second);
} else {
return std::string();
}
})
};
}
Resource Resource::tile(const std::string& urlTemplate, float pixelRatio, int32_t x, int32_t y, int8_t z) {
return Resource {
Resource::Kind::Tile,
util::replaceTokens(urlTemplate, [&](const std::string& token) {
if (token == "z") {
return util::toString(z);
} else if (token == "x") {
return util::toString(x);
} else if (token == "y") {
return util::toString(y);
} else if (token == "prefix") {
std::string prefix{ 2 };
prefix[0] = "0123456789abcdef"[x % 16];
prefix[1] = "0123456789abcdef"[y % 16];
return prefix;
} else if (token == "ratio") {
return std::string(pixelRatio > 1.0 ? "@2x" : "");
} else {
return std::string();
}
}),
Resource::TileData {
urlTemplate,
pixelRatio,
x,
y,
z
}
};
}
}

View File

@@ -67,15 +67,8 @@ GlyphPBF::GlyphPBF(GlyphStore* store,
GlyphStore::Observer* observer_)
: parsed(false),
observer(observer_) {
// Load the glyph set URL
std::string url = util::replaceTokens(store->getURL(), [&](const std::string &name) -> std::string {
if (name == "fontstack") return util::percentEncode(fontStack);
if (name == "range") return util::toString(glyphRange.first) + "-" + util::toString(glyphRange.second);
return "";
});
FileSource* fs = util::ThreadContext::getFileSource();
req = fs->request({ Resource::Kind::Glyphs, url }, [this, store, fontStack, glyphRange](Response res) {
req = fs->request(Resource::glyphs(store->getURL(), fontStack, glyphRange), [this, store, fontStack, glyphRange](Response res) {
if (res.error) {
observer->onGlyphsError(fontStack, glyphRange, std::make_exception_ptr(std::runtime_error(res.error->message)));
return;

View File

@@ -1,7 +1,4 @@
#include <mbgl/util/url.hpp>
#include <mbgl/util/token.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/map/tile_id.hpp>
#include <cctype>
#include <iomanip>
@@ -50,26 +47,5 @@ std::string percentDecode(const std::string& input) {
return decoded;
}
std::string templateTileURL(const std::string& url, const TileID& id, float pixelRatio) {
return util::replaceTokens(url, [&](const std::string& token) -> std::string {
if (token == "z") {
return util::toString(id.sourceZ);
} else if (token == "x") {
return util::toString(id.x);
} else if (token == "y") {
return util::toString(id.y);
} else if (token == "prefix") {
std::string prefix{ 2 };
prefix[0] = "0123456789abcdef"[id.x % 16];
prefix[1] = "0123456789abcdef"[id.y % 16];
return prefix;
} else if (token == "ratio") {
return pixelRatio > 1.0 ? "@2x" : "";
} else {
return "";
}
});
}
} // namespace util
} // namespace mbgl

View File

@@ -5,15 +5,11 @@
namespace mbgl {
class TileID;
namespace util {
std::string percentEncode(const std::string&);
std::string percentDecode(const std::string&);
std::string templateTileURL(const std::string& url, const TileID& id, float pixelRatio = 1);
} // namespace util
} // namespace mbgl

50
test/storage/resource.cpp Normal file
View File

@@ -0,0 +1,50 @@
#include <mbgl/storage/resource.hpp>
#include <gtest/gtest.h>
TEST(Resource, Style) {
using namespace mbgl;
Resource resource = Resource::style("http://example.com");
EXPECT_EQ(Resource::Kind::Style, resource.kind);
EXPECT_EQ("http://example.com", resource.url);
}
TEST(Resource, Source) {
using namespace mbgl;
Resource resource = Resource::source("http://example.com");
EXPECT_EQ(Resource::Kind::Source, resource.kind);
EXPECT_EQ("http://example.com", resource.url);
}
TEST(Resource, Tile) {
using namespace mbgl;
Resource resource = Resource::tile("http://example.com/{z}/{x}/{y}{ratio}.png", 2.0, 1, 2, 3);
EXPECT_EQ(Resource::Kind::Tile, resource.kind);
EXPECT_EQ("http://example.com/3/1/2@2x.png", resource.url);
EXPECT_EQ("http://example.com/{z}/{x}/{y}{ratio}.png", resource.tileData->urlTemplate);
EXPECT_EQ(2.0, resource.tileData->pixelRatio);
EXPECT_EQ(1, resource.tileData->x);
EXPECT_EQ(2, resource.tileData->y);
EXPECT_EQ(3, resource.tileData->z);
}
TEST(Resource, Glyphs) {
using namespace mbgl;
Resource resource = Resource::glyphs("http://example.com/{fontstack}/{range}", "stack", {0, 255});
EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
EXPECT_EQ("http://example.com/stack/0-255", resource.url);
}
TEST(Resource, SpriteImage) {
using namespace mbgl;
Resource resource = Resource::spriteImage("http://example.com/sprite", 2.0);
EXPECT_EQ(Resource::Kind::SpriteImage, resource.kind);
EXPECT_EQ("http://example.com/sprite@2x.png", resource.url);
}
TEST(Resource, SpriteJSON) {
using namespace mbgl;
Resource resource = Resource::spriteJSON("http://example.com/sprite", 2.0);
EXPECT_EQ(Resource::Kind::SpriteJSON, resource.kind);
EXPECT_EQ("http://example.com/sprite@2x.json", resource.url);
}

View File

@@ -87,6 +87,7 @@
'storage/http_retry_network_status.cpp',
'storage/http_reading.cpp',
'storage/http_timeout.cpp',
'storage/resource.cpp',
'style/glyph_store.cpp',
'style/pending_resources.cpp',