[core] introduce a RasterTileMonitor
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <mbgl/tile/vector_tile_source.hpp>
|
||||
#include <mbgl/tile/geojson_tile_source.hpp>
|
||||
#include <mbgl/tile/annotation_tile_source.hpp>
|
||||
#include <mbgl/tile/raster_tile_source.hpp>
|
||||
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
#include <mbgl/tile/raster_tile_data.hpp>
|
||||
@@ -202,9 +203,11 @@ std::unique_ptr<TileData> Source::createTile(const OverscaledTileID& overscaledT
|
||||
|
||||
// If we don't find working tile data, we're just going to load it.
|
||||
if (type == SourceType::Raster) {
|
||||
data = std::make_unique<RasterTileData>(overscaledTileID, parameters.pixelRatio,
|
||||
tileset->tiles.at(0), parameters.texturePool,
|
||||
parameters.worker, parameters.fileSource, callback);
|
||||
std::unique_ptr<RasterTileSource> monitor;
|
||||
monitor = std::make_unique<RasterTileSource>(overscaledTileID, parameters.pixelRatio, tileset->tiles.at(0), parameters.fileSource);
|
||||
|
||||
data = std::make_unique<RasterTileData>(overscaledTileID, std::move(monitor),
|
||||
parameters.texturePool, parameters.worker, callback);
|
||||
} else {
|
||||
std::unique_ptr<GeometryTileSource> monitor;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/tile/raster_tile_data.hpp>
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/tile/raster_tile_source.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
@@ -9,51 +10,51 @@
|
||||
using namespace mbgl;
|
||||
|
||||
RasterTileData::RasterTileData(const OverscaledTileID& id_,
|
||||
float pixelRatio,
|
||||
const std::string& urlTemplate,
|
||||
gl::TexturePool &texturePool_,
|
||||
std::unique_ptr<RasterTileSource> tileSource_,
|
||||
gl::TexturePool& texturePool_,
|
||||
Worker& worker_,
|
||||
FileSource& fileSource,
|
||||
const std::function<void(std::exception_ptr)>& callback)
|
||||
: TileData(id_),
|
||||
: TileData(id_, std::move(tileSource_)),
|
||||
texturePool(texturePool_),
|
||||
worker(worker_) {
|
||||
const Resource resource =
|
||||
Resource::tile(urlTemplate, pixelRatio, id.canonical.x, id.canonical.y, id.canonical.z);
|
||||
req = fileSource.request(resource, [callback, this](Response res) {
|
||||
if (res.error) {
|
||||
callback(std::make_exception_ptr(std::runtime_error(res.error->message)));
|
||||
} else if (res.notModified) {
|
||||
modified = res.modified;
|
||||
expires = res.expires;
|
||||
} else if (res.noContent) {
|
||||
availableData = DataAvailability::All;
|
||||
modified = res.modified;
|
||||
expires = res.expires;
|
||||
workRequest.reset();
|
||||
bucket.reset();
|
||||
callback(nullptr);
|
||||
} else {
|
||||
modified = res.modified;
|
||||
expires = res.expires;
|
||||
|
||||
workRequest.reset();
|
||||
workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), res.data, [this, callback] (RasterTileParseResult result) {
|
||||
workRequest.reset();
|
||||
|
||||
std::exception_ptr error;
|
||||
if (result.is<std::unique_ptr<Bucket>>()) {
|
||||
bucket = std::move(result.get<std::unique_ptr<Bucket>>());
|
||||
} else {
|
||||
error = result.get<std::exception_ptr>();
|
||||
bucket.reset();
|
||||
}
|
||||
|
||||
availableData = DataAvailability::All;
|
||||
|
||||
callback(error);
|
||||
});
|
||||
auto rasterTileSource = reinterpret_cast<RasterTileSource*>(tileSource.get());
|
||||
tileRequest = rasterTileSource->monitorTile([callback, this](std::exception_ptr err,
|
||||
std::shared_ptr<const std::string> data,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
modified = modified_;
|
||||
expires = expires_;
|
||||
|
||||
if (!data) {
|
||||
// This is a 404 response. We're treating these as empty tiles.
|
||||
workRequest.reset();
|
||||
availableData = DataAvailability::All;
|
||||
bucket.reset();
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
workRequest.reset();
|
||||
workRequest = worker.parseRasterTile(std::make_unique<RasterBucket>(texturePool), data, [this, callback] (RasterTileParseResult result) {
|
||||
workRequest.reset();
|
||||
|
||||
std::exception_ptr error;
|
||||
if (result.is<std::unique_ptr<Bucket>>()) {
|
||||
bucket = std::move(result.get<std::unique_ptr<Bucket>>());
|
||||
} else {
|
||||
error = result.get<std::exception_ptr>();
|
||||
bucket.reset();
|
||||
}
|
||||
|
||||
availableData = DataAvailability::All;
|
||||
|
||||
callback(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,6 +67,6 @@ Bucket* RasterTileData::getBucket(const style::Layer&) {
|
||||
}
|
||||
|
||||
void RasterTileData::cancel() {
|
||||
req = nullptr;
|
||||
tileRequest.reset();
|
||||
workRequest.reset();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FileSource;
|
||||
class RasterTileSource;
|
||||
class AsyncRequest;
|
||||
|
||||
namespace gl { class TexturePool; }
|
||||
@@ -17,11 +17,9 @@ class Layer;
|
||||
class RasterTileData : public TileData {
|
||||
public:
|
||||
RasterTileData(const OverscaledTileID&,
|
||||
float pixelRatio,
|
||||
const std::string& urlTemplate,
|
||||
std::unique_ptr<RasterTileSource>,
|
||||
gl::TexturePool&,
|
||||
Worker&,
|
||||
FileSource&,
|
||||
const std::function<void(std::exception_ptr)>& callback);
|
||||
~RasterTileData();
|
||||
|
||||
@@ -31,9 +29,13 @@ public:
|
||||
private:
|
||||
gl::TexturePool& texturePool;
|
||||
Worker& worker;
|
||||
std::unique_ptr<AsyncRequest> req;
|
||||
std::unique_ptr<Bucket> bucket;
|
||||
|
||||
std::unique_ptr<AsyncRequest> tileRequest;
|
||||
std::unique_ptr<AsyncRequest> workRequest;
|
||||
|
||||
// Contains the Bucket object for the tile. Buckets are render
|
||||
// objects and they get added by tile parsing operations.
|
||||
std::unique_ptr<Bucket> bucket;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
31
src/mbgl/tile/raster_tile_source.cpp
Normal file
31
src/mbgl/tile/raster_tile_source.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include <mbgl/tile/raster_tile_source.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
RasterTileSource::RasterTileSource(const OverscaledTileID& tileID_,
|
||||
float pixelRatio_,
|
||||
const std::string& urlTemplate_,
|
||||
FileSource& fileSource_)
|
||||
: tileID(tileID_), pixelRatio(pixelRatio_), urlTemplate(urlTemplate_), fileSource(fileSource_) {
|
||||
}
|
||||
|
||||
std::unique_ptr<AsyncRequest>
|
||||
RasterTileSource::monitorTile(const Callback& callback) {
|
||||
const Resource resource = Resource::tile(urlTemplate, pixelRatio, tileID.canonical.x,
|
||||
tileID.canonical.y, tileID.canonical.z);
|
||||
return fileSource.request(resource, [callback, this](Response res) {
|
||||
if (res.error) {
|
||||
callback(std::make_exception_ptr(std::runtime_error(res.error->message)), nullptr,
|
||||
res.modified, res.expires);
|
||||
} else if (res.notModified) {
|
||||
return;
|
||||
} else if (res.noContent) {
|
||||
callback(nullptr, nullptr, res.modified, res.expires);
|
||||
} else {
|
||||
callback(nullptr, res.data, res.modified, res.expires);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
40
src/mbgl/tile/raster_tile_source.hpp
Normal file
40
src/mbgl/tile/raster_tile_source.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/tile_source.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FileSource;
|
||||
|
||||
class RasterTileSource : public TileSource {
|
||||
public:
|
||||
RasterTileSource(const OverscaledTileID&,
|
||||
float pixelRatio,
|
||||
const std::string& urlTemplate,
|
||||
FileSource&);
|
||||
virtual ~RasterTileSource() = default;
|
||||
|
||||
using Callback = std::function<void(std::exception_ptr,
|
||||
std::shared_ptr<const std::string>,
|
||||
optional<Timestamp> modified,
|
||||
optional<Timestamp> expires)>;
|
||||
|
||||
/*
|
||||
* Monitor the tile held by this object for changes. When the tile is loaded for the first time,
|
||||
* or updates, the callback is executed. If an error occurs, the first parameter will be set.
|
||||
* Otherwise it will be null. If there is no data for the requested tile, the second parameter
|
||||
* will be null.
|
||||
*
|
||||
* To cease monitoring, release the returned Request.
|
||||
*/
|
||||
std::unique_ptr<AsyncRequest> monitorTile(const Callback&);
|
||||
|
||||
private:
|
||||
OverscaledTileID tileID;
|
||||
float pixelRatio;
|
||||
std::string urlTemplate;
|
||||
FileSource& fileSource;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,11 +1,12 @@
|
||||
#include <mbgl/tile/tile_data.hpp>
|
||||
#include <mbgl/tile/tile_source.hpp>
|
||||
#include <mbgl/renderer/debug_bucket.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
TileData::TileData(const OverscaledTileID& id_)
|
||||
: id(id_) {
|
||||
TileData::TileData(const OverscaledTileID& id_, std::unique_ptr<TileSource> tileSource_)
|
||||
: id(id_), tileSource(std::move(tileSource_)) {
|
||||
}
|
||||
|
||||
TileData::~TileData() = default;
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace mbgl {
|
||||
class Worker;
|
||||
class DebugBucket;
|
||||
class TransformState;
|
||||
class TileSource;
|
||||
|
||||
namespace style {
|
||||
class Layer;
|
||||
@@ -26,7 +27,7 @@ class Layer;
|
||||
|
||||
class TileData : private util::noncopyable {
|
||||
public:
|
||||
TileData(const OverscaledTileID&);
|
||||
TileData(const OverscaledTileID&, std::unique_ptr<TileSource>);
|
||||
virtual ~TileData();
|
||||
|
||||
// Mark this tile as no longer needed and cancel any pending work.
|
||||
@@ -63,6 +64,7 @@ public:
|
||||
const OverscaledTileID id;
|
||||
optional<Timestamp> modified;
|
||||
optional<Timestamp> expires;
|
||||
const std::unique_ptr<TileSource> tileSource;
|
||||
|
||||
// Contains the tile ID string for painting debug information.
|
||||
std::unique_ptr<DebugBucket> debugBucket;
|
||||
|
||||
@@ -12,7 +12,12 @@ namespace mbgl {
|
||||
class GeometryTile;
|
||||
class AsyncRequest;
|
||||
|
||||
class GeometryTileSource : private util::noncopyable {
|
||||
class TileSource : private util::noncopyable {
|
||||
public:
|
||||
virtual ~TileSource() = default;
|
||||
};
|
||||
|
||||
class GeometryTileSource : public TileSource {
|
||||
public:
|
||||
virtual ~GeometryTileSource() = default;
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
namespace mbgl {
|
||||
|
||||
VectorTileData::VectorTileData(const OverscaledTileID& id_,
|
||||
std::unique_ptr<GeometryTileSource> monitor_,
|
||||
std::unique_ptr<GeometryTileSource> tileSource_,
|
||||
std::string sourceID,
|
||||
style::Style& style_,
|
||||
const MapMode mode_,
|
||||
const std::function<void(std::exception_ptr)>& callback)
|
||||
: TileData(id_),
|
||||
: TileData(id_, std::move(tileSource_)),
|
||||
style(style_),
|
||||
worker(style_.workers),
|
||||
tileWorker(id_,
|
||||
@@ -27,10 +27,9 @@ VectorTileData::VectorTileData(const OverscaledTileID& id_,
|
||||
*style_.glyphAtlas,
|
||||
*style_.glyphStore,
|
||||
obsolete,
|
||||
mode_),
|
||||
monitor(std::move(monitor_))
|
||||
{
|
||||
tileRequest = monitor->monitorTile([callback, this](std::exception_ptr err,
|
||||
mode_) {
|
||||
auto geometryTileSource = reinterpret_cast<GeometryTileSource*>(tileSource.get());
|
||||
tileRequest = geometryTileSource->monitorTile([callback, this](std::exception_ptr err,
|
||||
std::unique_ptr<GeometryTile> tile,
|
||||
optional<Timestamp> modified_,
|
||||
optional<Timestamp> expires_) {
|
||||
|
||||
@@ -22,7 +22,7 @@ class Style;
|
||||
class VectorTileData : public TileData {
|
||||
public:
|
||||
VectorTileData(const OverscaledTileID&,
|
||||
std::unique_ptr<GeometryTileSource> monitor,
|
||||
std::unique_ptr<GeometryTileSource> tileSource,
|
||||
std::string sourceID,
|
||||
style::Style&,
|
||||
const MapMode,
|
||||
@@ -50,7 +50,6 @@ private:
|
||||
Worker& worker;
|
||||
TileWorker tileWorker;
|
||||
|
||||
std::unique_ptr<GeometryTileSource> monitor;
|
||||
std::unique_ptr<AsyncRequest> tileRequest;
|
||||
std::unique_ptr<AsyncRequest> workRequest;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user