Add callback for error notifications on renderStill()

The callback will be called when any of the resources requested
from the network failed to load.

There is not recovery implemented yet, so the closest thing to
reseting the Map object and reloading all the resources would
be setting a new style.
This commit is contained in:
Thiago Marcos P. Santos
2015-05-19 01:13:46 +03:00
parent b304b20073
commit da81211fea
9 changed files with 46 additions and 7 deletions

View File

@@ -111,7 +111,16 @@ int main(int argc, char *argv[]) {
util::write_file(output, png);
});
map.renderStill([async](std::unique_ptr<const StillImage> image) {
map.renderStill([async](std::exception_ptr error, std::unique_ptr<const StillImage> image) {
try {
if (error) {
std::rethrow_exception(error);
}
} catch(std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
exit(1);
}
async->data = const_cast<StillImage *>(image.release());
uv_async_send(async);
});

View File

@@ -42,7 +42,7 @@ public:
// Register a callback that will get called (on the render thread) when all resources have
// been loaded and a complete render occurs.
using StillImageCallback = std::function<void(std::unique_ptr<const StillImage>)>;
using StillImageCallback = std::function<void(std::exception_ptr, std::unique_ptr<const StillImage>)>;
void renderStill(StillImageCallback callback);
// Triggers a synchronous or asynchronous render.

View File

@@ -29,6 +29,7 @@ enum class Event : uint8_t {
ParseStyle,
ParseTile,
Render,
ResourceLoader,
Database,
HttpRequest,
Sprite,
@@ -46,6 +47,7 @@ MBGL_DEFINE_ENUM_CLASS(EventClass, Event, {
{ Event::ParseStyle, "ParseStyle" },
{ Event::ParseTile, "ParseTile" },
{ Event::Render, "Render" },
{ Event::ResourceLoader, "ResourceLoader" },
{ Event::Database, "Database" },
{ Event::HttpRequest, "HttpRequest" },
{ Event::Sprite, "Sprite" },

View File

@@ -232,7 +232,7 @@ void MapContext::render() {
painter->render(*style, transformState, data.getAnimationTime());
if (data.mode == MapMode::Still) {
callback(view.readStillImage());
callback(nullptr, view.readStillImage());
callback = nullptr;
}
@@ -274,4 +274,13 @@ void MapContext::onTileDataChanged() {
triggerUpdate();
}
void MapContext::onResourceLoadingFailed(std::exception_ptr error) {
assert(Environment::currentlyOn(ThreadType::Map));
if (data.mode == MapMode::Still && callback) {
callback(error, nullptr);
callback = nullptr;
}
}
}

View File

@@ -43,7 +43,7 @@ public:
void resize(uint16_t width, uint16_t height, float ratio);
using StillImageCallback = std::function<void(std::unique_ptr<const StillImage>)>;
using StillImageCallback = std::function<void(std::exception_ptr, std::unique_ptr<const StillImage>)>;
void renderStill(StillImageCallback callback);
void triggerUpdate(Update = Update::Nothing);
@@ -61,6 +61,7 @@ public:
// ResourceLoader::Observer implementation.
void onTileDataChanged() override;
void onResourceLoadingFailed(std::exception_ptr error) override;
private:
void updateTiles();

View File

@@ -130,4 +130,20 @@ void ResourceLoader::emitTileDataChanged() {
}
}
void ResourceLoader::emitResourceLoadingFailed(std::exception_ptr error) {
assert(Environment::currentlyOn(ThreadType::Map));
try {
if (error) {
std::rethrow_exception(error);
}
} catch(const std::exception& e) {
Log::Error(Event::ResourceLoader, e.what());
}
if (observer_) {
observer_->onResourceLoadingFailed(error);
}
}
}

View File

@@ -32,6 +32,7 @@ public:
virtual ~Observer() = default;
virtual void onTileDataChanged() = 0;
virtual void onResourceLoadingFailed(std::exception_ptr error) = 0;
};
ResourceLoader();
@@ -72,6 +73,7 @@ public:
private:
void emitTileDataChanged();
void emitResourceLoadingFailed(std::exception_ptr error);
bool shouldReparsePartialTiles_ = false;

View File

@@ -28,7 +28,7 @@ TEST(API, RepeatedRender) {
map.resize(128, 512, 1);
map.setStyleJSON(style, "test/suite");
std::promise<std::unique_ptr<const StillImage>> promise;
map.renderStill([&promise](std::unique_ptr<const StillImage> image) {
map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) {
promise.set_value(std::move(image));
});
auto result = promise.get_future().get();
@@ -42,7 +42,7 @@ TEST(API, RepeatedRender) {
map.resize(512, 512, 2);
map.setStyleJSON(style, "TEST_DATA/suite");
std::promise<std::unique_ptr<const StillImage>> promise;
map.renderStill([&promise](std::unique_ptr<const StillImage> image) {
map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) {
promise.set_value(std::move(image));
});
auto result = promise.get_future().get();

View File

@@ -152,7 +152,7 @@ TEST_P(HeadlessTest, render) {
map.setLatLngZoom(mbgl::LatLng(latitude, longitude), zoom);
map.setBearing(bearing);
map.renderStill([&](std::unique_ptr<const StillImage> image) {
map.renderStill([&](std::exception_ptr, std::unique_ptr<const StillImage> image) {
const std::string png = util::compress_png(image->width, image->height, image->pixels.get());
util::write_file("test/suite/tests/" + base + "/" + name + "/actual.png", png);
promise.set_value();