summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMike Morris <michael.patrick.morris@gmail.com>2014-10-10 12:24:45 -0400
committerMike Morris <michael.patrick.morris@gmail.com>2014-10-10 12:24:45 -0400
commit2d1219fa5154c489cd856bedd04b84573d45ac04 (patch)
treea8e42e6acd79f73aac228e0fe6876917067db8c4 /include
parent8f6e8eead12c6b2c2de0ce76fa7df39ca2445006 (diff)
parentf390dab0ea7d449bdd89855c84e47f4a07606fe4 (diff)
downloadqtlocation-mapboxgl-2d1219fa5154c489cd856bedd04b84573d45ac04.tar.gz
Merge branch 'master' into libuv-0.10-headless-display
Conflicts: common/curl_request.cpp common/glfw_view.cpp common/glfw_view.hpp include/mbgl/platform/request.hpp ios/mapbox-gl-cocoa setup-libraries.sh src/map/map.cpp src/platform/request.cpp test/fixtures/fixture_request.cpp
Diffstat (limited to 'include')
-rw-r--r--include/mbgl/map/map.hpp80
-rw-r--r--include/mbgl/map/raster_tile_data.hpp8
-rw-r--r--include/mbgl/map/source.hpp10
-rw-r--r--include/mbgl/map/sprite.hpp6
-rw-r--r--include/mbgl/map/tile.hpp4
-rw-r--r--include/mbgl/map/tile_data.hpp17
-rw-r--r--include/mbgl/map/tile_parser.hpp30
-rw-r--r--include/mbgl/map/transform.hpp8
-rw-r--r--include/mbgl/map/vector_tile_data.hpp6
-rw-r--r--include/mbgl/map/view.hpp2
-rw-r--r--include/mbgl/platform/event.hpp2
-rw-r--r--include/mbgl/platform/platform.hpp21
-rw-r--r--include/mbgl/platform/request.hpp41
-rw-r--r--include/mbgl/renderer/bucket.hpp6
-rw-r--r--include/mbgl/renderer/debug_bucket.hpp3
-rw-r--r--include/mbgl/renderer/fill_bucket.hpp2
-rw-r--r--include/mbgl/renderer/line_bucket.hpp5
-rw-r--r--include/mbgl/renderer/painter.hpp17
-rw-r--r--include/mbgl/renderer/raster_bucket.hpp4
-rw-r--r--include/mbgl/renderer/symbol_bucket.hpp2
-rw-r--r--include/mbgl/storage/base_request.hpp62
-rw-r--r--include/mbgl/storage/file_request.hpp27
-rw-r--r--include/mbgl/storage/file_request_baton.hpp35
-rw-r--r--include/mbgl/storage/file_source.hpp55
-rw-r--r--include/mbgl/storage/http_request.hpp57
-rw-r--r--include/mbgl/storage/http_request_baton.hpp73
-rw-r--r--include/mbgl/storage/request.hpp39
-rw-r--r--include/mbgl/storage/request_callback.hpp22
-rw-r--r--include/mbgl/storage/resource_type.hpp18
-rw-r--r--include/mbgl/storage/response.hpp26
-rw-r--r--include/mbgl/storage/sqlite_store.hpp47
-rw-r--r--include/mbgl/style/style.hpp4
-rw-r--r--include/mbgl/style/style_bucket.hpp6
-rw-r--r--include/mbgl/style/style_layer.hpp7
-rw-r--r--include/mbgl/style/style_layer_group.hpp2
-rw-r--r--include/mbgl/style/style_parser.hpp18
-rw-r--r--include/mbgl/style/style_source.hpp14
-rw-r--r--include/mbgl/text/glyph_store.hpp14
-rw-r--r--include/mbgl/util/compression.hpp15
-rw-r--r--include/mbgl/util/filesource.hpp43
-rw-r--r--include/mbgl/util/interpolate.hpp2
-rw-r--r--include/mbgl/util/parsedate.h38
-rw-r--r--include/mbgl/util/ptr.hpp29
-rw-r--r--include/mbgl/util/queue.h92
-rw-r--r--include/mbgl/util/raster.hpp8
-rw-r--r--include/mbgl/util/sqlite3.hpp74
-rw-r--r--include/mbgl/util/uv-channel.h29
-rw-r--r--include/mbgl/util/uv-messenger.h32
-rw-r--r--include/mbgl/util/uv-worker.h42
-rw-r--r--include/mbgl/util/uv.hpp7
-rw-r--r--include/mbgl/util/uv_detail.hpp52
51 files changed, 1011 insertions, 252 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index ac33dba0ef..7e4687ea6f 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -7,11 +7,11 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/time.hpp>
#include <mbgl/util/uv.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <atomic>
#include <iosfwd>
-#include <memory>
#include <set>
#include <vector>
@@ -31,21 +31,31 @@ class FileSource;
class View;
class Map : private util::noncopyable {
+ typedef void (*stop_callback)(void *);
+
public:
explicit Map(View &view);
~Map();
- // Start/stop the map render thread
+ // Start the map render thread. It is asynchronous.
void start();
- void stop();
- // Runs the map event loop.
+ // Stop the map render thread. This call will block until the map rendering thread stopped.
+ // The optional callback function will be invoked repeatedly until the map thread is stopped.
+ // The callback function should wait until it is woken up again by view.notify(), otherwise
+ // this will be a busy waiting loop. The optional data parameter will be passed to the callback
+ // function.
+ void stop(stop_callback cb = nullptr, void *data = nullptr);
+
+ // Runs the map event loop. ONLY run this function when you want to get render a single frame
+ // with this map object. It will *not* spawn a separate thread and instead block until the
+ // frame is completely rendered.
void run();
// Triggers a lazy rerender: only performs a render when the map is not clean.
void rerender();
- void renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass, const Tile::ID* id = nullptr, const mat4* matrix = nullptr);
+ void renderLayer(util::ptr<StyleLayer> layer_desc, RenderPass pass, const Tile::ID* id = nullptr, const mat4* matrix = nullptr);
// Forces a map update: always triggers a rerender.
void update();
@@ -65,7 +75,7 @@ public:
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height);
// Styling
- const std::set<std::shared_ptr<StyleSource>> getActiveSources() const;
+ const std::set<util::ptr<StyleSource>> getActiveSources() const;
void setAppliedClasses(const std::vector<std::string> &classes);
void toggleClass(const std::string &name);
const std::vector<std::string> &getAppliedClasses() const;
@@ -116,16 +126,20 @@ public:
void toggleDebug();
bool getDebug() const;
+ // Call this when the network reachability changed.
+ void setReachability(bool status);
+
public:
inline const TransformState &getState() const { return state; }
- inline std::shared_ptr<FileSource> getFileSource() const { return fileSource; }
- inline std::shared_ptr<Style> getStyle() const { return style; }
- inline std::shared_ptr<GlyphAtlas> getGlyphAtlas() { return glyphAtlas; }
- inline std::shared_ptr<GlyphStore> getGlyphStore() { return glyphStore; }
- inline std::shared_ptr<SpriteAtlas> getSpriteAtlas() { return spriteAtlas; }
- std::shared_ptr<Sprite> getSprite();
- inline std::shared_ptr<Texturepool> getTexturepool() { return texturepool; }
- inline std::shared_ptr<uv::loop> getLoop() { return loop; }
+ inline util::ptr<FileSource> getFileSource() const { return fileSource; }
+ inline util::ptr<Style> getStyle() const { return style; }
+ inline util::ptr<GlyphAtlas> getGlyphAtlas() { return glyphAtlas; }
+ inline util::ptr<GlyphStore> getGlyphStore() { return glyphStore; }
+ inline util::ptr<SpriteAtlas> getSpriteAtlas() { return spriteAtlas; }
+ util::ptr<Sprite> getSprite();
+ inline util::ptr<Texturepool> getTexturepool() { return texturepool; }
+ inline util::ptr<uv::loop> getLoop() { return loop; }
+ uv::worker &getWorker();
inline timestamp getAnimationTime() const { return animationTime; }
inline timestamp getTime() const { return animationTime; }
void updateTiles();
@@ -141,7 +155,7 @@ private:
void setup();
void updateSources();
- void updateSources(const std::shared_ptr<StyleLayerGroup> &group);
+ void updateSources(const util::ptr<StyleLayerGroup> &group);
void updateRenderState();
@@ -154,15 +168,16 @@ private:
// Unconditionally performs a render with the current map state.
void render();
- void renderLayers(std::shared_ptr<StyleLayerGroup> group);
+ void renderLayers(util::ptr<StyleLayerGroup> group);
private:
bool async = false;
- std::shared_ptr<uv::loop> loop;
+ util::ptr<uv::loop> loop;
+ std::unique_ptr<uv::worker> workers;
std::unique_ptr<uv::thread> thread;
- uv_async_t *async_terminate = nullptr;
- uv_async_t *async_render = nullptr;
- uv_async_t *async_cleanup = nullptr;
+ std::unique_ptr<uv_async_t> async_terminate;
+ std::unique_ptr<uv_async_t> async_render;
+ std::unique_ptr<uv_async_t> async_cleanup;
private:
// If cleared, the next time the render thread attempts to render the map, it will *actually*
@@ -177,24 +192,33 @@ private:
// ready for rendering.
std::atomic_flag is_rendered = ATOMIC_FLAG_INIT;
+ // Stores whether the map thread has been stopped already.
+ std::atomic_bool is_stopped;
+
public:
View &view;
private:
+#ifndef NDEBUG
+ const unsigned long main_thread;
+ unsigned long map_thread = -1;
+#endif
+
Transform transform;
TransformState state;
- std::shared_ptr<FileSource> fileSource;
+ util::ptr<FileSource> fileSource;
- std::shared_ptr<Style> style;
- std::shared_ptr<GlyphAtlas> glyphAtlas;
- std::shared_ptr<GlyphStore> glyphStore;
- std::shared_ptr<SpriteAtlas> spriteAtlas;
- std::shared_ptr<Sprite> sprite;
- std::shared_ptr<Texturepool> texturepool;
+ util::ptr<Style> style;
+ util::ptr<GlyphAtlas> glyphAtlas;
+ util::ptr<GlyphStore> glyphStore;
+ util::ptr<SpriteAtlas> spriteAtlas;
+ util::ptr<Sprite> sprite;
+ util::ptr<Texturepool> texturepool;
Painter painter;
+ std::string styleURL;
std::string styleJSON = "";
std::string accessToken = "";
@@ -203,7 +227,7 @@ private:
int indent = 0;
- std::set<std::shared_ptr<StyleSource>> activeSources;
+ std::set<util::ptr<StyleSource>> activeSources;
};
diff --git a/include/mbgl/map/raster_tile_data.hpp b/include/mbgl/map/raster_tile_data.hpp
index 98aa3baaf5..14833c0d84 100644
--- a/include/mbgl/map/raster_tile_data.hpp
+++ b/include/mbgl/map/raster_tile_data.hpp
@@ -5,8 +5,6 @@
#include <mbgl/map/tile_data.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
-#include <memory>
-
namespace mbgl {
class Map;
@@ -18,12 +16,12 @@ class RasterTileData : public TileData {
friend class TileParser;
public:
- RasterTileData(Tile::ID id, Map &map, const SourceInfo &source);
+ RasterTileData(Tile::ID id, Map &map, const util::ptr<SourceInfo> &source);
~RasterTileData();
virtual void parse();
- virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix);
- virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const;
+ virtual void render(Painter &painter, util::ptr<StyleLayer> layer_desc, const mat4 &matrix);
+ virtual bool hasData(util::ptr<StyleLayer> layer_desc) const;
protected:
StyleBucketRaster properties;
diff --git a/include/mbgl/map/source.hpp b/include/mbgl/map/source.hpp
index cb069db272..e74ddb9902 100644
--- a/include/mbgl/map/source.hpp
+++ b/include/mbgl/map/source.hpp
@@ -8,12 +8,12 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/time.hpp>
#include <mbgl/util/mat4.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <forward_list>
#include <iosfwd>
#include <map>
-#include <memory>
namespace mbgl {
@@ -25,7 +25,7 @@ struct box;
class Source : public std::enable_shared_from_this<Source>, private util::noncopyable {
public:
- Source(SourceInfo& info);
+ Source(const util::ptr<SourceInfo>& info);
void load(Map &map);
@@ -33,8 +33,8 @@ public:
void updateMatrices(const mat4 &projMatrix, const TransformState &transform);
void drawClippingMasks(Painter &painter);
size_t getTileCount() const;
- void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc);
- void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix);
+ void render(Painter &painter, util::ptr<StyleLayer> layer_desc);
+ void render(Painter &painter, util::ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix);
void finishRender(Painter &painter);
std::forward_list<Tile::ID> getIDs() const;
@@ -54,7 +54,7 @@ private:
double getZoom(const TransformState &state) const;
- SourceInfo& info;
+ util::ptr<SourceInfo> info;
bool loaded = false;
// Stores the time when this source was most recently updated.
diff --git a/include/mbgl/map/sprite.hpp b/include/mbgl/map/sprite.hpp
index 6461a5e33d..454ebd8886 100644
--- a/include/mbgl/map/sprite.hpp
+++ b/include/mbgl/map/sprite.hpp
@@ -3,11 +3,11 @@
#include <mbgl/util/image.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <atomic>
#include <iosfwd>
-#include <memory>
#include <string>
#include <unordered_map>
#include <future>
@@ -34,11 +34,11 @@ public:
class Sprite : public std::enable_shared_from_this<Sprite>, private util::noncopyable {
private:
struct Key {};
- void load(const std::shared_ptr<FileSource> &fileSource);
+ void load(const util::ptr<FileSource> &fileSource);
public:
Sprite(const Key &, const std::string& base_url, float pixelRatio);
- static std::shared_ptr<Sprite> Create(const std::string& base_url, float pixelRatio, const std::shared_ptr<FileSource> &fileSource);
+ static util::ptr<Sprite> Create(const std::string& base_url, float pixelRatio, const util::ptr<FileSource> &fileSource);
const SpritePosition &getSpritePosition(const std::string& name) const;
diff --git a/include/mbgl/map/tile.hpp b/include/mbgl/map/tile.hpp
index 75ced7e384..b9f0556add 100644
--- a/include/mbgl/map/tile.hpp
+++ b/include/mbgl/map/tile.hpp
@@ -3,6 +3,7 @@
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <bitset>
@@ -10,7 +11,6 @@
#include <cstdint>
#include <forward_list>
#include <iosfwd>
-#include <memory>
#include <string>
namespace mbgl {
@@ -78,7 +78,7 @@ public:
const Tile::ID id;
ClipID clip;
mat4 matrix;
- std::shared_ptr<TileData> data;
+ util::ptr<TileData> data;
};
}
diff --git a/include/mbgl/map/tile_data.hpp b/include/mbgl/map/tile_data.hpp
index 9aaef84e04..07cf19c5c8 100644
--- a/include/mbgl/map/tile_data.hpp
+++ b/include/mbgl/map/tile_data.hpp
@@ -6,11 +6,11 @@
#include <mbgl/geometry/debug_font_buffer.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/ptr.hpp>
#include <atomic>
#include <exception>
#include <iosfwd>
-#include <memory>
#include <string>
namespace mbgl {
@@ -19,8 +19,7 @@ class Map;
class Painter;
class SourceInfo;
class StyleLayer;
-
-namespace platform { class Request; }
+class Request;
class TileData : public std::enable_shared_from_this<TileData>,
private util::noncopyable {
@@ -29,7 +28,7 @@ public:
struct geometry_too_long_exception : exception {};
public:
- typedef std::shared_ptr<TileData> Ptr;
+ typedef util::ptr<TileData> Ptr;
enum class State {
invalid,
@@ -41,7 +40,7 @@ public:
};
public:
- TileData(Tile::ID id, Map &map, const SourceInfo &source);
+ TileData(Tile::ID id, Map &map, const util::ptr<SourceInfo> &source);
~TileData();
void request();
@@ -57,8 +56,8 @@ public:
virtual void beforeParse();
virtual void parse() = 0;
virtual void afterParse();
- virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix) = 0;
- virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const = 0;
+ virtual void render(Painter &painter, util::ptr<StyleLayer> layer_desc, const mat4 &matrix) = 0;
+ virtual bool hasData(util::ptr<StyleLayer> layer_desc) const = 0;
public:
@@ -69,10 +68,10 @@ protected:
Map &map;
public:
- const SourceInfo &source;
+ util::ptr<SourceInfo> source;
protected:
- std::weak_ptr<platform::Request> req;
+ std::unique_ptr<Request> req;
std::string data;
// Contains the tile ID string for painting debug information.
diff --git a/include/mbgl/map/tile_parser.hpp b/include/mbgl/map/tile_parser.hpp
index fa64dad6d5..ddb4b98820 100644
--- a/include/mbgl/map/tile_parser.hpp
+++ b/include/mbgl/map/tile_parser.hpp
@@ -4,10 +4,10 @@
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/text/glyph.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <iosfwd>
-#include <memory>
#include <string>
namespace mbgl {
@@ -32,11 +32,11 @@ class Collision;
class TileParser {
public:
TileParser(const std::string &data, VectorTileData &tile,
- const std::shared_ptr<const Style> &style,
- const std::shared_ptr<GlyphAtlas> &glyphAtlas,
- const std::shared_ptr<GlyphStore> &glyphStore,
- const std::shared_ptr<SpriteAtlas> &spriteAtlas,
- const std::shared_ptr<Sprite> &sprite);
+ const util::ptr<const Style> &style,
+ const util::ptr<GlyphAtlas> &glyphAtlas,
+ const util::ptr<GlyphStore> &glyphStore,
+ const util::ptr<SpriteAtlas> &spriteAtlas,
+ const util::ptr<Sprite> &sprite);
~TileParser();
public:
@@ -44,11 +44,11 @@ public:
private:
bool obsolete() const;
- void parseStyleLayers(std::shared_ptr<StyleLayerGroup> group);
- std::unique_ptr<Bucket> createBucket(std::shared_ptr<StyleBucket> bucket_desc);
+ void parseStyleLayers(util::ptr<StyleLayerGroup> group);
+ std::unique_ptr<Bucket> createBucket(util::ptr<StyleBucket> bucket_desc);
std::unique_ptr<Bucket> createFillBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketFill &fill);
- std::unique_ptr<Bucket> createRasterBucket(const std::shared_ptr<Texturepool> &texturepool, const StyleBucketRaster &raster);
+ std::unique_ptr<Bucket> createRasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster &raster);
std::unique_ptr<Bucket> createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line);
std::unique_ptr<Bucket> createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol);
@@ -59,12 +59,12 @@ private:
VectorTileData& tile;
// Cross-thread shared data.
- std::shared_ptr<const Style> style;
- std::shared_ptr<GlyphAtlas> glyphAtlas;
- std::shared_ptr<GlyphStore> glyphStore;
- std::shared_ptr<SpriteAtlas> spriteAtlas;
- std::shared_ptr<Sprite> sprite;
- std::shared_ptr<Texturepool> texturePool;
+ util::ptr<const Style> style;
+ util::ptr<GlyphAtlas> glyphAtlas;
+ util::ptr<GlyphStore> glyphStore;
+ util::ptr<SpriteAtlas> spriteAtlas;
+ util::ptr<Sprite> sprite;
+ util::ptr<Texturepool> texturePool;
std::unique_ptr<Collision> collision;
};
diff --git a/include/mbgl/map/transform.hpp b/include/mbgl/map/transform.hpp
index d0f56b7fba..5404f333c1 100644
--- a/include/mbgl/map/transform.hpp
+++ b/include/mbgl/map/transform.hpp
@@ -98,10 +98,10 @@ private:
// cache values for spherical mercator math
double Bc, Cc;
- std::forward_list<std::shared_ptr<util::transition>> transitions;
- std::shared_ptr<util::transition> scale_timeout;
- std::shared_ptr<util::transition> rotate_timeout;
- std::shared_ptr<util::transition> pan_timeout;
+ std::forward_list<util::ptr<util::transition>> transitions;
+ util::ptr<util::transition> scale_timeout;
+ util::ptr<util::transition> rotate_timeout;
+ util::ptr<util::transition> pan_timeout;
};
}
diff --git a/include/mbgl/map/vector_tile_data.hpp b/include/mbgl/map/vector_tile_data.hpp
index deb628e485..9de666c84f 100644
--- a/include/mbgl/map/vector_tile_data.hpp
+++ b/include/mbgl/map/vector_tile_data.hpp
@@ -26,14 +26,14 @@ class VectorTileData : public TileData {
friend class TileParser;
public:
- VectorTileData(Tile::ID id, Map &map, const SourceInfo &source);
+ VectorTileData(Tile::ID id, Map &map, const util::ptr<SourceInfo> &source);
~VectorTileData();
virtual void beforeParse();
virtual void parse();
virtual void afterParse();
- virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix);
- virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const;
+ virtual void render(Painter &painter, util::ptr<StyleLayer> layer_desc, const mat4 &matrix);
+ virtual bool hasData(util::ptr<StyleLayer> layer_desc) const;
protected:
// Holds the actual geometries in this tile.
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
index 3e2f1a4b5a..395a05d435 100644
--- a/include/mbgl/map/view.hpp
+++ b/include/mbgl/map/view.hpp
@@ -45,6 +45,8 @@ public:
return 0;
}
+ virtual void notify() = 0;
+
// Notifies a watcher of map x/y/scale/rotation changes.
// Must only be called from the same thread that caused the change.
// Must not be called from the render thread.
diff --git a/include/mbgl/platform/event.hpp b/include/mbgl/platform/event.hpp
index 1676f40d2c..d2a06618a3 100644
--- a/include/mbgl/platform/event.hpp
+++ b/include/mbgl/platform/event.hpp
@@ -29,6 +29,7 @@ enum class Event : uint8_t {
ParseStyle,
ParseTile,
Render,
+ Database,
HttpRequest,
Sprite,
};
@@ -40,6 +41,7 @@ MBGL_DEFINE_ENUM_CLASS(EventClass, Event, {
{ Event::ParseStyle, "ParseStyle" },
{ Event::ParseTile, "ParseTile" },
{ Event::Render, "Render" },
+ { Event::Database, "Database" },
{ Event::HttpRequest, "HttpRequest" },
{ Event::Sprite, "Sprite" },
{ Event(-1), "Unknown" },
diff --git a/include/mbgl/platform/platform.hpp b/include/mbgl/platform/platform.hpp
index 22405a4cfd..b7107bb9cd 100644
--- a/include/mbgl/platform/platform.hpp
+++ b/include/mbgl/platform/platform.hpp
@@ -4,7 +4,6 @@
#include <mbgl/util/uv.hpp>
#include <memory>
-#include <functional>
#include <string>
namespace mbgl {
@@ -12,30 +11,14 @@ namespace platform {
class Request;
-struct Response {
- Response(std::function<void(Response *)> callback) : callback(callback) {}
- int16_t code = -1;
- std::string body;
- std::string error_message;
- std::function<void(Response *)> callback;
-};
-
-// Makes an HTTP request of a URL, preferrably on a background thread, and calls a function with the
-// results in the original thread (which runs the libuv loop).
-// If the loop pointer is NULL, the callback function will be called on an arbitrary thread.
-// Returns a cancellable request.
-std::shared_ptr<Request> request_http(const std::string &url,
- std::function<void(Response *)> callback,
- std::shared_ptr<uv::loop> loop = nullptr);
-
// Uppercase a string, potentially using platform-specific routines.
std::string uppercase(const std::string &string);
// Lowercase a string, potentially using platform-specific routines.
std::string lowercase(const std::string &string);
-// Cancels an HTTP request.
-void cancel_request_http(const std::shared_ptr<Request> &req);
+// Returns the path to the default cache database on this system.
+std::string defaultCacheDatabase();
// Shows an alpha image with the specified dimensions in a named window.
void show_debug_image(std::string name, const char *data, size_t width, size_t height);
diff --git a/include/mbgl/platform/request.hpp b/include/mbgl/platform/request.hpp
deleted file mode 100644
index 2a231769c1..0000000000
--- a/include/mbgl/platform/request.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef MBGL_PLATFORM_REQUEST
-#define MBGL_PLATFORM_REQUEST
-
-#include <string>
-#include <functional>
-#include <memory>
-#include <atomic>
-
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/uv.hpp>
-
-namespace mbgl {
-namespace platform {
-
-struct Response;
-
-class Request : public std::enable_shared_from_this<Request>, private util::noncopyable {
-public:
- Request(const std::string &url,
- std::function<void(Response *)> callback,
- std::shared_ptr<uv::loop> loop);
- ~Request();
-
- void complete();
-
-private:
- static void complete(uv_async_t *async, int status);
-
-public:
- const std::string url;
- std::unique_ptr<Response> res;
- std::atomic<bool> cancelled;
-
-public:
- uv_async_t *async = nullptr;
- std::shared_ptr<uv::loop> loop;
-};
-}
-}
-
-#endif
diff --git a/include/mbgl/renderer/bucket.hpp b/include/mbgl/renderer/bucket.hpp
index 1391f6e3e3..696bfb1110 100644
--- a/include/mbgl/renderer/bucket.hpp
+++ b/include/mbgl/renderer/bucket.hpp
@@ -1,11 +1,11 @@
#ifndef MBGL_RENDERER_BUCKET
#define MBGL_RENDERER_BUCKET
-#include <string>
-#include <memory>
#include <mbgl/map/tile.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <string>
+
namespace mbgl {
class Painter;
@@ -13,7 +13,7 @@ class StyleLayer;
class Bucket : private util::noncopyable {
public:
- virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) = 0;
+ virtual void render(Painter& painter, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) = 0;
virtual bool hasData() const = 0;
virtual ~Bucket() {}
diff --git a/include/mbgl/renderer/debug_bucket.hpp b/include/mbgl/renderer/debug_bucket.hpp
index 660b7fcba8..fb6cfb4cae 100644
--- a/include/mbgl/renderer/debug_bucket.hpp
+++ b/include/mbgl/renderer/debug_bucket.hpp
@@ -6,7 +6,6 @@
#include <mbgl/geometry/vao.hpp>
#include <vector>
-#include <memory>
#ifndef BUFFER_OFFSET
#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
@@ -20,7 +19,7 @@ class DebugBucket : public Bucket {
public:
DebugBucket(DebugFontBuffer& fontBuffer);
- virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ virtual void render(Painter& painter, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
virtual bool hasData() const;
void drawLines(PlainShader& shader);
diff --git a/include/mbgl/renderer/fill_bucket.hpp b/include/mbgl/renderer/fill_bucket.hpp
index 15868e4092..ae766ec28d 100644
--- a/include/mbgl/renderer/fill_bucket.hpp
+++ b/include/mbgl/renderer/fill_bucket.hpp
@@ -44,7 +44,7 @@ public:
const StyleBucketFill& properties);
~FillBucket();
- virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ virtual void render(Painter& painter, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
virtual bool hasData() const;
void addGeometry(pbf& data);
diff --git a/include/mbgl/renderer/line_bucket.hpp b/include/mbgl/renderer/line_bucket.hpp
index 8babb734ed..7337ca80ad 100644
--- a/include/mbgl/renderer/line_bucket.hpp
+++ b/include/mbgl/renderer/line_bucket.hpp
@@ -1,13 +1,12 @@
#ifndef MBGL_RENDERER_LINEBUCKET
#define MBGL_RENDERER_LINEBUCKET
-#include "bucket.hpp"
+#include <mbgl/renderer/bucket.hpp>
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/geometry/line_buffer.hpp>
#include <mbgl/style/style_bucket.hpp>
-#include <memory>
#include <vector>
namespace mbgl {
@@ -30,7 +29,7 @@ public:
PointElementsBuffer& pointElementsBuffer,
const StyleBucketLine& properties);
- virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ virtual void render(Painter& painter, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
virtual bool hasData() const;
void addGeometry(pbf& data);
diff --git a/include/mbgl/renderer/painter.hpp b/include/mbgl/renderer/painter.hpp
index 15331b9b67..0f9bd79173 100644
--- a/include/mbgl/renderer/painter.hpp
+++ b/include/mbgl/renderer/painter.hpp
@@ -22,6 +22,7 @@
#include <mbgl/shader/gaussian_shader.hpp>
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/util/ptr.hpp>
#include <map>
#include <unordered_map>
@@ -73,7 +74,7 @@ public:
void changeMatrix();
// Renders a particular layer from a tile.
- void renderTileLayer(const Tile& tile, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix);
+ void renderTileLayer(const Tile& tile, util::ptr<StyleLayer> layer_desc, const mat4 &matrix);
// Renders debug information for a tile.
void renderTileDebug(const Tile& tile);
@@ -83,11 +84,11 @@ public:
void renderDebugText(DebugBucket& bucket, const mat4 &matrix);
void renderDebugText(const std::vector<std::string> &strings);
- void renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
- void renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
- void renderSymbol(SymbolBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
- void renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
- void renderBackground(std::shared_ptr<StyleLayer> layer_desc);
+ void renderFill(FillBucket& bucket, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ void renderLine(LineBucket& bucket, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ void renderSymbol(SymbolBucket& bucket, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ void renderRaster(RasterBucket& bucket, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ void renderBackground(util::ptr<StyleLayer> layer_desc);
float saturationFactor(float saturation);
float contrastFactor(float contrast);
@@ -97,7 +98,7 @@ public:
void renderPrerenderedTexture(RasterBucket &bucket, const mat4 &matrix, const RasterProperties& properties);
- void createPrerendered(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id);
+ void createPrerendered(RasterBucket& bucket, util::ptr<StyleLayer> layer_desc, const Tile::ID& id);
void resize();
@@ -111,7 +112,7 @@ public:
// Configures the painter strata that is used for early z-culling of fragments.
void setStrata(float strata);
- void drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &sources);
+ void drawClippingMasks(const std::set<util::ptr<StyleSource>> &sources);
void drawClippingMask(const mat4& matrix, const ClipID& clip);
void resetFramebuffer();
diff --git a/include/mbgl/renderer/raster_bucket.hpp b/include/mbgl/renderer/raster_bucket.hpp
index 66cceac8e7..794da3b143 100644
--- a/include/mbgl/renderer/raster_bucket.hpp
+++ b/include/mbgl/renderer/raster_bucket.hpp
@@ -16,9 +16,9 @@ class VertexArrayObject;
class RasterBucket : public Bucket {
public:
- RasterBucket(const std::shared_ptr<Texturepool> &texturepool, const StyleBucketRaster& properties);
+ RasterBucket(const util::ptr<Texturepool> &texturepool, const StyleBucketRaster& properties);
- virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
+ virtual void render(Painter& painter, util::ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix);
virtual bool hasData() const;
bool setImage(const std::string &data);
diff --git a/include/mbgl/renderer/symbol_bucket.hpp b/include/mbgl/renderer/symbol_bucket.hpp
index c71d276456..42682401ef 100644
--- a/include/mbgl/renderer/symbol_bucket.hpp
+++ b/include/mbgl/renderer/symbol_bucket.hpp
@@ -56,7 +56,7 @@ class SymbolBucket : public Bucket {
public:
SymbolBucket(const StyleBucketSymbol &properties, Collision &collision);
- virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix);
+ virtual void render(Painter &painter, util::ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix);
virtual bool hasData() const;
virtual bool hasTextData() const;
virtual bool hasIconData() const;
diff --git a/include/mbgl/storage/base_request.hpp b/include/mbgl/storage/base_request.hpp
new file mode 100644
index 0000000000..16ff24faa3
--- /dev/null
+++ b/include/mbgl/storage/base_request.hpp
@@ -0,0 +1,62 @@
+#ifndef MBGL_STORAGE_BASE_REQUEST
+#define MBGL_STORAGE_BASE_REQUEST
+
+#include <mbgl/storage/request_callback.hpp>
+#include <mbgl/util/ptr.hpp>
+
+#include <string>
+#include <forward_list>
+#include <functional>
+
+
+typedef struct uv_loop_s uv_loop_t;
+typedef struct uv_async_s uv_async_t;
+
+namespace mbgl {
+
+class Response;
+class Request;
+
+class BaseRequest {
+private:
+ // Make noncopyable and immovable
+ BaseRequest(const BaseRequest &) = delete;
+ BaseRequest(BaseRequest &&) = delete;
+ BaseRequest& operator=(const BaseRequest &) = delete;
+ BaseRequest& operator=(BaseRequest &&) = delete;
+
+public:
+ BaseRequest(const std::string &path);
+ virtual ~BaseRequest();
+
+ Callback *add(Callback &&callback, const util::ptr<BaseRequest> &request);
+ void remove(Callback *callback);
+
+ // Must be called by subclasses when a valid Response object is available. It will notify
+ // all listeners.
+ void notify();
+
+ // This function is called when the request ought to be stopped. Any subclass must make sure this
+ // is also called in its destructor. Calling this function repeatedly must be safe.
+ // This function must call notify().
+ virtual void cancel() = 0;
+
+ // This function is called when the request should be reattempted immediately. This is typically
+ // reaction to a network status change.
+ virtual void retryImmediately();
+
+public:
+ const unsigned long thread_id;
+ const std::string path;
+ std::unique_ptr<Response> response;
+
+protected:
+ // This object may hold a shared_ptr to itself. It does this to prevent destruction of this object
+ // while a request is in progress.
+ util::ptr<BaseRequest> self;
+ std::forward_list<std::unique_ptr<Callback>> callbacks;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/storage/file_request.hpp b/include/mbgl/storage/file_request.hpp
new file mode 100644
index 0000000000..2f883728ff
--- /dev/null
+++ b/include/mbgl/storage/file_request.hpp
@@ -0,0 +1,27 @@
+#ifndef MBGL_STORAGE_FILE_REQUEST
+#define MBGL_STORAGE_FILE_REQUEST
+
+#include <mbgl/storage/base_request.hpp>
+
+namespace mbgl {
+
+typedef struct uv_loop_s uv_loop_t;
+
+struct FileRequestBaton;
+
+class FileRequest : public BaseRequest {
+public:
+ FileRequest(const std::string &path, uv_loop_t *loop);
+ ~FileRequest();
+
+ void cancel();
+
+private:
+ FileRequestBaton *ptr = nullptr;
+
+ friend struct FileRequestBaton;
+};
+
+}
+
+#endif \ No newline at end of file
diff --git a/include/mbgl/storage/file_request_baton.hpp b/include/mbgl/storage/file_request_baton.hpp
new file mode 100644
index 0000000000..0f1968ca13
--- /dev/null
+++ b/include/mbgl/storage/file_request_baton.hpp
@@ -0,0 +1,35 @@
+#ifndef MBGL_STORAGE_FILE_REQUEST_BATON
+#define MBGL_STORAGE_FILE_REQUEST_BATON
+
+#include <mbgl/storage/file_request.hpp>
+
+#include <uv.h>
+
+namespace mbgl {
+
+struct FileRequestBaton {
+ FileRequestBaton(FileRequest *request_, const std::string &path, uv_loop_t *loop);
+ ~FileRequestBaton();
+
+ void cancel();
+ static void file_opened(uv_fs_t *req);
+ static void file_stated(uv_fs_t *req);
+ static void file_read(uv_fs_t *req);
+ static void file_closed(uv_fs_t *req);
+ static void notify_error(uv_fs_t *req);
+ static void cleanup(uv_fs_t *req);
+
+ const unsigned long thread_id;
+ FileRequest *request = nullptr;
+ uv_fs_t req;
+ uv_file fd = -1;
+ bool canceled = false;
+ std::string body;
+ uv_buf_t buffer;
+};
+
+
+}
+
+
+#endif
diff --git a/include/mbgl/storage/file_source.hpp b/include/mbgl/storage/file_source.hpp
new file mode 100644
index 0000000000..4b17cd29a7
--- /dev/null
+++ b/include/mbgl/storage/file_source.hpp
@@ -0,0 +1,55 @@
+#ifndef MBGL_STORAGE_FILE_SOURCE
+#define MBGL_STORAGE_FILE_SOURCE
+
+#include <mbgl/storage/resource_type.hpp>
+#include <mbgl/storage/request.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 {
+private:
+ FileSource(const FileSource &) = delete;
+ FileSource(FileSource &&) = delete;
+ FileSource& operator=(const FileSource &) = delete;
+ FileSource& operator=(FileSource &&) = delete;
+
+public:
+ FileSource(uv_loop_t *loop, const std::string &path);
+ ~FileSource();
+
+public:
+ // 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;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/storage/http_request.hpp b/include/mbgl/storage/http_request.hpp
new file mode 100644
index 0000000000..ec76f1147c
--- /dev/null
+++ b/include/mbgl/storage/http_request.hpp
@@ -0,0 +1,57 @@
+#ifndef MBGL_STORAGE_HTTP_REQUEST
+#define MBGL_STORAGE_HTTP_REQUEST
+
+#include <mbgl/storage/resource_type.hpp>
+#include <mbgl/storage/base_request.hpp>
+#include <mbgl/storage/http_request_baton.hpp>
+
+#include <string>
+#include <memory>
+#include <cassert>
+
+typedef struct uv_loop_s uv_loop_t;
+typedef struct uv_timer_s uv_timer_t;
+
+namespace mbgl {
+
+struct CacheRequestBaton;
+struct HTTPRequestBaton;
+struct CacheEntry;
+class SQLiteStore;
+
+class HTTPRequest : public BaseRequest {
+public:
+ HTTPRequest(ResourceType type, const std::string &path, uv_loop_t *loop, util::ptr<SQLiteStore> store);
+ ~HTTPRequest();
+
+ void cancel();
+ void retryImmediately();
+
+private:
+ void startCacheRequest();
+ void handleCacheResponse(std::unique_ptr<Response> &&response);
+ void startHTTPRequest(std::unique_ptr<Response> &&res);
+ void handleHTTPResponse(HTTPResponseType responseType, std::unique_ptr<Response> &&response);
+
+ void retryHTTPRequest(std::unique_ptr<Response> &&res, uint64_t timeout);
+
+ void removeCacheBaton();
+ void removeHTTPBaton();
+ void removeBackoffTimer();
+
+private:
+ const unsigned long thread_id;
+ uv_loop_t *const loop;
+ CacheRequestBaton *cache_baton = nullptr;
+ util::ptr<HTTPRequestBaton> http_baton;
+ uv_timer_t *backoff_timer = nullptr;
+ util::ptr<SQLiteStore> store;
+ const ResourceType type;
+ uint8_t attempts = 0;
+
+ friend struct HTTPRequestBaton;
+};
+
+}
+
+#endif \ No newline at end of file
diff --git a/include/mbgl/storage/http_request_baton.hpp b/include/mbgl/storage/http_request_baton.hpp
new file mode 100644
index 0000000000..279784ec25
--- /dev/null
+++ b/include/mbgl/storage/http_request_baton.hpp
@@ -0,0 +1,73 @@
+#ifndef MBGL_STORAGE_HTTP_REQUEST_BATON
+#define MBGL_STORAGE_HTTP_REQUEST_BATON
+
+#include <mbgl/storage/response.hpp>
+#include <mbgl/util/ptr.hpp>
+
+#include <string>
+
+typedef struct uv_async_s uv_async_t;
+
+namespace mbgl {
+
+class HTTPRequest;
+
+enum class HTTPResponseType : int8_t {
+ // This error probably won't be resolved by retrying anytime soon. We are giving up.
+ PermanentError = -5,
+
+ // This error might be resolved by waiting some time (e.g. server issues).
+ // We are going to do an exponential back-off and will try again in a few seconds.
+ TemporaryError = -4,
+
+ // This error was caused by a temporary error and it is likely that it will be resolved
+ // immediately. We are going to try again right away. This is like the TemporaryError, except
+ // that we will not perform exponential back-off.
+ SingularError = -3,
+
+ // This error might be resolved once the network reachability status changes.
+ // We are going to watch the network status for changes and will retry as soon as the operating
+ // system notifies us of a network status change.
+ ConnectionError = -2,
+
+ // The request was canceled programatically.
+ Canceled = -1,
+
+ // The request is still in progress.
+ Unknown = 0,
+
+ // The request returned data successfully. We retrieved and decoded the data successfully.
+ Successful = 1,
+
+ // The request confirmed that the data wasn't changed. We already have the data.
+ NotModified = 2,
+};
+
+struct HTTPRequestBaton {
+ HTTPRequestBaton(const std::string &path);
+ ~HTTPRequestBaton();
+
+ const unsigned long thread_id;
+ const std::string path;
+
+ HTTPRequest *request = nullptr;
+ uv_async_t *async = nullptr;
+
+ HTTPResponseType type = HTTPResponseType::Unknown;
+ std::unique_ptr<Response> response;
+
+ // Implementation specific use.
+ void *ptr = nullptr;
+
+ // IMPLEMENT THESE 3 PLATFORM SPECIFIC FUNCTIONS:
+
+ // Begin the HTTP request. Platform-specific implementation.
+ static void start(const util::ptr<HTTPRequestBaton> &ptr);
+
+ // This will be called to stop/cancel the HTTP request (if possible). Platform-specific implementation.
+ static void stop(const util::ptr<HTTPRequestBaton> &ptr);
+};
+
+}
+
+#endif
diff --git a/include/mbgl/storage/request.hpp b/include/mbgl/storage/request.hpp
new file mode 100644
index 0000000000..e603ee527a
--- /dev/null
+++ b/include/mbgl/storage/request.hpp
@@ -0,0 +1,39 @@
+#ifndef MBGL_STORAGE_REQUEST
+#define MBGL_STORAGE_REQUEST
+
+#include <mbgl/storage/request_callback.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/util/ptr.hpp>
+
+#include <forward_list>
+
+typedef struct uv_loop_s uv_loop_t;
+
+namespace mbgl {
+
+class BaseRequest;
+
+class Request {
+private:
+ Request(const Request &) = delete;
+ Request(Request &&) = delete;
+ Request& operator=(const Request &) = delete;
+ Request& operator=(Request &&) = delete;
+
+public:
+ Request(const util::ptr<BaseRequest> &base);
+ ~Request();
+
+ void onload(CompletedCallback cb);
+ void oncancel(AbortedCallback cb);
+ void cancel();
+
+private:
+ const unsigned long thread_id;
+ util::ptr<BaseRequest> base;
+ std::forward_list<Callback *> callbacks;
+};
+
+}
+
+#endif \ No newline at end of file
diff --git a/include/mbgl/storage/request_callback.hpp b/include/mbgl/storage/request_callback.hpp
new file mode 100644
index 0000000000..01427bd96d
--- /dev/null
+++ b/include/mbgl/storage/request_callback.hpp
@@ -0,0 +1,22 @@
+#ifndef MBGL_STORAGE_REQUEST_CALLBACK
+#define MBGL_STORAGE_REQUEST_CALLBACK
+
+#include <mbgl/util/variant.hpp>
+
+#include <functional>
+
+namespace mbgl {
+
+class Response;
+
+using CompletedCallback = std::function<void(const Response &)>;
+using AbortedCallback = std::function<void()>;
+
+using Callback = mapbox::util::variant<
+ CompletedCallback,
+ AbortedCallback
+>;
+
+}
+
+#endif
diff --git a/include/mbgl/storage/resource_type.hpp b/include/mbgl/storage/resource_type.hpp
new file mode 100644
index 0000000000..b7204a9fa1
--- /dev/null
+++ b/include/mbgl/storage/resource_type.hpp
@@ -0,0 +1,18 @@
+#ifndef MBGL_STORAGE_RESOURCE_TYPE
+#define MBGL_STORAGE_RESOURCE_TYPE
+
+#include <cstdint>
+
+namespace mbgl {
+
+enum class ResourceType : uint8_t {
+ Unknown = 0,
+ Tile = 1,
+ Glyphs = 2,
+ Image = 3,
+ JSON = 4
+};
+
+}
+
+#endif
diff --git a/include/mbgl/storage/response.hpp b/include/mbgl/storage/response.hpp
new file mode 100644
index 0000000000..9357ad3c63
--- /dev/null
+++ b/include/mbgl/storage/response.hpp
@@ -0,0 +1,26 @@
+#ifndef MBGL_STORAGE_RESPONSE
+#define MBGL_STORAGE_RESPONSE
+
+#include <string>
+#include <ctime>
+
+namespace mbgl {
+
+
+
+class Response {
+public:
+ long code = 0;
+ int64_t modified = 0;
+ int64_t expires = 0;
+ std::string etag;
+ std::string data;
+
+ std::string message;
+
+ static int64_t parseCacheControl(const char *value);
+};
+
+}
+
+#endif \ No newline at end of file
diff --git a/include/mbgl/storage/sqlite_store.hpp b/include/mbgl/storage/sqlite_store.hpp
new file mode 100644
index 0000000000..cb7730d0bf
--- /dev/null
+++ b/include/mbgl/storage/sqlite_store.hpp
@@ -0,0 +1,47 @@
+#ifndef MBGL_STORAGE_SQLITE_STORE
+#define MBGL_STORAGE_SQLITE_STORE
+
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/storage/response.hpp>
+
+#include <uv.h>
+
+#include <string>
+
+typedef struct uv_worker_s uv_worker_t;
+
+namespace mapbox {
+namespace sqlite {
+class Database;
+}
+}
+
+namespace mbgl {
+
+class SQLiteStore {
+public:
+ SQLiteStore(uv_loop_t *loop, const std::string &path);
+ ~SQLiteStore();
+
+ typedef void (*GetCallback)(std::unique_ptr<Response> &&entry, void *ptr);
+
+ void get(const std::string &path, GetCallback cb, void *ptr);
+ void put(const std::string &path, ResourceType type, const Response &entry);
+ void updateExpiration(const std::string &path, int64_t expires);
+
+private:
+ void createSchema();
+ void closeDatabase();
+ static void runGet(uv_work_t *req);
+ static void runPut(uv_work_t *req);
+ static void deliverResult(uv_work_t *req, int status);
+
+private:
+ const unsigned long thread_id;
+ util::ptr<mapbox::sqlite::Database> db;
+ uv_worker_t *worker = nullptr;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/style/style.hpp b/include/mbgl/style/style.hpp
index c09de6ebba..56f318ecbb 100644
--- a/include/mbgl/style/style.hpp
+++ b/include/mbgl/style/style.hpp
@@ -6,6 +6,7 @@
#include <mbgl/util/time.hpp>
#include <mbgl/util/uv.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <map>
@@ -13,7 +14,6 @@
#include <unordered_map>
#include <vector>
#include <set>
-#include <memory>
namespace mbgl {
@@ -49,7 +49,7 @@ public:
const std::string &getSpriteURL() const;
public:
- std::shared_ptr<StyleLayerGroup> layers;
+ util::ptr<StyleLayerGroup> layers;
std::vector<std::string> appliedClasses;
std::string glyph_url;
diff --git a/include/mbgl/style/style_bucket.hpp b/include/mbgl/style/style_bucket.hpp
index c2cde52aa5..c4a8f6037e 100644
--- a/include/mbgl/style/style_bucket.hpp
+++ b/include/mbgl/style/style_bucket.hpp
@@ -8,8 +8,8 @@
#include <mbgl/util/vec.hpp>
#include <mbgl/util/variant.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/ptr.hpp>
-#include <memory>
#include <forward_list>
namespace mbgl {
@@ -93,12 +93,12 @@ typedef mapbox::util::variant<StyleBucketFill, StyleBucketLine, StyleBucketSymbo
class StyleBucket {
public:
- typedef std::shared_ptr<StyleBucket> Ptr;
+ typedef util::ptr<StyleBucket> Ptr;
StyleBucket(StyleLayerType type);
std::string name;
- std::shared_ptr<StyleSource> style_source;
+ util::ptr<StyleSource> style_source;
std::string source_layer;
FilterExpression filter;
StyleBucketRender render = std::false_type();
diff --git a/include/mbgl/style/style_layer.hpp b/include/mbgl/style/style_layer.hpp
index 84981e3fb4..641dc1e71c 100644
--- a/include/mbgl/style/style_layer.hpp
+++ b/include/mbgl/style/style_layer.hpp
@@ -6,8 +6,9 @@
#include <mbgl/style/style_properties.hpp>
#include <mbgl/style/applied_class_properties.hpp>
+#include <mbgl/util/ptr.hpp>
+
#include <vector>
-#include <memory>
#include <string>
#include <map>
#include <set>
@@ -64,7 +65,7 @@ public:
// Bucket information, telling the renderer how to generate the geometries
// for this layer (feature property filters, tessellation instructions, ...).
- std::shared_ptr<StyleBucket> bucket;
+ util::ptr<StyleBucket> bucket;
// Contains all style classes that can be applied to this layer.
const std::map<ClassID, ClassProperties> styles;
@@ -80,7 +81,7 @@ public:
StyleProperties properties;
// Child layer array (if this layer has child layers).
- std::shared_ptr<StyleLayerGroup> layers;
+ util::ptr<StyleLayerGroup> layers;
};
}
diff --git a/include/mbgl/style/style_layer_group.hpp b/include/mbgl/style/style_layer_group.hpp
index 983dd136f0..1af6e23bd7 100644
--- a/include/mbgl/style/style_layer_group.hpp
+++ b/include/mbgl/style/style_layer_group.hpp
@@ -15,7 +15,7 @@ public:
bool hasTransitions() const;
public:
- std::vector<std::shared_ptr<StyleLayer>> layers;
+ std::vector<util::ptr<StyleLayer>> layers;
};
}
diff --git a/include/mbgl/style/style_parser.hpp b/include/mbgl/style/style_parser.hpp
index e4e1b7f632..fc253bb1dd 100644
--- a/include/mbgl/style/style_parser.hpp
+++ b/include/mbgl/style/style_parser.hpp
@@ -27,7 +27,7 @@ public:
void parse(JSVal document);
- std::shared_ptr<StyleLayerGroup> getLayers() {
+ util::ptr<StyleLayerGroup> getLayers() {
return root;
}
@@ -46,14 +46,14 @@ private:
void parseSources(JSVal value);
std::unique_ptr<StyleLayerGroup> createLayers(JSVal value);
- std::shared_ptr<StyleLayer> createLayer(JSVal value);
+ util::ptr<StyleLayer> createLayer(JSVal value);
void parseLayers();
- void parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair);
+ void parseLayer(std::pair<JSVal, util::ptr<StyleLayer>> &pair);
void parseStyles(JSVal value, std::map<ClassID, ClassProperties> &styles);
void parseStyle(JSVal, ClassProperties &properties);
- void parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer);
- void parseBucket(JSVal value, std::shared_ptr<StyleLayer> &layer);
- void parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer);
+ void parseReference(JSVal value, util::ptr<StyleLayer> &layer);
+ void parseBucket(JSVal value, util::ptr<StyleLayer> &layer);
+ void parseRender(JSVal value, util::ptr<StyleLayer> &layer);
void parseSprite(JSVal value);
void parseGlyphURL(JSVal value);
@@ -94,13 +94,13 @@ private:
private:
std::unordered_map<std::string, const rapidjson::Value *> constants;
- std::unordered_map<std::string, const std::shared_ptr<StyleSource>> sources;
+ std::unordered_map<std::string, const util::ptr<StyleSource>> sources;
// This stores the root layer.
- std::shared_ptr<StyleLayerGroup> root;
+ util::ptr<StyleLayerGroup> root;
// This maps ids to Layer objects, with all items being at the root level.
- std::unordered_map<std::string, std::pair<JSVal, std::shared_ptr<StyleLayer>>> layers;
+ std::unordered_map<std::string, std::pair<JSVal, util::ptr<StyleLayer>>> layers;
// Store a stack of layers we're parsing right now. This is to prevent reference cycles.
std::forward_list<StyleLayer *> stack;
diff --git a/include/mbgl/style/style_source.hpp b/include/mbgl/style/style_source.hpp
index b598550c65..00c48431a1 100644
--- a/include/mbgl/style/style_source.hpp
+++ b/include/mbgl/style/style_source.hpp
@@ -2,18 +2,18 @@
#define MBGL_STYLE_STYLE_SOURCE
#include <mbgl/style/types.hpp>
+#include <mbgl/util/ptr.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <rapidjson/document.h>
-#include <memory>
#include <vector>
#include <string>
-#include <rapidjson/document.h>
-
namespace mbgl {
class Source;
-class SourceInfo {
+class SourceInfo : private util::noncopyable {
public:
SourceType type = SourceType::Vector;
std::string url;
@@ -31,12 +31,12 @@ public:
class StyleSource : public std::enable_shared_from_this<StyleSource> {
public:
- SourceInfo info;
+ util::ptr<SourceInfo> info;
bool enabled = false;
- std::shared_ptr<Source> source;
+ util::ptr<Source> source;
- StyleSource(const SourceInfo &info)
+ StyleSource(const util::ptr<SourceInfo> &info)
: info(info)
{}
};
diff --git a/include/mbgl/text/glyph_store.hpp b/include/mbgl/text/glyph_store.hpp
index e0c0391c73..f8a7cb4d0c 100644
--- a/include/mbgl/text/glyph_store.hpp
+++ b/include/mbgl/text/glyph_store.hpp
@@ -4,6 +4,7 @@
#include <mbgl/text/glyph.hpp>
#include <mbgl/util/pbf.hpp>
#include <mbgl/util/vec.hpp>
+#include <mbgl/util/ptr.hpp>
#include <cstdint>
#include <vector>
@@ -47,8 +48,15 @@ private:
class GlyphPBF {
public:
- GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange, const std::shared_ptr<FileSource> &fileSource);
+ GlyphPBF(const std::string &glyphURL, const std::string &fontStack, GlyphRange glyphRange, const util::ptr<FileSource> &fileSource);
+private:
+ GlyphPBF(const GlyphPBF &) = delete;
+ GlyphPBF(GlyphPBF &&) = delete;
+ GlyphPBF &operator=(const GlyphPBF &) = delete;
+ GlyphPBF &operator=(GlyphPBF &&) = delete;
+
+public:
void parse(FontStack &stack);
std::shared_future<GlyphPBF &> getFuture();
@@ -63,7 +71,7 @@ private:
// Manages Glyphrange PBF loading.
class GlyphStore {
public:
- GlyphStore(const std::shared_ptr<FileSource> &fileSource);
+ GlyphStore(const util::ptr<FileSource> &fileSource);
// Block until all specified GlyphRanges of the specified font stack are loaded.
void waitForGlyphRanges(const std::string &fontStack, const std::set<GlyphRange> &glyphRanges);
@@ -82,7 +90,7 @@ public:
std::string glyphURL;
private:
- const std::shared_ptr<FileSource> fileSource;
+ const util::ptr<FileSource> fileSource;
std::unordered_map<std::string, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>> ranges;
std::unordered_map<std::string, std::unique_ptr<FontStack>> stacks;
std::mutex mtx;
diff --git a/include/mbgl/util/compression.hpp b/include/mbgl/util/compression.hpp
new file mode 100644
index 0000000000..a33b2476a7
--- /dev/null
+++ b/include/mbgl/util/compression.hpp
@@ -0,0 +1,15 @@
+#ifndef MBGL_UTIL_COMPRESSION
+#define MBGL_UTIL_COMPRESSION
+
+#include <string>
+
+namespace mbgl {
+namespace util {
+
+std::string compress(const std::string &raw);
+std::string decompress(const std::string &raw);
+
+}
+}
+
+#endif
diff --git a/include/mbgl/util/filesource.hpp b/include/mbgl/util/filesource.hpp
deleted file mode 100644
index 18c63ddfeb..0000000000
--- a/include/mbgl/util/filesource.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef MBGL_UTIL_FILESOURCE
-#define MBGL_UTIL_FILESOURCE
-
-#include <mbgl/util/uv.hpp>
-
-#include <string>
-#include <memory>
-#include <functional>
-
-namespace mbgl {
-
-namespace platform {
-struct Response;
-}
-
-enum class ResourceType : uint8_t {
- Unknown,
- Tile,
- Glyphs,
- Image,
- JSON
-};
-
-class FileSource {
-public:
- FileSource();
-
- void setBase(const std::string &value);
- const std::string &getBase() const;
-
- void load(ResourceType type, const std::string &url, std::function<void(platform::Response *)> callback, const std::shared_ptr<uv::loop> loop = nullptr);
-
-private:
- // Stores a URL that is used as a base for loading resources with relative path.
- std::string base;
-
- // Stores the absolute path to the cache directory.
- const std::string cache;
-};
-
-}
-
-#endif
diff --git a/include/mbgl/util/interpolate.hpp b/include/mbgl/util/interpolate.hpp
index e8c3389350..c9232db4eb 100644
--- a/include/mbgl/util/interpolate.hpp
+++ b/include/mbgl/util/interpolate.hpp
@@ -1,6 +1,8 @@
#ifndef MBGL_UTIL_INTERPOLATE
#define MBGL_UTIL_INTERPOLATE
+#include <array>
+
namespace mbgl {
namespace util {
diff --git a/include/mbgl/util/parsedate.h b/include/mbgl/util/parsedate.h
new file mode 100644
index 0000000000..6905e361d4
--- /dev/null
+++ b/include/mbgl/util/parsedate.h
@@ -0,0 +1,38 @@
+#ifndef HEADER_PARSEDATE_H
+#define HEADER_PARSEDATE_H
+/***************************************************************************
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
+ * \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+
+time_t parse_date(const char *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_PARSEDATE_H */
diff --git a/include/mbgl/util/ptr.hpp b/include/mbgl/util/ptr.hpp
new file mode 100644
index 0000000000..6e02f956f3
--- /dev/null
+++ b/include/mbgl/util/ptr.hpp
@@ -0,0 +1,29 @@
+#ifndef MBGL_UTIL_PTR
+#define MBGL_UTIL_PTR
+
+#include <memory>
+#include <cassert>
+
+namespace mbgl {
+namespace util {
+
+template <typename T>
+class ptr : public ::std::shared_ptr<T> {
+public:
+ template <typename... Args>
+ inline ptr(Args &&... args)
+ : ::std::shared_ptr<T>(::std::forward<Args>(args)...) {}
+
+ inline auto operator->() const -> decltype(this->::std::shared_ptr<T>::operator->()) {
+ assert(*this);
+ return ::std::shared_ptr<T>::operator->();
+ }
+ inline auto operator*() const -> decltype(this->::std::shared_ptr<T>::operator*()) {
+ assert(*this);
+ return ::std::shared_ptr<T>::operator*();
+ }
+};
+}
+}
+
+#endif \ No newline at end of file
diff --git a/include/mbgl/util/queue.h b/include/mbgl/util/queue.h
new file mode 100644
index 0000000000..fe02b454ea
--- /dev/null
+++ b/include/mbgl/util/queue.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef QUEUE_H_
+#define QUEUE_H_
+
+typedef void *QUEUE[2];
+
+/* Private macros. */
+#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0]))
+#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1]))
+#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q)))
+#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q)))
+
+/* Public macros. */
+#define QUEUE_DATA(ptr, type, field) \
+ ((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
+
+#define QUEUE_FOREACH(q, h) \
+ for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))
+
+#define QUEUE_EMPTY(q) \
+ ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))
+
+#define QUEUE_HEAD(q) \
+ (QUEUE_NEXT(q))
+
+#define QUEUE_INIT(q) \
+ do { \
+ QUEUE_NEXT(q) = (q); \
+ QUEUE_PREV(q) = (q); \
+ } \
+ while (0)
+
+#define QUEUE_ADD(h, n) \
+ do { \
+ QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \
+ QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \
+ QUEUE_PREV(h) = QUEUE_PREV(n); \
+ QUEUE_PREV_NEXT(h) = (h); \
+ } \
+ while (0)
+
+#define QUEUE_SPLIT(h, q, n) \
+ do { \
+ QUEUE_PREV(n) = QUEUE_PREV(h); \
+ QUEUE_PREV_NEXT(n) = (n); \
+ QUEUE_NEXT(n) = (q); \
+ QUEUE_PREV(h) = QUEUE_PREV(q); \
+ QUEUE_PREV_NEXT(h) = (h); \
+ QUEUE_PREV(q) = (n); \
+ } \
+ while (0)
+
+#define QUEUE_INSERT_HEAD(h, q) \
+ do { \
+ QUEUE_NEXT(q) = QUEUE_NEXT(h); \
+ QUEUE_PREV(q) = (h); \
+ QUEUE_NEXT_PREV(q) = (q); \
+ QUEUE_NEXT(h) = (q); \
+ } \
+ while (0)
+
+#define QUEUE_INSERT_TAIL(h, q) \
+ do { \
+ QUEUE_NEXT(q) = (h); \
+ QUEUE_PREV(q) = QUEUE_PREV(h); \
+ QUEUE_PREV_NEXT(q) = (q); \
+ QUEUE_PREV(h) = (q); \
+ } \
+ while (0)
+
+#define QUEUE_REMOVE(q) \
+ do { \
+ QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \
+ QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \
+ } \
+ while (0)
+
+#endif /* QUEUE_H_ */
diff --git a/include/mbgl/util/raster.hpp b/include/mbgl/util/raster.hpp
index e526ffa5ac..7051c30091 100644
--- a/include/mbgl/util/raster.hpp
+++ b/include/mbgl/util/raster.hpp
@@ -4,11 +4,11 @@
#include <mbgl/util/transition.hpp>
#include <mbgl/util/texturepool.hpp>
#include <mbgl/util/image.hpp>
+#include <mbgl/util/ptr.hpp>
#include <mbgl/renderer/prerendered_texture.hpp>
#include <string>
#include <mutex>
-#include <memory>
typedef struct uv_loop_s uv_loop_t;
@@ -17,7 +17,7 @@ namespace mbgl {
class Raster : public std::enable_shared_from_this<Raster> {
public:
- Raster(const std::shared_ptr<Texturepool> &texturepool);
+ Raster(const util::ptr<Texturepool> &texturepool);
~Raster();
// load image data
@@ -57,7 +57,7 @@ private:
bool loaded = false;
// shared texture pool
- std::shared_ptr<Texturepool> texturepool;
+ util::ptr<Texturepool> texturepool;
// min/mag filter
uint32_t filter = 0;
@@ -66,7 +66,7 @@ private:
std::unique_ptr<util::Image> img;
// fade in transition
- std::shared_ptr<util::transition> fade_transition = nullptr;
+ util::ptr<util::transition> fade_transition = nullptr;
};
}
diff --git a/include/mbgl/util/sqlite3.hpp b/include/mbgl/util/sqlite3.hpp
new file mode 100644
index 0000000000..3e324f7ce1
--- /dev/null
+++ b/include/mbgl/util/sqlite3.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#include <string>
+#include <stdexcept>
+
+typedef struct sqlite3 sqlite3;
+typedef struct sqlite3_stmt sqlite3_stmt;
+
+namespace mapbox {
+namespace sqlite {
+
+enum OpenFlag : int {
+ ReadOnly = 0x00000001,
+ ReadWrite = 0x00000002,
+ Create = 0x00000004,
+ NoMutex = 0x00008000,
+ FullMutex = 0x00010000,
+ SharedCache = 0x00020000,
+ PrivateCache = 0x00040000,
+};
+
+struct Exception : std::runtime_error {
+ inline Exception(int err, const char *msg) : std::runtime_error(msg), code(err) {}
+ const int code = 0;
+};
+
+class Statement;
+
+class Database {
+private:
+ Database(const Database &) = delete;
+ Database &operator=(const Database &) = delete;
+
+public:
+ Database(const std::string &filename, int flags = 0);
+ Database(Database &&);
+ ~Database();
+ Database &operator=(Database &&);
+
+ operator bool() const;
+
+ void exec(const std::string &sql);
+ Statement prepare(const char *query);
+
+private:
+ sqlite3 *db = nullptr;
+};
+
+class Statement {
+private:
+ Statement(const Statement &) = delete;
+ Statement &operator=(const Statement &) = delete;
+
+public:
+ Statement(sqlite3 *db, const char *sql);
+ Statement(Statement &&);
+ ~Statement();
+ Statement &operator=(Statement &&);
+
+ operator bool() const;
+
+ template <typename T> void bind(int offset, T value);
+ void bind(int offset, const std::string &value, bool retain = true);
+ template <typename T> T get(int offset);
+
+ bool run();
+ void reset();
+
+private:
+ sqlite3_stmt *stmt = nullptr;
+};
+
+}
+}
diff --git a/include/mbgl/util/uv-channel.h b/include/mbgl/util/uv-channel.h
new file mode 100644
index 0000000000..ea5c279f65
--- /dev/null
+++ b/include/mbgl/util/uv-channel.h
@@ -0,0 +1,29 @@
+#ifndef MBGL_UTIL_UV_CHANNEL
+#define MBGL_UTIL_UV_CHANNEL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <uv.h>
+
+// Taken from http://navaneeth.github.io/blog/2013/08/02/channels-in-libuv/
+
+typedef struct uv_chan_s uv_chan_t;
+
+struct uv_chan_s {
+ uv_mutex_t mutex;
+ uv_cond_t cond;
+ void *q[2];
+};
+
+int uv_chan_init(uv_chan_t *chan);
+void uv_chan_send(uv_chan_t *chan, void *data);
+void *uv_chan_receive(uv_chan_t *chan);
+void uv_chan_destroy(uv_chan_t *chan);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/mbgl/util/uv-messenger.h b/include/mbgl/util/uv-messenger.h
new file mode 100644
index 0000000000..82b8ef2d9c
--- /dev/null
+++ b/include/mbgl/util/uv-messenger.h
@@ -0,0 +1,32 @@
+#ifndef MBGL_UTIL_UV_MESSENGER
+#define MBGL_UTIL_UV_MESSENGER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <uv.h>
+
+typedef struct uv_messenger_s uv_messenger_t;
+typedef void (*uv_messenger_cb)(void *arg);
+typedef void (*uv_messenger_stop_cb)(uv_messenger_t *msgr);
+
+struct uv_messenger_s {
+ uv_mutex_t mutex;
+ uv_async_t async;
+ uv_messenger_cb callback;
+ void *data;
+ void *queue[2];
+};
+
+int uv_messenger_init(uv_loop_t *loop, uv_messenger_t *msgr, uv_messenger_cb callback);
+void uv_messenger_send(uv_messenger_t *msgr, void *arg);
+void uv_messenger_stop(uv_messenger_t *msgr);
+void uv_messenger_ref(uv_messenger_t *msgr);
+void uv_messenger_unref(uv_messenger_t *msgr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/mbgl/util/uv-worker.h b/include/mbgl/util/uv-worker.h
new file mode 100644
index 0000000000..451b6fb04d
--- /dev/null
+++ b/include/mbgl/util/uv-worker.h
@@ -0,0 +1,42 @@
+#ifndef MBGL_UTIL_UV_WORKER
+#define MBGL_UTIL_UV_WORKER
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct uv_messenger_s uv_messenger_t;
+
+#include <mbgl/util/uv-channel.h>
+
+#include <stdlib.h>
+
+typedef struct uv_worker_s uv_worker_t;
+
+typedef void (*uv_worker_cb)(void *data);
+typedef void (*uv_worker_after_cb)(void *data);
+typedef void (*uv_worker_close_cb)(uv_worker_t *worker);
+
+struct uv_worker_s {
+#ifndef NDEBUG
+ unsigned long thread_id;
+#endif
+ uv_loop_t *loop;
+ uv_messenger_t *msgr;
+ uv_chan_t chan;
+ const char *name;
+ int count;
+ uv_worker_close_cb close_cb;
+ unsigned int active_items;
+};
+
+int uv_worker_init(uv_worker_t *worker, uv_loop_t *loop, int count, const char *name);
+void uv_worker_send(uv_worker_t *worker, void *data, uv_worker_cb work_cb,
+ uv_worker_after_cb after_work_cb);
+void uv_worker_close(uv_worker_t *worker, uv_worker_close_cb close_cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/mbgl/util/uv.hpp b/include/mbgl/util/uv.hpp
index 4ceb8b873f..3c533cfbf8 100644
--- a/include/mbgl/util/uv.hpp
+++ b/include/mbgl/util/uv.hpp
@@ -4,6 +4,7 @@
#include <string>
typedef struct uv_async_s uv_async_t;
+typedef struct uv_timer_s uv_timer_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_loop_s uv_loop_t;
@@ -11,9 +12,15 @@ namespace uv {
std::string cwd();
+struct deleter {
+ void operator()(uv_async_t *async);
+ void operator()(uv_timer_t *timer);
+};
+
class thread;
class rwlock;
class loop;
+class worker;
}
diff --git a/include/mbgl/util/uv_detail.hpp b/include/mbgl/util/uv_detail.hpp
index b3fdbb3719..a80423f822 100644
--- a/include/mbgl/util/uv_detail.hpp
+++ b/include/mbgl/util/uv_detail.hpp
@@ -1,21 +1,13 @@
#ifndef MBGL_UTIL_UV_DETAIL
#define MBGL_UTIL_UV_DETAIL
+#include <mbgl/util/ptr.hpp>
+#include <mbgl/util/uv-worker.h>
+
#include <uv.h>
+
#include <functional>
#include <cassert>
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-parameter"
-#endif
-
-#include <boost/lockfree/queue.hpp>
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
#include <string>
@@ -112,6 +104,24 @@ private:
uv_once_t o = UV_ONCE_INIT;
};
+class worker {
+public:
+ inline worker(uv_loop_t *loop, unsigned int count, const char *name = nullptr) : w(new uv_worker_t) {
+ uv_worker_init(w, loop, count, name);
+ }
+ inline ~worker() {
+ uv_worker_close(w, [](uv_worker_t *worker) {
+ delete worker;
+ });
+ }
+ inline void add(void *data, uv_worker_cb work_cb, uv_worker_after_cb after_work_cb) {
+ uv_worker_send(w, data, work_cb, after_work_cb);
+ }
+
+private:
+ uv_worker_t *w;
+};
+
template <typename T>
class work {
public:
@@ -119,30 +129,26 @@ public:
typedef void (*after_work_callback)(T &object);
template<typename... Args>
- work(const std::shared_ptr<loop> &loop, work_callback work_cb, after_work_callback after_work_cb, Args&&... args)
- : loop(loop),
- data(std::forward<Args>(args)...),
+ work(worker &worker, work_callback work_cb, after_work_callback after_work_cb, Args&&... args)
+ : data(std::forward<Args>(args)...),
work_cb(work_cb),
after_work_cb(after_work_cb) {
- req.data = this;
- uv_queue_work(**loop, &req, do_work, after_work);
+ worker.add(this, do_work, after_work);
}
private:
- static void do_work(uv_work_t *req) {
- work<T> *w = static_cast<work<T> *>(req->data);
+ static void do_work(void *data) {
+ work<T> *w = reinterpret_cast<work<T> *>(data);
w->work_cb(w->data);
}
- static void after_work(uv_work_t *req, int) {
- work<T> *w = static_cast<work<T> *>(req->data);
+ static void after_work(void *data) {
+ work<T> *w = reinterpret_cast<work<T> *>(data);
w->after_work_cb(w->data);
delete w;
}
private:
- std::shared_ptr<uv::loop> loop;
- uv_work_t req;
T data;
work_callback work_cb;
after_work_callback after_work_cb;