summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-05-19 00:38:10 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2015-05-22 10:44:18 +0300
commitee9b172152c7e462f2c204ea7b85c3cc4bd04582 (patch)
treea28556dcb66e64ee43f373743934b91650586049
parentac64bef87f5c0b3d23be59de984fd93eb7f2378f (diff)
downloadqtlocation-mapboxgl-ee9b172152c7e462f2c204ea7b85c3cc4bd04582.tar.gz
Notify failures when loading glyphs
-rw-r--r--include/mbgl/util/exception.hpp5
-rw-r--r--src/mbgl/map/resource_loader.cpp4
-rw-r--r--src/mbgl/map/resource_loader.hpp1
-rw-r--r--src/mbgl/text/glyph_store.cpp55
-rw-r--r--src/mbgl/text/glyph_store.hpp10
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;
};