Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
SequenceClock.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "LegacySequence.hpp"
4
5#include <cstdint>
6#include <expected>
7#include <optional>
8#include <string_view>
9
10namespace monopoly::sequence
11{
22
23 [[nodiscard]] std::string_view clockErrorName(ClockError error) noexcept;
24
26 {
27 // Nonzero replacements have the source command semantics. Zero keeps
28 // the corresponding disk value (L_Seqncr.cpp:3766-3784).
29 std::uint8_t timeMultiple{};
30 std::uint8_t endingAction{};
31 std::optional<bool> dropFrames;
32 std::int32_t initialClockOffset{};
33 std::optional<std::int32_t> endTimeOverride;
34 // Omit for a top-level sequence; supply the parent's current clock
35 // for a newly born child. This is not its last-update timestamp.
36 std::optional<std::int32_t> parentClockAtBirth;
37 };
38
40 {
41 bool updated{};
42 // No previous clock means the initial scan begins at minus infinity.
43 std::optional<std::int32_t> previousClock;
44 std::int32_t clock{};
45 bool hitEnd{}; // callback/watch condition, including held ends
46 bool notifyEnd{}; // label event condition; held ends notify once
48 bool stopped{};
49 };
50
51 // Owned CPU timing state extracted from StartUpSequence and
52 // UpdateSequenceClock. Consumes decoded records; no borrowed payload.
53 // This is NOT a tree executor or animation renderer: the caller must
54 // consume restart/stop events and manage children, commands, tweekers,
55 // transforms and render slots. Video receives an elapsed timeline; decoded
56 // media EOF remains the video backend's responsibility. Sound hardware
57 // clocks stay external; scrolling-world hibernation is driven explicitly
58 // by SequenceRuntime from render-slot visibility.
60 {
61 public:
62 static constexpr std::int32_t InfiniteEndTime = 1'234'567'890;
63
64 [[nodiscard]] static std::expected<SequenceClock, ClockError> start(
65 const data::LegacySequenceRecord& record,
66 ClockStartOptions options = {});
67
68 // Time units are those of the parent (top-level ArtLib clock: 60 Hz).
69 // No implicit wall clock. Backwards parent time requires the future
70 // tree rewind operation; errors preserve all current state.
71 [[nodiscard]] std::expected<ClockUpdate, ClockError> update(
72 std::int32_t parentClock, bool forceReevaluation = false);
73
74 // Video media time is supplied by decoded frames / consumed PCM. The
75 // separate parent elapsed clock keeps silent playback progressing.
76 [[nodiscard]] std::expected<void, ClockError> supplyVideoClock(
77 std::int32_t mediaClock, std::int32_t duration, bool ended);
78 // Source sound time comes from consumed audio, never the parent timer.
79 [[nodiscard]] std::expected<void, ClockError> supplySoundClock(
80 std::int32_t mediaClock);
82 { return videoClock_ ? elapsedParentClock_ : clock_; }
83 [[nodiscard]] std::expected<void, ClockError> setPaused(
84 bool paused, std::int32_t parentClock);
85 void hibernateScrollingWorld(std::int32_t parentClock) noexcept;
86
87 // GoBackwardsInTime: explicit seek uses modulo for loops, unlike a
88 // natural end. Caller destroys/recreates children and recursively
89 // seeks them to newTime-parentStartTime, even with keepFrames.
90 [[nodiscard]] ClockUpdate seek(std::int32_t newTime, std::int32_t parentClock);
91 [[nodiscard]] std::expected<void, ClockError> setEndingAction(std::uint8_t action);
92
93 [[nodiscard]] std::int32_t clock() const noexcept { return clock_; }
94 [[nodiscard]] std::int32_t endTime() const noexcept { return endTime_; }
95 [[nodiscard]] std::uint8_t timeMultiple() const noexcept { return timeMultiple_; }
96 [[nodiscard]] std::uint8_t endingAction() const noexcept { return endingAction_; }
97 [[nodiscard]] bool paused() const noexcept { return paused_; }
98 [[nodiscard]] bool stopped() const noexcept { return stopped_; }
99
100 private:
101 SequenceClock() = default;
102 std::optional<std::int32_t> lastParentClock_;
103 std::int32_t clock_{};
104 std::int32_t endTime_{};
105 std::uint8_t timeMultiple_{};
106 std::uint8_t endingAction_{};
107 bool dropFrames_{};
108 bool paused_{};
109 bool stopped_{};
110 struct VideoClockInput { std::int32_t clock{}, duration{}; bool ended{}; };
111 std::optional<VideoClockInput> pendingVideoClock_;
112 std::int32_t elapsedParentClock_{};
113 std::int32_t authoredEndTime_{InfiniteEndTime};
114 bool videoClock_{};
115 bool videoHeld_{};
116 bool soundClock_{};
117 std::optional<std::int32_t> pendingSoundClock_;
118 };
119}
unsigned index
std::string error
std::expected< void, ClockError > supplySoundClock(std::int32_t mediaClock)
std::int32_t endTime() const noexcept
std::int32_t clock() const noexcept
ClockUpdate seek(std::int32_t newTime, std::int32_t parentClock)
void hibernateScrollingWorld(std::int32_t parentClock) noexcept
std::expected< ClockUpdate, ClockError > update(std::int32_t parentClock, bool forceReevaluation=false)
static std::expected< SequenceClock, ClockError > start(const data::LegacySequenceRecord &record, ClockStartOptions options={})
std::uint8_t endingAction() const noexcept
std::expected< void, ClockError > setPaused(bool paused, std::int32_t parentClock)
std::int32_t elapsedParentClock() const noexcept
std::expected< void, ClockError > supplyVideoClock(std::int32_t mediaClock, std::int32_t duration, bool ended)
std::expected< void, ClockError > setEndingAction(std::uint8_t action)
static constexpr std::int32_t InfiniteEndTime
std::uint8_t timeMultiple() const noexcept
std::string_view clockErrorName(ClockError error) noexcept
std::optional< std::int32_t > endTimeOverride
std::optional< std::int32_t > parentClockAtBirth
std::optional< std::int32_t > previousClock