Notify failures when loading tiles
This commit is contained in:
@@ -31,6 +31,11 @@ struct SpriteLoadingException : Exception {
|
||||
inline SpriteLoadingException(const std::string &msg) : Exception(msg) {}
|
||||
};
|
||||
|
||||
struct TileLoadingException : Exception {
|
||||
inline TileLoadingException(const char *msg) : Exception(msg) {}
|
||||
inline TileLoadingException(const std::string &msg) : Exception(msg) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,10 @@ void ResourceLoader::onTileLoaded(bool isNewTile) {
|
||||
emitTileDataChanged();
|
||||
}
|
||||
|
||||
void ResourceLoader::onTileLoadingFailed(std::exception_ptr error) {
|
||||
emitResourceLoadingFailed(error);
|
||||
}
|
||||
|
||||
void ResourceLoader::onSpriteLoaded() {
|
||||
shouldReparsePartialTiles_ = true;
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
void onSourceLoaded() override;
|
||||
void onSourceLoadingFailed(std::exception_ptr error) override;
|
||||
void onTileLoaded(bool isNewTile) override;
|
||||
void onTileLoadingFailed(std::exception_ptr error) override;
|
||||
|
||||
// Sprite::Observer implementation.
|
||||
void onSpriteLoaded() override;
|
||||
|
||||
@@ -287,22 +287,26 @@ TileData::State Source::addTile(MapData& data,
|
||||
new_tile.data = cache.get(normalized_id.to_uint64());
|
||||
}
|
||||
|
||||
auto callback = std::bind(&Source::emitTileLoaded, this, true);
|
||||
auto successCallback = std::bind(&Source::emitTileLoaded, this, true);
|
||||
auto failureCallback = std::bind(&Source::emitTileLoadingFailed, this, std::placeholders::_1);
|
||||
|
||||
if (!new_tile.data) {
|
||||
// If we don't find working tile data, we're just going to load it.
|
||||
if (info.type == SourceType::Vector) {
|
||||
new_tile.data =
|
||||
std::make_shared<VectorTileData>(normalized_id, data.transform.getMaxZoom(), style, glyphAtlas,
|
||||
glyphStore, spriteAtlas, sprite, info);
|
||||
new_tile.data->request(style.workers, transformState.getPixelRatio(), callback);
|
||||
new_tile.data->request(
|
||||
style.workers, transformState.getPixelRatio(), successCallback, failureCallback);
|
||||
} else if (info.type == SourceType::Raster) {
|
||||
new_tile.data = std::make_shared<RasterTileData>(normalized_id, texturePool, info);
|
||||
new_tile.data->request(style.workers, transformState.getPixelRatio(), callback);
|
||||
new_tile.data->request(
|
||||
style.workers, transformState.getPixelRatio(), successCallback, failureCallback);
|
||||
} else if (info.type == SourceType::Annotations) {
|
||||
new_tile.data = std::make_shared<LiveTileData>(normalized_id, data.annotationManager,
|
||||
data.transform.getMaxZoom(), style, glyphAtlas,
|
||||
glyphStore, spriteAtlas, sprite, info);
|
||||
new_tile.data->reparse(style.workers, callback);
|
||||
new_tile.data->reparse(style.workers, successCallback);
|
||||
} else {
|
||||
throw std::runtime_error("source type not implemented");
|
||||
}
|
||||
@@ -556,4 +560,13 @@ void Source::emitTileLoaded(bool isNewTile) {
|
||||
}
|
||||
}
|
||||
|
||||
void Source::emitTileLoadingFailed(const std::string& message) {
|
||||
if (!observer_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto error = std::make_exception_ptr(util::TileLoadingException(message));
|
||||
observer_->onTileLoadingFailed(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
virtual void onSourceLoadingFailed(std::exception_ptr error) = 0;
|
||||
|
||||
virtual void onTileLoaded(bool isNewTile) = 0;
|
||||
virtual void onTileLoadingFailed(std::exception_ptr error) = 0;
|
||||
};
|
||||
|
||||
Source();
|
||||
@@ -106,6 +107,7 @@ private:
|
||||
void emitSourceLoaded();
|
||||
void emitSourceLoadingFailed(const std::string& message);
|
||||
void emitTileLoaded(bool isNewTile);
|
||||
void emitTileLoadingFailed(const std::string& message);
|
||||
|
||||
bool handlePartialTile(const TileID &id, Worker &worker);
|
||||
bool findLoadedChildren(const TileID& id, int32_t maxCoveringZoom, std::forward_list<TileID>& retain);
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include <mbgl/map/tile_data.hpp>
|
||||
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/map/source.hpp>
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
#include <mbgl/util/work_request.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/util/work_request.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
@@ -34,15 +36,20 @@ void TileData::setState(const State& state_) {
|
||||
state = state_;
|
||||
}
|
||||
|
||||
void TileData::request(Worker& worker, float pixelRatio, std::function<void()> callback) {
|
||||
void TileData::request(Worker& worker,
|
||||
float pixelRatio,
|
||||
const std::function<void()>& successCallback,
|
||||
const std::function<void(const std::string& message)>& failureCallback) {
|
||||
std::string url = source.tileURL(id, pixelRatio);
|
||||
state = State::loading;
|
||||
|
||||
req = env.request({ Resource::Kind::Tile, url }, [url, callback, &worker, this](const Response &res) {
|
||||
req = env.request({ Resource::Kind::Tile, url }, [url, successCallback, failureCallback, &worker, this](const Response &res) {
|
||||
req = nullptr;
|
||||
|
||||
if (res.status != Response::Successful) {
|
||||
Log::Error(Event::HttpRequest, "[%s] tile loading failed: %s", url.c_str(), res.message.c_str());
|
||||
std::stringstream message;
|
||||
message << "Failed to load [" << url << "]: " << res.message;
|
||||
failureCallback(message.str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -50,7 +57,7 @@ void TileData::request(Worker& worker, float pixelRatio, std::function<void()> c
|
||||
data = res.data;
|
||||
|
||||
// Schedule tile parsing in another thread
|
||||
reparse(worker, callback);
|
||||
reparse(worker, successCallback);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,10 @@ public:
|
||||
TileData(const TileID&, const SourceInfo&);
|
||||
~TileData();
|
||||
|
||||
void request(Worker&, float pixelRatio, std::function<void ()> callback);
|
||||
void request(Worker&,
|
||||
float pixelRatio,
|
||||
const std::function<void()>& successCallback,
|
||||
const std::function<void(const std::string& message)>& failureCallback);
|
||||
|
||||
// Schedule a tile reparse on a worker thread and call the callback on
|
||||
// completion. It will return true if the work was schedule or false it was
|
||||
|
||||
Reference in New Issue
Block a user