Merge branch 'master' into android-mason
Conflicts: gyp/mbgl-ios.gypi gyp/mbgl-linux.gypi gyp/mbgl-osx.gypi platform/default/caching_http_file_source.cpp
This commit is contained in:
@@ -4,12 +4,32 @@
|
||||
'product_name': 'mbgl-headless',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'variables': {
|
||||
'cflags_cc': [
|
||||
'<@(uv_cflags)',
|
||||
],
|
||||
'cflags': [
|
||||
'<@(uv_cflags)',
|
||||
],
|
||||
},
|
||||
'include_dirs': [
|
||||
'../include',
|
||||
],
|
||||
'conditions': [
|
||||
['OS == "mac"', {
|
||||
'xcode_settings': {
|
||||
'OTHER_CPLUSPLUSFLAGS': [ '<@(cflags_cc)' ],
|
||||
'OTHER_CFLAGS': [ '<@(cflags)' ],
|
||||
}
|
||||
}, {
|
||||
'cflags_cc': [ '<@(cflags_cc)' ],
|
||||
'cflags': [ '<@(cflags)' ],
|
||||
}]
|
||||
],
|
||||
'sources': [
|
||||
'../platform/default/headless_view.cpp',
|
||||
'../platform/default/headless_display.cpp',
|
||||
'../platform/default/caching_http_file_source.cpp',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_baton_cocoa.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
'../platform/default/caching_http_file_source.cpp',
|
||||
'../platform/default/asset_request_baton_noop.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
'../platform/default/image_reader.cpp',
|
||||
'../platform/default/png_reader.cpp',
|
||||
'../platform/default/jpeg_reader.cpp',
|
||||
'../platform/default/caching_http_file_source.cpp',
|
||||
'../platform/default/asset_request_baton_noop.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
'../platform/darwin/string_nsstring.mm',
|
||||
'../platform/darwin/http_request_baton_cocoa.mm',
|
||||
'../platform/darwin/image.mm',
|
||||
'../platform/default/caching_http_file_source.cpp',
|
||||
'../platform/default/asset_request_baton_noop.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
|
||||
@@ -34,7 +34,7 @@ class Map : private util::noncopyable {
|
||||
typedef void (*stop_callback)(void *);
|
||||
|
||||
public:
|
||||
explicit Map(View &view);
|
||||
explicit Map(View&, FileSource&);
|
||||
~Map();
|
||||
|
||||
// Start the map render thread. It is asynchronous.
|
||||
@@ -197,7 +197,7 @@ private:
|
||||
Transform transform;
|
||||
TransformState state;
|
||||
|
||||
util::ptr<FileSource> fileSource;
|
||||
FileSource& fileSource;
|
||||
|
||||
util::ptr<Style> style;
|
||||
GlyphAtlas glyphAtlas;
|
||||
|
||||
52
include/mbgl/platform/default/caching_http_file_source.hpp
Normal file
52
include/mbgl/platform/default/caching_http_file_source.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef MBGL_STORAGE_CACHING_HTTP_FILE_SOURCE
|
||||
#define MBGL_STORAGE_CACHING_HTTP_FILE_SOURCE
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
typedef struct uv_messenger_s uv_messenger_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class BaseRequest;
|
||||
class SQLiteStore;
|
||||
|
||||
class CachingHTTPFileSource : public FileSource {
|
||||
public:
|
||||
CachingHTTPFileSource(uv_loop_t*, const std::string &path_);
|
||||
CachingHTTPFileSource(const std::string &path_);
|
||||
~CachingHTTPFileSource();
|
||||
|
||||
// Stores and checks the libuv loop for requests
|
||||
void setLoop(uv_loop_t*);
|
||||
bool hasLoop();
|
||||
|
||||
// Stores and retrieves the base path/URL for relative requests
|
||||
void setBase(const std::string &value);
|
||||
const std::string &getBase() const;
|
||||
|
||||
std::unique_ptr<Request> request(ResourceType type, const std::string &url);
|
||||
|
||||
void prepare(std::function<void()> fn);
|
||||
|
||||
void retryAllPending();
|
||||
|
||||
private:
|
||||
unsigned long thread_id;
|
||||
|
||||
// Path to the cache database.
|
||||
std::string path;
|
||||
|
||||
// Stores a URL that is used as a base for loading resources with relative path.
|
||||
std::string base;
|
||||
|
||||
std::unordered_map<std::string, std::weak_ptr<BaseRequest>> pending;
|
||||
util::ptr<SQLiteStore> store;
|
||||
uv_loop_t *loop = nullptr;
|
||||
uv_messenger_t *queue = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,48 +1,25 @@
|
||||
#ifndef MBGL_STORAGE_FILE_SOURCE
|
||||
#define MBGL_STORAGE_FILE_SOURCE
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/storage/resource_type.hpp>
|
||||
#include <mbgl/storage/request.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
typedef struct uv_loop_s uv_loop_t;
|
||||
typedef struct uv_messenger_s uv_messenger_t;
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class BaseRequest;
|
||||
class SQLiteStore;
|
||||
|
||||
class FileSource : public util::noncopyable {
|
||||
private:
|
||||
public:
|
||||
FileSource(uv_loop_t *loop, const std::string &path);
|
||||
~FileSource();
|
||||
|
||||
// Stores and retrieves the base path/URL for relative requests
|
||||
void setBase(const std::string &value);
|
||||
const std::string &getBase() const;
|
||||
|
||||
std::unique_ptr<Request> request(ResourceType type, const std::string &url);
|
||||
|
||||
void prepare(std::function<void()> fn);
|
||||
|
||||
void retryAllPending();
|
||||
|
||||
private:
|
||||
const unsigned long thread_id;
|
||||
|
||||
// Stores a URL that is used as a base for loading resources with relative path.
|
||||
std::string base;
|
||||
|
||||
std::unordered_map<std::string, std::weak_ptr<BaseRequest>> pending;
|
||||
util::ptr<SQLiteStore> store;
|
||||
uv_loop_t *loop = nullptr;
|
||||
uv_messenger_t *queue = nullptr;
|
||||
virtual void setLoop(uv_loop_t*) = 0;
|
||||
virtual bool hasLoop() = 0;
|
||||
virtual void setBase(const std::string &value) = 0;
|
||||
virtual std::unique_ptr<Request> request(ResourceType type, const std::string &url) = 0;
|
||||
virtual void prepare(std::function<void()> fn) = 0;
|
||||
virtual void retryAllPending() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <mbgl/platform/default/settings_json.hpp>
|
||||
#include <mbgl/platform/default/glfw_view.hpp>
|
||||
#include <mbgl/platform/default/log_stderr.hpp>
|
||||
#include <mbgl/platform/default/caching_http_file_source.hpp>
|
||||
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
@@ -63,7 +64,8 @@ int main(int argc, char *argv[]) {
|
||||
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||
|
||||
view = new GLFWView();
|
||||
mbgl::Map map(*view);
|
||||
mbgl::CachingHTTPFileSource fileSource(mbgl::platform::defaultCacheDatabase());
|
||||
mbgl::Map map(*view, fileSource);
|
||||
|
||||
// Load settings
|
||||
mbgl::Settings_JSON settings;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <mbgl/platform/darwin/log_nslog.hpp>
|
||||
#include <mbgl/platform/darwin/Reachability.h>
|
||||
#include <mbgl/platform/default/glfw_view.hpp>
|
||||
#include <mbgl/platform/default/caching_http_file_source.hpp>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -72,7 +73,8 @@ int main() {
|
||||
mbgl::Log::Set<mbgl::NSLogBackend>();
|
||||
|
||||
GLFWView view;
|
||||
mbgl::Map map(view);
|
||||
mbgl::CachingHTTPFileSource fileSource(mbgl::platform::defaultCacheDatabase());
|
||||
mbgl::Map map(view, fileSource);
|
||||
mbgl::Map *map_ptr = ↦
|
||||
|
||||
URLHandler *handler = [[URLHandler alloc] init];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/platform/default/caching_http_file_source.hpp>
|
||||
#include <mbgl/storage/file_request.hpp>
|
||||
#include <mbgl/storage/http_request.hpp>
|
||||
#include <mbgl/storage/sqlite_store.hpp>
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
FileSource::FileSource(uv_loop_t *loop_, const std::string &path)
|
||||
CachingHTTPFileSource::CachingHTTPFileSource(uv_loop_t* loop_, const std::string &path_)
|
||||
: thread_id(uv_thread_self()),
|
||||
path(path_),
|
||||
store(!path.empty() ? util::ptr<SQLiteStore>(new SQLiteStore(loop_, path)) : nullptr),
|
||||
loop(loop_),
|
||||
queue(new uv_messenger_t) {
|
||||
@@ -23,34 +24,56 @@ FileSource::FileSource(uv_loop_t *loop_, const std::string &path)
|
||||
uv_unref((uv_handle_t *)&queue->async);
|
||||
}
|
||||
|
||||
FileSource::~FileSource() {
|
||||
// FIXME temp fix for #608 crash
|
||||
//assert(thread_id == uv_thread_self());
|
||||
uv_messenger_stop(queue, [](uv_messenger_t *msgr) {
|
||||
delete msgr;
|
||||
});
|
||||
CachingHTTPFileSource::CachingHTTPFileSource(const std::string &path_)
|
||||
: path(path_) {}
|
||||
|
||||
util::ptr<BaseRequest> req;
|
||||
CachingHTTPFileSource::~CachingHTTPFileSource() {
|
||||
if (hasLoop()) {
|
||||
// FIXME temp fix for #608 crash
|
||||
// assert(thread_id == uv_thread_self());
|
||||
uv_messenger_stop(queue, [](uv_messenger_t *msgr) {
|
||||
delete msgr;
|
||||
});
|
||||
|
||||
// Send a cancel() message to all requests that we are still holding.
|
||||
for (const std::pair<std::string, std::weak_ptr<BaseRequest>> &pair : pending) {
|
||||
if ((req = pair.second.lock())) {
|
||||
req->cancel();
|
||||
util::ptr<BaseRequest> req;
|
||||
|
||||
// Send a cancel() message to all requests that we are still holding.
|
||||
for (const std::pair<std::string, std::weak_ptr<BaseRequest>> &pair : pending) {
|
||||
if ((req = pair.second.lock())) {
|
||||
req->cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSource::setBase(const std::string &value) {
|
||||
void CachingHTTPFileSource::setLoop(uv_loop_t* loop_) {
|
||||
thread_id = uv_thread_self();
|
||||
store = !path.empty() ? util::ptr<SQLiteStore>(new SQLiteStore(loop_, path)) : nullptr;
|
||||
loop = loop_;
|
||||
queue = new uv_messenger_t;
|
||||
|
||||
uv_messenger_init(loop, queue, [](void *ptr) {
|
||||
std::unique_ptr<std::function<void()>> fn { reinterpret_cast<std::function<void()> *>(ptr) };
|
||||
(*fn)();
|
||||
});
|
||||
uv_unref((uv_handle_t *)&queue->async);
|
||||
}
|
||||
|
||||
bool CachingHTTPFileSource::hasLoop() {
|
||||
return loop;
|
||||
}
|
||||
|
||||
void CachingHTTPFileSource::setBase(const std::string &value) {
|
||||
assert(thread_id == uv_thread_self());
|
||||
base = value;
|
||||
}
|
||||
|
||||
const std::string &FileSource::getBase() const {
|
||||
const std::string &CachingHTTPFileSource::getBase() const {
|
||||
assert(thread_id == uv_thread_self());
|
||||
return base;
|
||||
}
|
||||
|
||||
std::unique_ptr<Request> FileSource::request(ResourceType type, const std::string &url) {
|
||||
std::unique_ptr<Request> CachingHTTPFileSource::request(ResourceType type, const std::string &url) {
|
||||
assert(thread_id == uv_thread_self());
|
||||
|
||||
// Make URL absolute.
|
||||
@@ -87,7 +110,7 @@ std::unique_ptr<Request> FileSource::request(ResourceType type, const std::strin
|
||||
return util::make_unique<Request>(req);
|
||||
}
|
||||
|
||||
void FileSource::prepare(std::function<void()> fn) {
|
||||
void CachingHTTPFileSource::prepare(std::function<void()> fn) {
|
||||
if (thread_id == uv_thread_self()) {
|
||||
fn();
|
||||
} else {
|
||||
@@ -95,7 +118,7 @@ void FileSource::prepare(std::function<void()> fn) {
|
||||
}
|
||||
}
|
||||
|
||||
void FileSource::retryAllPending() {
|
||||
void CachingHTTPFileSource::retryAllPending() {
|
||||
assert(thread_id == uv_thread_self());
|
||||
|
||||
util::ptr<BaseRequest> req;
|
||||
@@ -90,13 +90,14 @@ const static bool sqlite_version_check = []() {
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
Map::Map(View& view_)
|
||||
Map::Map(View& view_, FileSource& fileSource_)
|
||||
: loop(util::make_unique<uv::loop>()),
|
||||
view(view_),
|
||||
#ifndef NDEBUG
|
||||
mainThread(uv_thread_self()),
|
||||
#endif
|
||||
transform(view_),
|
||||
fileSource(fileSource_),
|
||||
glyphAtlas(1024, 1024),
|
||||
spriteAtlas(512, 512),
|
||||
texturePool(std::make_shared<TexturePool>()),
|
||||
@@ -120,7 +121,6 @@ Map::~Map() {
|
||||
glyphStore.reset();
|
||||
style.reset();
|
||||
texturePool.reset();
|
||||
fileSource.reset();
|
||||
workers.reset();
|
||||
|
||||
uv_run(**loop, UV_RUN_DEFAULT);
|
||||
@@ -150,7 +150,6 @@ void Map::start(bool startPaused) {
|
||||
|
||||
// Remove all of these to make sure they are destructed in the correct thread.
|
||||
glyphStore.reset();
|
||||
fileSource.reset();
|
||||
style.reset();
|
||||
workers.reset();
|
||||
activeSources.clear();
|
||||
@@ -371,11 +370,9 @@ void Map::terminate() {
|
||||
void Map::setReachability(bool reachable) {
|
||||
// Note: This function may be called from *any* thread.
|
||||
if (reachable) {
|
||||
if (fileSource) {
|
||||
fileSource->prepare([&]() {
|
||||
fileSource->retryAllPending();
|
||||
});
|
||||
}
|
||||
fileSource.prepare([&]() {
|
||||
fileSource.retryAllPending();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,11 +404,11 @@ void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) {
|
||||
}
|
||||
|
||||
style->loadJSON((const uint8_t *)styleJSON.c_str());
|
||||
if (!fileSource) {
|
||||
fileSource = std::make_shared<FileSource>(**loop, platform::defaultCacheDatabase());
|
||||
glyphStore = std::make_shared<GlyphStore>(*fileSource);
|
||||
if (!fileSource.hasLoop()) {
|
||||
fileSource.setLoop(**loop);
|
||||
glyphStore = std::make_shared<GlyphStore>(fileSource);
|
||||
}
|
||||
fileSource->setBase(base);
|
||||
fileSource.setBase(base);
|
||||
glyphStore->setURL(util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken()));
|
||||
|
||||
style->setDefaultTransitionDuration(defaultTransitionDuration);
|
||||
@@ -447,7 +444,7 @@ util::ptr<Sprite> Map::getSprite() {
|
||||
const float pixelRatio = state.getPixelRatio();
|
||||
const std::string &sprite_url = style->getSpriteURL();
|
||||
if (!sprite || sprite->pixelRatio != pixelRatio) {
|
||||
sprite = Sprite::Create(sprite_url, pixelRatio, *fileSource);
|
||||
sprite = Sprite::Create(sprite_url, pixelRatio, fileSource);
|
||||
}
|
||||
|
||||
return sprite;
|
||||
@@ -671,7 +668,7 @@ void Map::updateSources() {
|
||||
if (source->enabled) {
|
||||
if (!source->source) {
|
||||
source->source = std::make_shared<Source>(source->info);
|
||||
source->source->load(*this, *fileSource);
|
||||
source->source->load(*this, fileSource);
|
||||
}
|
||||
} else {
|
||||
source->source.reset();
|
||||
@@ -705,20 +702,20 @@ void Map::updateTiles() {
|
||||
source->source->update(*this, getWorker(),
|
||||
style, glyphAtlas, *glyphStore,
|
||||
spriteAtlas, getSprite(),
|
||||
*texturePool, *fileSource, [this](){ update(); });
|
||||
*texturePool, fileSource, [this](){ update(); });
|
||||
}
|
||||
}
|
||||
|
||||
void Map::prepare() {
|
||||
if (!fileSource) {
|
||||
fileSource = std::make_shared<FileSource>(**loop, platform::defaultCacheDatabase());
|
||||
glyphStore = std::make_shared<GlyphStore>(*fileSource);
|
||||
if (!fileSource.hasLoop()) {
|
||||
fileSource.setLoop(**loop);
|
||||
glyphStore = std::make_shared<GlyphStore>(fileSource);
|
||||
}
|
||||
|
||||
if (!style) {
|
||||
style = std::make_shared<Style>();
|
||||
|
||||
fileSource->request(ResourceType::JSON, styleURL)->onload([&](const Response &res) {
|
||||
fileSource.request(ResourceType::JSON, styleURL)->onload([&](const Response &res) {
|
||||
if (res.code == 200) {
|
||||
// Calculate the base
|
||||
const size_t pos = styleURL.rfind('/');
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <mbgl/platform/default/headless_view.hpp>
|
||||
#include <mbgl/platform/default/headless_display.hpp>
|
||||
#include <mbgl/platform/default/caching_http_file_source.hpp>
|
||||
|
||||
#include "./fixtures/fixture_log.hpp"
|
||||
|
||||
@@ -184,7 +185,8 @@ TEST_P(HeadlessTest, render) {
|
||||
}
|
||||
|
||||
HeadlessView view(env->display);
|
||||
Map map(view);
|
||||
CachingHTTPFileSource fileSource(platform::defaultCacheDatabase());
|
||||
Map map(view, fileSource);
|
||||
|
||||
map.setStyleJSON(style, base_directory);
|
||||
map.setAppliedClasses(classes);
|
||||
|
||||
Reference in New Issue
Block a user