void VectorTileData::redoPlacement(const std::function<void()>& callback) { // Don't start a new placement request when the current one hasn't completed yet, or when // we are parsing buckets. if (workRequest) return; workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, callback, config = targetConfig] { workRequest.reset(); // Persist the configuration we just placed so that we can later check whether we need to // place again in case the configuration has changed. placedConfig = config; for (auto& bucket : buckets) { bucket.second->swapRenderData(); } // The target configuration could have changed since we started placement. In this case, // we're starting another placement run. if (placedConfig != targetConfig) { redoPlacement(callback); } else { callback(); } }); }
void VectorTileData::redoPlacement(const PlacementConfig newConfig, const std::function<void()>& callback) { if (newConfig != placedConfig) { targetConfig = newConfig; redoPlacement(callback); } }
void VectorTileData::redoPlacement(const PlacementConfig newConfig) { if (newConfig != placedConfig) { targetConfig = newConfig; if (!workRequest) { // Don't start a new placement request when the current one hasn't completed yet, or when // we are parsing buckets. redoPlacement(); } } }
void VectorTileData::redoPlacement() { workRequest.reset(); workRequest = worker.redoPlacement(tileWorker, style.getLayers(), buckets, targetConfig, [this, config = targetConfig] { workRequest.reset(); // Persist the configuration we just placed so that we can later check whether we need to // place again in case the configuration has changed. placedConfig = config; for (auto& bucket : buckets) { bucket.second->swapRenderData(); } // The target configuration could have changed since we started placement. In this case, // we're starting another placement run. if (placedConfig != targetConfig) { redoPlacement(); } }); }
bool VectorTileData::parsePending(std::function<void()> callback) { if (workRequest) { // There's already parsing or placement going on. return false; } workRequest.reset(); workRequest = worker.parsePendingGeometryTileLayers(tileWorker, [this, callback] (TileParseResult result) { workRequest.reset(); if (state == State::obsolete) { return; } if (result.is<TileParseResultBuckets>()) { auto& resultBuckets = result.get<TileParseResultBuckets>(); state = resultBuckets.state; // Move over all buckets we received in this parse request, potentially overwriting // existing buckets in case we got a refresh parse. for (auto& bucket : resultBuckets.buckets) { buckets[bucket.first] = std::move(bucket.second); } // The target configuration could have changed since we started placement. In this case, // we're starting another placement run. if (placedConfig != targetConfig) { redoPlacement(); } } else { std::stringstream message; message << "Failed to parse [" << std::string(id) << "]: " << result.get<std::string>(); error = message.str(); state = State::obsolete; } callback(); }); return true; }
VectorTileData::VectorTileData(const TileID& id_, std::unique_ptr<GeometryTileMonitor> monitor_, std::string sourceID, Style& style_, const std::function<void()>& callback) : TileData(id_), style(style_), worker(style_.workers), tileWorker(id_, sourceID, *style_.spriteStore, *style_.glyphAtlas, *style_.glyphStore, state), monitor(std::move(monitor_)) { state = State::loading; tileRequest = monitor->monitorTile([callback, this](std::exception_ptr err, std::unique_ptr<GeometryTile> tile, Seconds modified_, Seconds expires_) { if (err) { try { std::rethrow_exception(err); } catch (const std::exception& e) { error = e.what(); state = State::obsolete; callback(); return; } } if (!tile) { state = State::parsed; buckets.clear(); callback(); return; } if (state == State::loading) { state = State::loaded; } else if (isReady()) { state = State::partial; } modified = modified_; expires = expires_; // Kick off a fresh parse of this tile. This happens when the tile is new, or // when tile data changed. Replacing the workdRequest will cancel a pending work // request in case there is one. workRequest.reset(); workRequest = worker.parseGeometryTile(tileWorker, style.getLayers(), std::move(tile), targetConfig, [callback, this, config = targetConfig] (TileParseResult result) { workRequest.reset(); if (state == State::obsolete) { return; } if (result.is<TileParseResultBuckets>()) { auto& resultBuckets = result.get<TileParseResultBuckets>(); state = resultBuckets.state; // Persist the configuration we just placed so that we can later check whether we need to // place again in case the configuration has changed. placedConfig = config; // Move over all buckets we received in this parse request, potentially overwriting // existing buckets in case we got a refresh parse. buckets = std::move(resultBuckets.buckets); // The target configuration could have changed since we started placement. In this case, // we're starting another placement run. if (placedConfig != targetConfig) { redoPlacement(); } } else { std::stringstream message; message << "Failed to parse [" << std::string(id) << "]: " << result.get<std::string>(); error = message.str(); state = State::obsolete; } callback(); }); }); }