diff options
author | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-05-19 00:38:10 +0300 |
---|---|---|
committer | Thiago Marcos P. Santos <thiago@mapbox.com> | 2015-05-22 10:44:18 +0300 |
commit | ee9b172152c7e462f2c204ea7b85c3cc4bd04582 (patch) | |
tree | a28556dcb66e64ee43f373743934b91650586049 | |
parent | ac64bef87f5c0b3d23be59de984fd93eb7f2378f (diff) | |
download | qtlocation-mapboxgl-ee9b172152c7e462f2c204ea7b85c3cc4bd04582.tar.gz |
Notify failures when loading glyphs
-rw-r--r-- | include/mbgl/util/exception.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/map/resource_loader.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/map/resource_loader.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/text/glyph_store.cpp | 55 | ||||
-rw-r--r-- | src/mbgl/text/glyph_store.hpp | 10 |
5 files changed, 58 insertions, 17 deletions
diff --git a/include/mbgl/util/exception.hpp b/include/mbgl/util/exception.hpp index 7ef8ea9762..da61aa482a 100644 --- a/include/mbgl/util/exception.hpp +++ b/include/mbgl/util/exception.hpp @@ -11,6 +11,11 @@ struct Exception : std::runtime_error { inline Exception(const std::string &msg) : std::runtime_error(msg) {} }; +struct GlyphRangeLoadingException : Exception { + inline GlyphRangeLoadingException(const char *msg) : Exception(msg) {} + inline GlyphRangeLoadingException(const std::string &msg) : Exception(msg) {} +}; + struct MisuseException : Exception { inline MisuseException(const char *msg) : Exception(msg) {} inline MisuseException(const std::string &msg) : Exception(msg) {} diff --git a/src/mbgl/map/resource_loader.cpp b/src/mbgl/map/resource_loader.cpp index ddef11293a..5aa714595d 100644 --- a/src/mbgl/map/resource_loader.cpp +++ b/src/mbgl/map/resource_loader.cpp @@ -104,6 +104,10 @@ void ResourceLoader::onGlyphRangeLoaded() { emitTileDataChanged(); } +void ResourceLoader::onGlyphRangeLoadingFailed(std::exception_ptr error) { + emitResourceLoadingFailed(error); +} + void ResourceLoader::onSourceLoaded() { emitTileDataChanged(); } diff --git a/src/mbgl/map/resource_loader.hpp b/src/mbgl/map/resource_loader.hpp index 9d94cb6495..33949aa487 100644 --- a/src/mbgl/map/resource_loader.hpp +++ b/src/mbgl/map/resource_loader.hpp @@ -63,6 +63,7 @@ public: // GlyphStore::Observer implementation. void onGlyphRangeLoaded() override; + void onGlyphRangeLoadingFailed(std::exception_ptr error) override; // Source::Observer implementation. void onSourceLoaded() override; diff --git a/src/mbgl/text/glyph_store.cpp b/src/mbgl/text/glyph_store.cpp index 4ee853b1ef..72c7b16a84 100644 --- a/src/mbgl/text/glyph_store.cpp +++ b/src/mbgl/text/glyph_store.cpp @@ -1,20 +1,23 @@ #include <mbgl/text/glyph_store.hpp> #include <mbgl/map/environment.hpp> +#include <mbgl/platform/log.hpp> +#include <mbgl/platform/platform.hpp> +#include <mbgl/storage/file_source.hpp> +#include <mbgl/util/constants.hpp> +#include <mbgl/util/exception.hpp> +#include <mbgl/util/math.hpp> +#include <mbgl/util/pbf.hpp> #include <mbgl/util/std.hpp> #include <mbgl/util/string.hpp> -#include <mbgl/util/utf.hpp> -#include <mbgl/util/pbf.hpp> -#include <mbgl/util/url.hpp> -#include <mbgl/util/constants.hpp> #include <mbgl/util/token.hpp> -#include <mbgl/util/math.hpp> +#include <mbgl/util/url.hpp> +#include <mbgl/util/utf.hpp> #include <mbgl/util/uv_detail.hpp> -#include <mbgl/storage/file_source.hpp> -#include <mbgl/platform/log.hpp> -#include <mbgl/platform/platform.hpp> #include <mbgl/util/uv_detail.hpp> + #include <algorithm> +#include <sstream> namespace mbgl { @@ -139,7 +142,8 @@ GlyphPBF::GlyphPBF(const std::string& glyphURL, const std::string& fontStack, GlyphRange glyphRange, Environment& env_, - const GlyphLoadedCallback& callback) + const GlyphLoadedCallback& successCallback, + const GlyphLoadingFailedCallback& failureCallback) : parsed(false), env(env_) { // Load the glyph set URL std::string url = util::replaceTokens(glyphURL, [&](const std::string &name) -> std::string { @@ -149,20 +153,20 @@ GlyphPBF::GlyphPBF(const std::string& glyphURL, }); // The prepare call jumps back to the main thread. - req = env.request({ Resource::Kind::Glyphs, url }, [&, url, callback](const Response &res) { + req = env.request({ Resource::Kind::Glyphs, url }, [&, url, successCallback, failureCallback](const Response &res) { req = nullptr; if (res.status != Response::Successful) { - // Something went wrong with loading the glyph pbf. - const std::string msg = std::string { "[ERROR] failed to load glyphs: " } + url + " message: " + res.message; - Log::Error(Event::HttpRequest, msg); + std::stringstream message; + message << "Failed to load [" << url << "]: " << res.message; + failureCallback(message.str()); } else { // Transfer the data to the GlyphSet and signal its availability. // Once it is available, the caller will need to call parse() to actually // parse the data we received. We are not doing this here since this callback is being // called from another (unknown) thread. data = res.data; - callback(this); + successCallback(this); } }); } @@ -234,8 +238,10 @@ bool GlyphPBF::isParsed() const { GlyphStore::GlyphStore(uv_loop_t* loop, Environment& env_) : env(env_), asyncEmitGlyphRangeLoaded(util::make_unique<uv::async>(loop, [this] { emitGlyphRangeLoaded(); })), + asyncEmitGlyphRangeLoadedingFailed(util::make_unique<uv::async>(loop, [this] { emitGlyphRangeLoadingFailed(); })), observer(nullptr) { asyncEmitGlyphRangeLoaded->unref(); + asyncEmitGlyphRangeLoadedingFailed->unref(); } GlyphStore::~GlyphStore() { @@ -254,19 +260,26 @@ bool GlyphStore::requestGlyphRangesIfNeeded(const std::string& fontStackName, return requestIsNeeded; } - auto callback = [this, fontStackName](GlyphPBF* glyph) { + auto successCallback = [this, fontStackName](GlyphPBF* glyph) { auto fontStack = createFontStack(fontStackName); glyph->parse(**fontStack); asyncEmitGlyphRangeLoaded->send(); }; + auto failureCallback = [this](const std::string& message) { + std::lock_guard<std::mutex> lock(errorMessageMutex); + errorMessage = message; + asyncEmitGlyphRangeLoadedingFailed->send(); + }; + std::lock_guard<std::mutex> lock(rangesMutex); auto& rangeSets = ranges[fontStackName]; for (const auto& range : glyphRanges) { const auto& rangeSets_it = rangeSets.find(range); if (rangeSets_it == rangeSets.end()) { - auto glyph = util::make_unique<GlyphPBF>(glyphURL, fontStackName, range, env, callback); + auto glyph = util::make_unique<GlyphPBF>(glyphURL, fontStackName, range, env, + successCallback, failureCallback); rangeSets.emplace(range, std::move(glyph)); requestIsNeeded = true; continue; @@ -312,4 +325,14 @@ void GlyphStore::emitGlyphRangeLoaded() { } } +void GlyphStore::emitGlyphRangeLoadingFailed() { + if (!observer) { + return; + } + + std::lock_guard<std::mutex> lock(errorMessageMutex); + auto error = std::make_exception_ptr(util::GlyphRangeLoadingException(errorMessage)); + observer->onGlyphRangeLoadingFailed(error); +} + } diff --git a/src/mbgl/text/glyph_store.hpp b/src/mbgl/text/glyph_store.hpp index e13ed1f1d7..77452a3057 100644 --- a/src/mbgl/text/glyph_store.hpp +++ b/src/mbgl/text/glyph_store.hpp @@ -59,12 +59,14 @@ private: class GlyphPBF { public: using GlyphLoadedCallback = std::function<void(GlyphPBF*)>; + using GlyphLoadingFailedCallback = std::function<void(const std::string&)>; GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange, Environment &env, - const GlyphLoadedCallback& callback); + const GlyphLoadedCallback& successCallback, + const GlyphLoadingFailedCallback& failureCallback); ~GlyphPBF(); void parse(FontStack &stack); @@ -91,6 +93,7 @@ public: virtual ~Observer() = default; virtual void onGlyphRangeLoaded() = 0; + virtual void onGlyphRangeLoadingFailed(std::exception_ptr error) = 0; }; GlyphStore(uv_loop_t* loop, Environment &); @@ -110,6 +113,7 @@ public: private: void emitGlyphRangeLoaded(); + void emitGlyphRangeLoadingFailed(); util::exclusive<FontStack> createFontStack(const std::string &fontStack); @@ -122,7 +126,11 @@ private: std::unordered_map<std::string, std::unique_ptr<FontStack>> stacks; std::mutex stacksMutex; + std::string errorMessage; + std::mutex errorMessageMutex; + std::unique_ptr<uv::async> asyncEmitGlyphRangeLoaded; + std::unique_ptr<uv::async> asyncEmitGlyphRangeLoadedingFailed; Observer* observer; }; |