7 SequenceChildSchedule::SequenceChildSchedule(
8 std::shared_ptr<const Description> description)
9 : description_(std::move(description)) {}
11 std::expected<SequenceChildSchedule, ChildScheduleError>
19 std::expected<SequenceChildSchedule, ChildScheduleError>
23 auto description = std::make_shared<Description>(Description{reader, containingDataId, {}});
28 if (!chunk)
return std::unexpected(ChildScheduleError{ chunk.error() });
30 if (chunk->id >= 1 && chunk->id < 11)
33 return std::unexpected(ChildScheduleError{ data::SequenceError{
34 data::SequenceErrorCode::RecordLimitExceeded,
35 chunk->headerOffset,
"child sequence record budget exceeded",
37 auto record = data::readLegacySequenceRecord(reader);
39 return std::unexpected(ChildScheduleError{ record.error() });
40 description->records.push_back(std::move(*record));
43 return std::unexpected(ChildScheduleError{
ascended.error() });
48 auto skipped = reader.
seek(chunk->endOffset);
50 return std::unexpected(ChildScheduleError{ skipped.error() });
53 return SequenceChildSchedule(std::move(description));
56 std::span<const data::LegacySequenceRecord>
57 SequenceChildSchedule::records()
const noexcept {
return description_->records; }
59 {
return description_->containingDataId; }
60 std::size_t SequenceChildSchedule::nextIndex()
const noexcept {
return nextIndex_; }
63 SequenceChildSchedule::select(std::optional<std::int32_t>
previous,
68 data::SequenceErrorCode::InvalidClockRange, description_->reader.currentOffset(),
69 "child scan cannot run backwards; rewind and rescan from minus infinity",
71 std::vector<std::size_t> selected;
72 auto next = nextIndex_;
73 for (;
next < description_->records.size(); ++
next)
75 const auto&
header = description_->records[
next].header;
76 if (
header.parentStartTime > current)
break;
77 const auto end =
static_cast<std::int64_t
>(
header.parentStartTime) +
80 (
header.endingAction != 1 ||
header.endTime == 0 || end > current))
81 selected.push_back(
next);
87 void SequenceChildSchedule::rewind()
noexcept { nextIndex_ = 0; }
89 std::expected<data::LegacyChunkReader, data::ChunkError>
90 SequenceChildSchedule::readerForChild(std::size_t
index)
const
92 if (
index >= description_->records.size())
94 data::ChunkErrorCode::PositionOutOfRange, description_->reader.currentOffset(),
95 "child record index is out of range" });
96 auto reader = description_->reader;
97 const auto seek = reader.
seek(description_->records[
index].chunk.headerOffset);
98 if (!seek)
return std::unexpected(seek.error());
102 std::expected<SequenceChildSchedule, ChildScheduleError>
110 auto parent = data::readLegacySequenceRecord(*reader);
112 if (
const auto*
indirect = std::get_if<data::SequenceIndirectData>(&parent->data))
114 const auto id = data::resolveSequenceDataId(parent->header,
127 data::ChunkErrorCode::PositionOutOfRange, 0,
128 "same-item indirect child list starts outside its parent chunk" } });
std::vector< std::byte > bytes
std::shared_ptr< const data::HmdTextureImage > source
std::expected< void, ChunkError > ascend()
std::expected< ChunkInfo, ChunkError > descend(std::uint8_t findId=NullStandardId)
std::expected< void, ChunkError > seek(std::size_t absoluteOffset)
std::size_t remaining() const noexcept
std::shared_ptr< const DataBytes > SharedDataBytes
std::expected< SequenceChildSchedule, ChildScheduleError > openSequenceChildSchedule(const data::DataSource &source, data::DataId parentDataId, std::size_t parentOffset, std::size_t maximumRecords)
std::variant< data::DataError, data::ChunkError, data::SequenceError > ChildScheduleError