Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Parse GeoJSONSource description in background
Browse files Browse the repository at this point in the history
Unblocks the UI thread on heavy GeoJSON tiles parsing operation
  • Loading branch information
pozdnyakov committed Nov 5, 2019
1 parent 31421f8 commit e6e6bcf
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions src/mbgl/style/sources/geojson_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <mbgl/style/sources/geojson_source_impl.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/thread_pool.hpp>

namespace mbgl {
namespace style {
Expand Down Expand Up @@ -69,18 +70,29 @@ void GeoJSONSource::loadDescription(FileSource& fileSource) {
observer->onSourceError(
*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
} else {
conversion::Error error;
std::shared_ptr<GeoJSONData> geoJSONData;
if (optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error)) {
geoJSONData = GeoJSONData::create(*geoJSON, impl().getOptions());
} else {
// Create an empty GeoJSON VT object to make sure we're not infinitely waiting for tiles to load.
Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
error.message.c_str());
}
baseImpl = makeMutable<Impl>(impl(), std::move(geoJSONData));
loaded = true;
observer->onSourceLoaded(*this);
auto makeImplInBackground = [currentImpl = baseImpl, data = res.data]() -> Immutable<Source::Impl> {
assert(data);
auto& impl = static_cast<const Impl&>(*currentImpl);
conversion::Error error;
std::shared_ptr<GeoJSONData> geoJSONData;
if (optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*data, error)) {
geoJSONData = GeoJSONData::create(*geoJSON, impl.getOptions());
} else {
// Create an empty GeoJSON VT object to make sure we're not infinitely waiting for tiles to load.
Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", error.message.c_str());
}
return makeMutable<Impl>(impl, std::move(geoJSONData));
};
auto onImplReady = [this, self = makeWeakPtr(), capturedReq = req.get()](Immutable<Source::Impl> newImpl) {
assert(capturedReq);
if (!self) return; // This source has been deleted.
if (capturedReq != req.get()) return; // A new request is being processed, ignore this impl.

baseImpl = std::move(newImpl);
loaded = true;
observer->onSourceLoaded(*this);
};
Scheduler::GetBackground()->scheduleAndReplyValue(makeImplInBackground, onImplReady);
}
});
}
Expand Down

0 comments on commit e6e6bcf

Please sign in to comment.