Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
TradeCashDialogPlayback.cpp
Go to the documentation of this file.
2
3#include <array>
4#include <memory>
5#include <utility>
6#include <variant>
7#include <vector>
8
9namespace monopoly::tradeui
10{
11 namespace
12 {
13 inline constexpr std::size_t CashDialogSequenceCount = 4;
14 inline constexpr std::uint8_t EndingActionStop = 1;
15
16 [[nodiscard]] std::array<data::DataId, CashDialogSequenceCount>
18 {
19 return {
24 }
25
26 [[nodiscard]] std::uint16_t cashDialogPriority(
27 std::size_t index) noexcept
28 {
30 }
31
32 [[nodiscard]] std::int32_t cashDialogX(
33 std::size_t index,
34 std::uint8_t side) noexcept
35 {
36 return index == 0 ? TradeCashDialogX[side] : TradeCashButtonX[side];
37 }
38
39 [[nodiscard]] std::int32_t cashDialogY(
40 std::size_t index,
41 std::uint8_t side) noexcept
42 {
43 return index == 0 ? TradeCashDialogY[side] : TradeCashButtonY[side];
44 }
45 }
46
47 std::expected<void, std::string> CashDialogPlayback::sync(
48 State& state,
50 std::uint64_t nowTick,
52 {
54 if (tradeView && (state.cashDialogVisible || state.cashDialogClosing) &&
55 state.cashDialogSide >= 2)
56 {
57 return std::unexpected("Trade cash-dialog side is out of range");
58 }
59
60 const bool feedbackCompleted =
61 feedback_ != data::EmptyDataId &&
62 nowTick > feedbackStartTick_ &&
63 playback.runtime().matching(
64 feedback_, TradeCashPressedPriority).empty();
67 : feedback_;
68
69 bool closingAfter = state.cashDialogClosing;
70 if (!tradeView)
71 closingAfter = false;
72 else if (feedbackCompleted &&
73 state.cashDialogFeedback == CashDialogFeedback::None)
74 closingAfter = false;
75
76 const bool desiredVisible = tradeView &&
77 (state.cashDialogVisible || closingAfter);
78 const auto desiredSide = desiredVisible
79 ? state.cashDialogSide
80 : side_;
81
82 const auto requestedFeedback = tradeView
83 ? state.cashDialogFeedback
85 const auto requestedFeedbackId =
89 {
90 return std::unexpected("Trade cash-dialog feedback is out of range");
91 }
92
93 const auto ids = cashDialogSequences();
94 std::array<std::shared_ptr<const sequence::SequenceProgram>,
96 if (desiredVisible && !visible_)
97 {
98 for (std::size_t index = 0; index < ids.size(); ++index)
99 {
101 playback.resources(), ids[index]);
102 if (!loaded)
103 return std::unexpected(loaded.error().detail);
104 programs[index] = std::move(*loaded);
105 }
106 }
107
108 std::shared_ptr<const sequence::SequenceProgram> feedbackProgram;
110 {
112 playback.resources(), requestedFeedbackId);
113 if (!loaded)
114 return std::unexpected(loaded.error().detail);
115 feedbackProgram = std::move(*loaded);
116 }
117
118 std::vector<sequence::SequenceCommand> commands;
119 if (visible_ && !desiredVisible)
120 {
121 for (std::size_t index = 0; index < ids.size(); ++index)
122 commands.push_back(sequence::StopSequenceCommand{
123 ids[index], cashDialogPriority(index), false});
124 }
125 else if (!visible_ && desiredVisible)
126 {
127 for (std::size_t index = 0; index < ids.size(); ++index)
128 {
129 commands.push_back(sequence::StartSequenceCommand{
131 commands.push_back(sequence::makeMoveXY(
135 }
136 }
137 else if (visible_ && desiredVisible && side_ != desiredSide)
138 {
139 for (std::size_t index = 0; index < ids.size(); ++index)
140 {
141 commands.push_back(sequence::makeMoveXY(
145 }
146 }
147
149 {
151 {
152 commands.push_back(sequence::StopSequenceCommand{
154 }
155 commands.push_back(sequence::StartSequenceCommand{
157 commands.push_back(sequence::makeMoveXY(
159 TradeCashButtonX[state.cashDialogSide],
160 TradeCashButtonY[state.cashDialogSide]));
163 EndingActionStop, false});
164 }
165
166 if (commands.size() > sequence::SequenceCommandQueue::Capacity -
167 playback.commands().pendingCount())
168 {
169 return std::unexpected(
170 "sequence command queue cannot fit Trade cash-dialog transition");
171 }
172
173 for (auto& command : commands)
174 {
175 const auto queued = std::visit(
176 [&](auto value)
177 {
178 return playback.commands().enqueue(std::move(value));
179 },
180 std::move(command));
181 if (!queued)
182 {
183 return std::unexpected(
184 "validated Trade cash-dialog command rejected");
185 }
186 }
187
188 visible_ = desiredVisible;
189 if (desiredVisible)
190 side_ = desiredSide;
191
192 if (!tradeView)
193 {
194 state.cashDialogVisible = false;
195 state.cashDialogClosing = false;
196 state.cashDialogFeedback = CashDialogFeedback::None;
198 {
199 feedback_ = data::EmptyDataId;
200 feedbackStartTick_ = 0;
201 }
202 }
203 else
204 {
205 state.cashDialogClosing = closingAfter;
207 {
208 feedback_ = requestedFeedbackId;
209 feedbackStartTick_ = nowTick;
210 state.cashDialogFeedback = CashDialogFeedback::None;
211 }
212 else if (feedbackCompleted)
213 {
214 feedback_ = data::EmptyDataId;
215 feedbackStartTick_ = 0;
216 }
217 }
218
219 return {};
220 }
221}
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={})
std::expected< void, std::string > sync(State &state, display::Screen2D desiredView, std::uint64_t nowTick, engine::SequencePlayback &playback)
constexpr DataId EmptyDataId
Definition DataBanks.hpp:13
MoveSequenceCommand makeMoveXY(data::DataId dataId, std::uint16_t priority, std::int32_t x, std::int32_t y) noexcept
constexpr std::array< std::int32_t, 2 > TradeCashButtonX
constexpr std::array< std::int32_t, 2 > TradeCashDialogX
constexpr std::array< std::int32_t, 2 > TradeCashDialogY
constexpr data::DataId tradeCashPressedSequence(CashDialogFeedback feedback) noexcept
constexpr std::uint16_t TradeCashDialogPriority
constexpr std::array< std::int32_t, 2 > TradeCashButtonY
constexpr data::DataId tradeCashIdleSequence(std::size_t index) noexcept
constexpr std::uint16_t TradeCashButtonPriority
constexpr std::uint16_t TradeCashPressedPriority
constexpr data::DataId tradeCashDialogSequence() noexcept