diff options
Diffstat (limited to 'include')
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 ↦ 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; |