diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index 19a57ab52..b6cffb417 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -65,8 +65,8 @@ private: bool findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::forward_list& retain); bool findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list& retain); bool updateTiles(); - const Tile *addTile(const Tile::ID& id); - const Tile *hasTile(const Tile::ID& id); + TileData::State addTile(const Tile::ID& id); + TileData::State hasTile(const Tile::ID& id); void update(); diff --git a/include/llmr/map/tile_data.hpp b/include/llmr/map/tile_data.hpp index 67aa3e530..98709ad32 100644 --- a/include/llmr/map/tile_data.hpp +++ b/include/llmr/map/tile_data.hpp @@ -42,7 +42,8 @@ public: public: typedef std::shared_ptr Ptr; - enum state { + enum class State { + invalid, initial, loading, loaded, @@ -71,7 +72,7 @@ public: public: const Tile::ID id; - std::atomic state; + std::atomic state; // Holds the actual geometries in this tile. DebugFontBuffer debugFontBuffer; diff --git a/src/map/map.cpp b/src/map/map.cpp index 8ab9f7f64..a57396280 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -238,21 +238,21 @@ void Map::update() { } -const Tile *Map::hasTile(const Tile::ID& id) { +TileData::State Map::hasTile(const Tile::ID& id) { for (const Tile& tile : tiles) { - if (tile.id == id) { - return &tile; + if (tile.id == id && tile.data) { + return tile.data->state; } } - return nullptr; + return TileData::State::invalid; } -const Tile *Map::addTile(const Tile::ID& id) { - const Tile *tile = hasTile(id); +TileData::State Map::addTile(const Tile::ID& id) { + const TileData::State state = hasTile(id); - if (tile) { - return tile; + if (state != TileData::State::invalid) { + return state; } tiles.emplace_front(id); @@ -271,9 +271,11 @@ const Tile *Map::addTile(const Tile::ID& id) { new_tile.data = it->lock(); } else { new_tile.data = std::make_shared(normalized_id, style); + new_tile.data->request(); tile_data.push_front(new_tile.data); } - return &new_tile; + + return new_tile.data->state; } /** @@ -291,9 +293,9 @@ bool Map::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::f auto ids = Tile::children(id, z + 1); for (const Tile::ID& child_id : ids) { - const Tile *tile = hasTile(child_id); - if (tile && tile->data && tile->data->state == TileData::parsed) { - retain.emplace_front(tile->id); + const TileData::State state = hasTile(child_id); + if (state == TileData::State::parsed) { + retain.emplace_front(child_id); } else { complete = false; if (z < maxCoveringZoom) { @@ -317,9 +319,9 @@ bool Map::findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::f bool Map::findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list& retain) { for (int32_t z = id.z - 1; z >= minCoveringZoom; --z) { const Tile::ID parent_id = Tile::parent(id, z); - const Tile *tile = hasTile(parent_id); - if (tile && tile->data && tile->data->state == TileData::parsed) { - retain.emplace_front(tile->id); + const TileData::State state = hasTile(parent_id); + if (state == TileData::State::parsed) { + retain.emplace_front(parent_id); return true; } } @@ -355,10 +357,9 @@ bool Map::updateTiles() { // Add existing child/parent tiles if the actual tile is not yet loaded for (const Tile::ID& id : required) { - const Tile *tile = addTile(id); - assert(tile); + const TileData::State state = addTile(id); - if (tile && tile->data && tile->data->state != TileData::parsed) { + if (state != TileData::State::parsed) { // The tile we require is not yet loaded. Try to find a parent or // child tile that we already have. @@ -373,9 +374,7 @@ bool Map::updateTiles() { } } - if (tile && tile->data && tile->data->state == TileData::initial) { - // If the tile is new, we have to make sure to load it. - tile->data->request(); + if (state == TileData::State::initial) { changed = true; } } @@ -421,7 +420,7 @@ bool Map::render() { uint8_t i = 1; painter.prepareClippingMask(); for (Tile& tile : tiles) { - if (tile.data && tile.data->state == TileData::parsed) { + if (tile.data && tile.data->state == TileData::State::parsed) { // The position matrix. transform.matrixFor(tile.matrix, tile.id); matrix::multiply(tile.matrix, painter.projMatrix, tile.matrix); @@ -432,7 +431,7 @@ bool Map::render() { painter.finishClippingMask(); for (const Tile& tile : tiles) { - if (tile.data && tile.data->state == TileData::parsed) { + if (tile.data && tile.data->state == TileData::State::parsed) { painter.render(tile); } } diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 7df8183ba..aadb60785 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -18,7 +18,7 @@ using namespace llmr; TileData::TileData(Tile::ID id, const Style& style) : id(id), - state(initial), + state(State::initial), fillVertexBuffer(std::make_shared()), lineVertexBuffer(std::make_shared()), pointVertexBuffer(std::make_shared()), @@ -41,7 +41,7 @@ const std::string TileData::toString() const { } void TileData::request() { - state = loading; + state = State::loading; // Create http request std::string url = util::sprintf(kTileURL, @@ -50,11 +50,11 @@ void TileData::request() { // Note: Somehow this feels slower than the change to request_http() std::shared_ptr tile = shared_from_this(); platform::Request *request = platform::request_http(url, [=](platform::Response& res) { - if (res.code == 200 && tile->state != obsolete) { - tile->state = loaded; + if (res.code == 200 && tile->state != State::obsolete) { + tile->state = State::loaded; tile->data.swap(res.body); tile->parse(); - } else if (tile->state != obsolete) { + } else if (tile->state != State::obsolete) { fprintf(stderr, "tile loading failed\n"); } }, []() { @@ -64,8 +64,8 @@ void TileData::request() { } void TileData::cancel() { - if (state != obsolete) { - state = obsolete; + if (state != State::obsolete) { + state = State::obsolete; platform::cancel_request_http(req); } else { assert((!"logic error? multiple cancelleations")); @@ -73,7 +73,7 @@ void TileData::cancel() { } bool TileData::parse() { - if (state != loaded) { + if (state != State::loaded) { return false; } @@ -82,7 +82,7 @@ bool TileData::parse() { VectorTile tile(pbf((const uint8_t *)data.data(), data.size())); parseStyleLayers(tile, style.layers); double parse_time = (platform::time() - parse_time_start) * 1000.0; - if (state == obsolete) { + if (state == State::obsolete) { // fprintf(stderr, "[%p] parsing [%d/%d/%d] cancelled after %8.3fms\n", this, id.z, id.x, id.y, parse_time); } else { // fprintf(stderr, "[%p] parsing [%d/%d/%d] took %8.3fms\n", this, id.z, id.x, id.y, parse_time); @@ -93,10 +93,10 @@ bool TileData::parse() { return false; } - if (state == obsolete) { + if (state == State::obsolete) { return false; } else { - state = parsed; + state = State::parsed; } return true; @@ -105,7 +105,7 @@ bool TileData::parse() { void TileData::parseStyleLayers(const VectorTile& tile, const std::vector& layers) { for (const LayerDescription& layer_desc : layers) { // Cancel early when parsing. - if (state == obsolete) { + if (state == State::obsolete) { return; } @@ -164,7 +164,7 @@ std::shared_ptr TileData::createFillBucket(const VectorTileLayer& layer, FilteredVectorTileLayer filtered_layer(layer, bucket_desc); for (pbf feature : filtered_layer) { - if (state == obsolete) return nullptr; + if (state == State::obsolete) return nullptr; while (feature.next(4)) { // geometry pbf geometry_pbf = feature.message(); @@ -183,7 +183,7 @@ std::shared_ptr TileData::createLineBucket(const VectorTileLayer& layer, FilteredVectorTileLayer filtered_layer(layer, bucket_desc); for (pbf feature : filtered_layer) { - if (state == obsolete) return nullptr; + if (state == State::obsolete) return nullptr; while (feature.next(4)) { // geometry pbf geometry_pbf = feature.message(); @@ -201,7 +201,7 @@ std::shared_ptr TileData::createPointBucket(const VectorTileLayer& layer FilteredVectorTileLayer filtered_layer(layer, bucket_desc); for (pbf feature : filtered_layer) { - if (state == obsolete) return nullptr; + if (state == State::obsolete) return nullptr; while (feature.next(4)) { // geometry pbf geometry_pbf = feature.message(); diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 9a4ffe4a2..8b4ff0777 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -132,7 +132,7 @@ void Painter::clear() { void Painter::render(const Tile& tile) { assert(tile.data); - if (tile.data->state != TileData::parsed) { + if (tile.data->state != TileData::State::parsed) { return; }