feat: wire V4 QBIN host API into RasterArraySource
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl::style {
|
||||
@@ -22,8 +23,56 @@ namespace {
|
||||
// same source ID, and that must always invalidate the prior GPU field.
|
||||
std::atomic_uint64_t nextRasterArrayFieldGeneration{0};
|
||||
|
||||
bool validEncodedFieldKey(const std::string& fieldKey) {
|
||||
if (fieldKey.empty() || fieldKey.size() > 128) return false;
|
||||
return std::all_of(fieldKey.begin(), fieldKey.end(), [](const unsigned char value) {
|
||||
return std::isalnum(value) || value == '.' || value == '_' || value == '-' || value == ':';
|
||||
});
|
||||
}
|
||||
|
||||
bool validRuntimeMetadata(const particle::ingress::EncodedFieldRuntimeMetadata& metadata) {
|
||||
return !metadata.fieldID.empty() && metadata.fieldID.size() <= 128 && metadata.generation != 0;
|
||||
}
|
||||
|
||||
RasterArrayEncodedFieldSubmitResult mapEncodedFieldStoreResult(const particle::FieldSeriesSubmitResult result) {
|
||||
switch (result) {
|
||||
case particle::FieldSeriesSubmitResult::Inserted: return RasterArrayEncodedFieldSubmitResult::AcceptedInserted;
|
||||
case particle::FieldSeriesSubmitResult::ReplacedRevision:
|
||||
return RasterArrayEncodedFieldSubmitResult::AcceptedReplacedRevision;
|
||||
case particle::FieldSeriesSubmitResult::Duplicate: return RasterArrayEncodedFieldSubmitResult::Duplicate;
|
||||
case particle::FieldSeriesSubmitResult::RejectedInvalidFieldKey:
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedInvalidFieldKey;
|
||||
case particle::FieldSeriesSubmitResult::RejectedIdentityConflict:
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedIdentityConflict;
|
||||
case particle::FieldSeriesSubmitResult::RejectedStaleRevision:
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedStaleRevision;
|
||||
case particle::FieldSeriesSubmitResult::RejectedIncompatibleFrame:
|
||||
case particle::FieldSeriesSubmitResult::RejectedInvalidFrame:
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedIncompatible;
|
||||
case particle::FieldSeriesSubmitResult::RejectedCapacity:
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedCapacity;
|
||||
}
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedIncompatible;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const char* rasterArrayEncodedFieldSubmitResultName(const RasterArrayEncodedFieldSubmitResult result) {
|
||||
switch (result) {
|
||||
case RasterArrayEncodedFieldSubmitResult::AcceptedInserted: return "AcceptedInserted";
|
||||
case RasterArrayEncodedFieldSubmitResult::AcceptedReplacedRevision: return "AcceptedReplacedRevision";
|
||||
case RasterArrayEncodedFieldSubmitResult::Duplicate: return "Duplicate";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedDecode: return "RejectedDecode";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedContract: return "RejectedContract";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedInvalidFieldKey: return "RejectedInvalidFieldKey";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedIdentityConflict: return "RejectedIdentityConflict";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedStaleRevision: return "RejectedStaleRevision";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedIncompatible: return "RejectedIncompatible";
|
||||
case RasterArrayEncodedFieldSubmitResult::RejectedCapacity: return "RejectedCapacity";
|
||||
}
|
||||
return "RejectedIncompatible";
|
||||
}
|
||||
|
||||
RasterArrayTimelineRuntime::RasterArrayTimelineRuntime(std::vector<Entry> entries_)
|
||||
: entries(std::move(entries_)) {
|
||||
if (entries.size() < 2) {
|
||||
@@ -307,6 +356,53 @@ RasterArraySource::~RasterArraySource() {
|
||||
weakFactory.invalidateWeakPtrs();
|
||||
}
|
||||
|
||||
RasterArrayEncodedFieldSubmitResult RasterArraySource::submitEncodedField(
|
||||
const std::string& fieldKey,
|
||||
const particle::ingress::EncodedFieldRuntimeMetadata& runtimeMetadata,
|
||||
const particle::ResolvedFieldProfileContract& contract,
|
||||
const std::vector<uint8_t>& rawQbinBytes) {
|
||||
// Keep every failure before Store::submit side-effect-free. Decoder also
|
||||
// checks metadata, but validate it here to make the Host ordering explicit.
|
||||
if (!validEncodedFieldKey(fieldKey)) return RasterArrayEncodedFieldSubmitResult::RejectedInvalidFieldKey;
|
||||
if (!validRuntimeMetadata(runtimeMetadata)) return RasterArrayEncodedFieldSubmitResult::RejectedDecode;
|
||||
const auto decoded = particle::ingress::QbinV2Decoder::decode(runtimeMetadata, rawQbinBytes);
|
||||
if (!decoded.accepted()) return RasterArrayEncodedFieldSubmitResult::RejectedDecode;
|
||||
if (!particle::FieldProfileValidator::validate(contract, *decoded.frame).accepted())
|
||||
return RasterArrayEncodedFieldSubmitResult::RejectedContract;
|
||||
return mapEncodedFieldStoreResult(encodedFieldStore.submit(fieldKey, std::move(decoded.frame)));
|
||||
}
|
||||
|
||||
void RasterArraySource::setColorBinding(particle::ColorBinding binding) { colorBinding = std::move(binding); }
|
||||
|
||||
void RasterArraySource::setParticleBinding(particle::ParticleBinding binding) { particleBinding = std::move(binding); }
|
||||
|
||||
bool RasterArraySource::setRequestedForecastTime(const uint64_t timestampMs) {
|
||||
return forecastClock.setRequestedForecastTime(timestampMs);
|
||||
}
|
||||
|
||||
void RasterArraySource::setForecastPlaybackState(const particle::ForecastPlaybackState state) {
|
||||
state == particle::ForecastPlaybackState::Playing ? forecastClock.play() : forecastClock.pause();
|
||||
}
|
||||
|
||||
bool RasterArraySource::setForecastPlaybackSpeed(const float value) { return forecastClock.setPlaybackSpeed(value); }
|
||||
|
||||
bool RasterArraySource::advanceForecastClock(const uint64_t elapsedMs) { return forecastClock.advance(elapsedMs); }
|
||||
|
||||
particle::ColorProjectionResult RasterArraySource::resolveColorProjection() const {
|
||||
if (!colorBinding) return {particle::BindingProjectionError::InvalidBinding, {}};
|
||||
return particle::BindingProjectionResolver::resolve(encodedFieldStore, *colorBinding, forecastClock.requestedForecastTime());
|
||||
}
|
||||
|
||||
particle::ParticleProjectionResult RasterArraySource::resolveParticleProjection() const {
|
||||
if (!particleBinding) return {particle::BindingProjectionError::InvalidBinding, {}};
|
||||
return particle::BindingProjectionResolver::resolve(encodedFieldStore, *particleBinding,
|
||||
forecastClock.requestedForecastTime());
|
||||
}
|
||||
|
||||
bool RasterArraySource::clearEncodedField(const std::string& fieldKey) { return encodedFieldStore.clear(fieldKey); }
|
||||
|
||||
void RasterArraySource::clearAllEncodedFields() { encodedFieldStore.clearAll(); }
|
||||
|
||||
const RasterArraySource::Impl& RasterArraySource::impl() const {
|
||||
return static_cast<const Impl&>(*baseImpl);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user