Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
StatsPlayback.cpp
Go to the documentation of this file.
1#include "StatsPlayback.hpp"
2
3#include <memory>
4#include <utility>
5#include <variant>
6#include <vector>
7
8namespace monopoly::statsui
9{
10 namespace
11 {
12 [[nodiscard]] constexpr std::size_t visualColumn(ButtonVisual visual) noexcept
13 {
14 return visual == ButtonVisual::Idle ? 0U
15 : visual == ButtonVisual::Return ? 1U : 2U;
16 }
17
18 [[nodiscard]] constexpr std::uint16_t categoryPriority(
19 std::size_t index, ButtonVisual visual) noexcept
20 {
21 return visual == ButtonVisual::Press
24 }
25
26 [[nodiscard]] constexpr std::uint16_t sortPriority(
27 std::size_t index, ButtonVisual visual) noexcept
28 {
29 return visual == ButtonVisual::Press
32 }
33 }
34
35 ButtonVisual Playback::categoryVisual(std::size_t index) const noexcept
36 {
37 return index < categoryVisual_.size() ? categoryVisual_[index]
39 }
40
41 ButtonVisual Playback::sortVisual(std::size_t index) const noexcept
42 {
43 return index < sortVisual_.size() ? sortVisual_[index]
45 }
46
48 {
49 published_.fill(std::nullopt);
50 categoryVisual_.fill(ButtonVisual::Off);
51 sortVisual_.fill(ButtonVisual::Off);
52 visible_ = false;
53 screen_ = Screen::Player;
54 sort_ = 0;
55 }
56
57 std::expected<void, std::string> Playback::sync(
60 {
62 const auto desiredScreen = state.screen;
63 const auto desiredSort = static_cast<std::uint8_t>(state.activeSort < 4
64 ? state.activeSort : 0);
65
66 auto nextCategory = categoryVisual_;
67 auto nextSort = sortVisual_;
68 if (!desiredVisible)
69 {
72 }
73 else if (!visible_)
74 {
77 nextCategory[static_cast<std::size_t>(desiredScreen)] = ButtonVisual::Press;
79 }
80 else if (desiredScreen != screen_)
81 {
82 nextCategory[static_cast<std::size_t>(screen_)] = ButtonVisual::Return;
83 nextCategory[static_cast<std::size_t>(desiredScreen)] = ButtonVisual::Press;
86 }
87 else if (desiredSort != sort_)
88 {
91 }
92
93 std::array<std::optional<Published>, SlotCount> desired{};
95 {
96 desired[0] = Published{
99 {
100 desired[1] = Published{
102 5, 229, true, false};
103 }
104 else if (desiredScreen == Screen::Bank)
105 {
106 desired[1] = Published{
109 }
110
111 desired[2] = Published{
113 desired[3] = Published{
115 const auto screenIndex = static_cast<std::size_t>(desiredScreen);
116 desired[4] = Published{
118 desired[5] = Published{
120
121 for (std::size_t index = 0; index < nextCategory.size(); ++index)
122 {
123 const auto visual = nextCategory[index];
124 if (visual == ButtonVisual::Off) continue;
125 desired[6 + index] = Published{
127 categoryPriority(index, visual), 0, 0, false,
128 visual == ButtonVisual::Press || visual == ButtonVisual::Return};
129 }
130 for (std::size_t index = 0; index < nextSort.size(); ++index)
131 {
132 const auto visual = nextSort[index];
133 if (visual == ButtonVisual::Off) continue;
134 desired[9 + index] = Published{
136 sortPriority(index, visual), 0, 0, false,
137 visual == ButtonVisual::Press || visual == ButtonVisual::Return};
138 }
139 }
140
141 std::array<std::shared_ptr<const sequence::SequenceProgram>, SlotCount> programs{};
142 std::size_t commandCount{};
143 for (std::size_t slot = 0; slot < SlotCount; ++slot)
144 {
145 if (published_[slot] == desired[slot]) continue;
146 if (published_[slot]) ++commandCount;
147 if (desired[slot])
148 {
150 playback.resources(), desired[slot]->id);
151 if (!loaded)
152 return std::unexpected(
153 "UDStats sequence " + std::to_string(desired[slot]->id) +
154 ": " + loaded.error().detail);
155 programs[slot] = std::move(*loaded);
156 ++commandCount;
157 if (desired[slot]->moved) ++commandCount;
158 if (desired[slot]->stay) ++commandCount;
159 }
160 }
161
163 playback.commands().pendingCount())
164 {
165 return std::unexpected(
166 "sequence command queue cannot fit UDStats playback transition");
167 }
168
169 std::vector<sequence::SequenceCommand> commands;
170 commands.reserve(commandCount);
171 for (std::size_t slot = 0; slot < SlotCount; ++slot)
172 {
173 if (published_[slot] == desired[slot]) continue;
174 if (published_[slot])
175 {
176 commands.push_back(sequence::StopSequenceCommand{
177 published_[slot]->id, published_[slot]->priority, false});
178 }
179 if (!desired[slot]) continue;
180
181 const auto& spec = *desired[slot];
182 commands.push_back(sequence::StartSequenceCommand{
183 programs[slot], spec.priority, {}});
184 if (spec.moved)
185 {
186 commands.push_back(sequence::makeMoveXY(
187 spec.id, spec.priority, spec.x, spec.y));
188 }
189 if (spec.stay)
190 {
192 spec.id, spec.priority, StatusStayAtEnd, false});
193 }
194 }
195
196 for (auto& command : commands)
197 {
198 const auto queued = std::visit(
199 [&](auto value)
200 {
201 return playback.commands().enqueue(std::move(value));
202 }, std::move(command));
203 if (!queued)
204 return std::unexpected("validated UDStats playback command rejected");
205 }
206
207 published_ = desired;
208 categoryVisual_ = nextCategory;
209 sortVisual_ = nextSort;
210 visible_ = desiredVisible;
211 screen_ = desiredScreen;
212 sort_ = desiredSort;
213 return {};
214 }
215}
PlayerNumber slot
unsigned state
unsigned index
std::uint16_t value
Definition Timers.cpp:16
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > load(const data::DataSource &source, data::DataId id, std::size_t offset=0, DescriptionLimits limits={})
ButtonVisual sortVisual(std::size_t index) const noexcept
ButtonVisual categoryVisual(std::size_t index) const noexcept
std::expected< void, std::string > sync(const State &state, display::Screen2D desiredView, engine::SequencePlayback &playback)
MoveSequenceCommand makeMoveXY(data::DataId dataId, std::uint16_t priority, std::int32_t x, std::int32_t y) noexcept
constexpr std::uint8_t StatusStayAtEnd
constexpr std::array< std::uint16_t, 3 > CategoryPressPriorities
constexpr std::array< std::array< std::array< data::DataTag, 3 >, 4 >, 3 > SortButtonTags
constexpr data::DataTag StatusBackgroundTag
constexpr std::array< data::DataTag, 4 > BankBackgroundTags
constexpr std::uint16_t DeedBackgroundPriority
constexpr std::uint16_t StatusBarPriority
constexpr std::uint16_t StatusBarOverlayPriority
constexpr std::array< std::uint16_t, 3 > CategoryIdlePriorities
constexpr data::DataId mainSequence(data::DataTag tag) noexcept
constexpr std::uint16_t StatusBackgroundPriority
constexpr std::array< std::array< data::DataTag, 2 >, 3 > SortBarTags
constexpr std::array< std::array< data::DataTag, 3 >, 3 > CategoryButtonTags
constexpr data::DataTag DeedBackgroundTag
constexpr std::array< std::uint16_t, 4 > SortPressPriorities
constexpr std::array< std::uint16_t, 4 > SortIdlePriorities
constexpr std::uint16_t BankBackgroundPriority
constexpr std::array< data::DataTag, 2 > CategoryBarTags
constexpr data::DataId languageSequence(data::DataTag tag) noexcept