#ifndef MBGL_MAP_MAP #define MBGL_MAP_MAP #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { class Painter; class GlyphStore; class LayerDescription; class Sprite; class Style; class StyleLayer; class StyleLayerGroup; class StyleSource; class TexturePool; class FileSource; class View; class GlyphAtlas; class SpriteAtlas; class Map : private util::noncopyable { typedef void (*stop_callback)(void *); public: explicit Map(View&, FileSource&); ~Map(); // Start the map render thread. It is asynchronous. void start(); // 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(); // Forces a map update: always triggers a rerender. void update(); // Triggers a cleanup that releases resources. void cleanup(); // Releases resources immediately void terminate(); // Controls buffer swapping. bool needsSwap(); void swapped(); // Size void resize(uint16_t width, uint16_t height, float ratio = 1); void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height); // Styling void setAppliedClasses(const std::vector &classes); void toggleClass(const std::string &name); const std::vector &getAppliedClasses() const; void setDefaultTransitionDuration(uint64_t milliseconds = 0); void setStyleURL(const std::string &url); void setStyleJSON(std::string newStyleJSON, const std::string &base = ""); std::string getStyleJSON() const; void setAccessToken(std::string accessToken); std::string getAccessToken() const; // Transition void cancelTransitions(); // Position void moveBy(double dx, double dy, double duration = 0); void setLonLat(double lon, double lat, double duration = 0); void getLonLat(double &lon, double &lat) const; void startPanning(); void stopPanning(); void resetPosition(); // Scale void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0); void setScale(double scale, double cx = -1, double cy = -1, double duration = 0); double getScale() const; void setZoom(double zoom, double duration = 0); double getZoom() const; void setLonLatZoom(double lon, double lat, double zoom, double duration = 0); void getLonLatZoom(double &lon, double &lat, double &zoom) const; void resetZoom(); void startScaling(); void stopScaling(); double getMinZoom() const; double getMaxZoom() const; // Rotation void rotateBy(double sx, double sy, double ex, double ey, double duration = 0); void setBearing(double degrees, double duration = 0); void setBearing(double degrees, double cx, double cy); double getBearing() const; void resetNorth(); void startRotating(); void stopRotating(); // Debug void setDebug(bool value); void toggleDebug(); bool getDebug() const; // Call this when the network reachability changed. void setReachability(bool status); inline const TransformState &getState() const { return state; } inline timestamp getTime() const { return animationTime; } private: util::ptr getSprite(); uv::worker& getWorker(); // Setup void setup(); void updateTiles(); void updateSources(); void updateSources(const util::ptr &group); // Prepares a map render by updating the tiles we need for the current view, as well as updating // the stylesheet. void prepare(); // Unconditionally performs a render with the current map state. void render(); bool async = false; std::unique_ptr loop; std::unique_ptr workers; std::thread thread; std::unique_ptr asyncTerminate; std::unique_ptr asyncRender; std::unique_ptr asyncCleanup; // If cleared, the next time the render thread attempts to render the map, it will *actually* // render the map. std::atomic_flag isClean = ATOMIC_FLAG_INIT; // If this flag is cleared, the current back buffer is ready for being swapped with the front // buffer (i.e. it has rendered data). std::atomic_flag isSwapped = ATOMIC_FLAG_INIT; // This is cleared once the current front buffer has been presented and the back buffer is // ready for rendering. std::atomic_flag isRendered = ATOMIC_FLAG_INIT; // Stores whether the map thread has been stopped already. std::atomic_bool isStopped; View &view; #ifndef NDEBUG const std::thread::id mainThread; std::thread::id mapThread; #endif Transform transform; TransformState state; FileSource& fileSource; util::ptr