feat: establish formal raster particle source chain

This commit is contained in:
OpenAI Codex
2026-08-31 12:17:06 +08:00
parent 343cecc778
commit 39c7ae22ed
40 changed files with 811 additions and 130 deletions

View File

@@ -0,0 +1,80 @@
#include <mbgl/style/sources/raster_array_source.hpp>
#include <mbgl/particle/field/offline_fixture_particle_adapter.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/style/source_observer.hpp>
#include <mbgl/style/sources/raster_array_source_impl.hpp>
#include <mbgl/util/async_request.hpp>
#include <mbgl/util/logging.hpp>
namespace mbgl::style {
RasterArraySource::RasterArraySource(std::string id,
std::string fixtureID,
std::string metadataURL,
std::string fieldURL)
: Source(makeMutable<Impl>(std::move(id), std::move(fixtureID), std::move(metadataURL), std::move(fieldURL))) {}
RasterArraySource::~RasterArraySource() {
weakFactory.invalidateWeakPtrs();
}
const RasterArraySource::Impl& RasterArraySource::impl() const {
return static_cast<const Impl&>(*baseImpl);
}
void RasterArraySource::loadDescription(FileSource& fileSource) {
if (metadataRequest || fieldRequest) return;
metadataRequest = fileSource.request(
Resource::source(impl().metadataURL), [this, self = makeWeakPtr()](const Response& response) {
if (auto guard = self.lock(); self) {
if (response.error || response.noContent || !response.data) {
observer->onSourceError(
*this, std::make_exception_ptr(std::runtime_error("particle metadata request failed")));
return;
}
metadata = *response.data;
tryLoad();
}
});
fieldRequest = fileSource.request(
Resource::source(impl().fieldURL), [this, self = makeWeakPtr()](const Response& response) {
if (auto guard = self.lock(); self) {
if (response.error || response.noContent || !response.data) {
observer->onSourceError(
*this, std::make_exception_ptr(std::runtime_error("particle field request failed")));
return;
}
fieldBytes = std::vector<char>(response.data->begin(), response.data->end());
tryLoad();
}
});
}
void RasterArraySource::tryLoad() {
if (!metadata || !fieldBytes) return;
try {
auto field = particle::OfflineFixtureParticleAdapter::load(
impl().fixtureID, *metadata, *fieldBytes, ++generation);
baseImpl = makeMutable<Impl>(impl(), std::move(field));
loaded = true;
Log::Info(Event::Render,
"ParticleField: source loaded fixtureId=" + impl().fixtureID + " metadata=" + impl().metadataURL +
" field=" + impl().fieldURL);
observer->onSourceLoaded(*this);
observer->onSourceChanged(*this);
} catch (const std::exception& error) {
observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.what())));
}
}
bool RasterArraySource::supportsLayerType(const LayerTypeInfo* info) const {
return info && std::string(info->type) == "raster-particle";
}
Mutable<Source::Impl> RasterArraySource::createMutable() const noexcept {
return staticMutableCast<Source::Impl>(makeMutable<Impl>(impl()));
}
} // namespace mbgl::style