Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
OptionsTogglePlayback.cpp
Go to the documentation of this file.
2
3#include <array>
4#include <memory>
5#include <optional>
6#include <utility>
7#include <variant>
8#include <vector>
9
10namespace monopoly::optionsui
11{
12 namespace
13 {
14 [[nodiscard]] std::optional<std::size_t> supportedIndex(
15 OptionToggle toggle) noexcept
16 {
17 for (std::size_t index = 0; index < SupportedOptionToggles.size(); ++index)
18 if (SupportedOptionToggles[index] == toggle) return index;
19 return std::nullopt;
20 }
21
22 struct LoadedPair
23 {
24 std::shared_ptr<const sequence::SequenceProgram> on;
25 std::shared_ptr<const sequence::SequenceProgram> off;
26 };
27 }
28
29 std::int8_t TogglePlayback::shown(OptionToggle toggle) const noexcept
30 {
31 const auto index = supportedIndex(toggle);
32 return index ? shown_[*index] : static_cast<std::int8_t>(-1);
33 }
34
35 std::expected<void, std::string> TogglePlayback::sync(
36 const State& state,
39 {
40 const bool visible = desiredView == display::Screen2D::Options &&
41 state.active && state.currentScreen == Screen::Option &&
42 state.optionSnapshotLoaded;
43
44 std::array<std::int8_t, SupportedOptionToggles.size()> desired{};
45 desired.fill(-1);
46 if (visible)
47 {
48 for (std::size_t index = 0; index < SupportedOptionToggles.size(); ++index)
49 {
50 const auto toggle = SupportedOptionToggles[index];
51 desired[index] = state.optionOn[static_cast<std::size_t>(toggle)] ? 1 : 0;
52 }
53 }
54
55 if (desired == shown_) return {};
56 std::array<LoadedPair, SupportedOptionToggles.size()> programs{};
57 for (std::size_t index = 0; index < desired.size(); ++index)
58 {
59 if (desired[index] == shown_[index] || desired[index] < 0) continue;
60 const bool value = desired[index] != 0;
62 playback.resources(), toggleSequence(true, value));
63 if (!on) return std::unexpected(on.error().detail);
65 playback.resources(), toggleSequence(false, value));
66 if (!off) return std::unexpected(off.error().detail);
67 programs[index].on = std::move(*on);
68 programs[index].off = std::move(*off);
69 }
70
71 std::vector<sequence::SequenceCommand> commands;
72 for (std::size_t index = 0; index < desired.size(); ++index)
73 {
74 if (desired[index] == shown_[index]) continue;
75 const auto toggle = SupportedOptionToggles[index];
76 const auto priority = togglePriority(toggle);
77 if (shown_[index] >= 0)
78 {
79 const bool oldValue = shown_[index] != 0;
80 commands.push_back(sequence::StopSequenceCommand{
81 toggleSequence(true, oldValue), priority, false});
82 commands.push_back(sequence::StopSequenceCommand{
83 toggleSequence(false, oldValue), priority, false});
84 }
85 if (desired[index] < 0) continue;
86 const bool value = desired[index] != 0;
87 const auto onRect = optionToggleRect(toggle, true);
88 const auto offRect = optionToggleRect(toggle, false);
89
90 commands.push_back(sequence::StartSequenceCommand{
91 programs[index].on, priority, {}});
92 commands.push_back(sequence::makeMoveXY(
93 toggleSequence(true, value), priority, onRect.left, onRect.top));
96
97 commands.push_back(sequence::StartSequenceCommand{
98 programs[index].off, priority, {}});
99 commands.push_back(sequence::makeMoveXY(
100 toggleSequence(false, value), priority, offRect.left, offRect.top));
102 toggleSequence(false, value), priority, ToggleStayAtEnd, false});
103 }
104
105 if (commands.size() > sequence::SequenceCommandQueue::Capacity -
106 playback.commands().pendingCount())
107 return std::unexpected(
108 "sequence command queue cannot fit Options toggle transition");
109
110 for (auto& command : commands)
111 {
112 const auto queued = std::visit(
113 [&](auto value)
114 {
115 return playback.commands().enqueue(std::move(value));
116 },
117 std::move(command));
118 if (!queued)
119 return std::unexpected(
120 "validated Options toggle command rejected");
121 }
122
123 shown_ = desired;
124 return {};
125 }
126}
std::uint16_t priority
unsigned state
unsigned index
std::shared_ptr< const sequence::SequenceProgram > off
std::shared_ptr< const sequence::SequenceProgram > on
std::uint16_t value
Definition Timers.cpp:16
std::int8_t shown(OptionToggle toggle) const noexcept
std::expected< void, std::string > sync(const State &state, display::Screen2D desiredView, engine::SequencePlayback &playback)
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > load(const data::DataSource &source, data::DataId id, std::size_t offset=0, DescriptionLimits limits={})
Rect optionToggleRect(OptionToggle toggle, bool onSide) noexcept
Definition OptionsUI.cpp:77
constexpr std::uint16_t togglePriority(OptionToggle toggle) noexcept
constexpr data::DataId toggleSequence(bool onSide, bool value) noexcept
constexpr std::array< OptionToggle, 8 > SupportedOptionToggles
Definition OptionsUI.hpp:68
constexpr std::uint8_t ToggleStayAtEnd
MoveSequenceCommand makeMoveXY(data::DataId dataId, std::uint16_t priority, std::int32_t x, std::int32_t y) noexcept