Monopoly — Portage moderne 0.1.0
Portage moderne C/C++23 du Monopoly de 1999
Loading...
Searching...
No Matches
StatsCalculatorDeedPickerPlayback.cpp
Go to the documentation of this file.
4
5#include <algorithm>
6
7#include <memory>
8#include <utility>
9
10namespace monopoly::statsui
11{
12 namespace
13 {
14 [[nodiscard]] constexpr data::DataId deedId(int property) noexcept
15 {
17 static_cast<data::DataTag>(
18 PlayerDeedNormalBaseTag + property));
19 }
20
21 [[nodiscard]] data::DataId cornerDeedId(int square, int city) noexcept
22 {
23 const int property = ibar::layout::propertyIndex(square);
24 if (property < 0) return data::EmptyDataId;
26 static_cast<data::DataTag>(DeedFloaterCardBaseTag + property +
27 DeedFloaterCardsPerCity * std::max(city, 0)));
28 }
29
30 [[nodiscard]] std::vector<CalculatorDeedPickerPlayback::Published>
31 desiredPicker(const CalculatorUIState& ui, int city,
32 display::Screen2D desiredView, engine::SequencePlayback& playback)
33 {
34 std::vector<CalculatorDeedPickerPlayback::Published> result;
36 ui.picker != CalculatorPicker::Deed)
37 return result;
38
39 result.reserve(29);
40 for (int square = 0;
42 {
43 const int property = ibar::layout::propertyIndex(square);
44 if (property < 0) continue;
45
46 result.push_back({
52 }
53 if (ui.hoveredDeed)
54 {
55 const auto id = playback.deedDataId(*ui.hoveredDeed, true,
56 cornerDeedId(*ui.hoveredDeed, city));
57 if (id != data::EmptyDataId)
58 result.push_back({id, CalculatorDeedPickerPriority, 600, -2});
59 }
60 return result;
61 }
62 }
63
64 std::expected<void, std::string> CalculatorDeedPickerPlayback::sync(
65 const CalculatorUIState& ui, int city,
68 {
69 const bool desiredBackground =
72 auto desired = desiredPicker(ui, city, desiredView, playback);
73 if (desired == current_ && desiredBackground == backgroundVisible_)
74 return {};
75
76 std::vector<Published> removed;
77 std::vector<Published> added;
78 for (const auto& object : current_)
79 if (std::find(desired.begin(), desired.end(), object) == desired.end())
80 removed.push_back(object);
81 for (const auto& object : desired)
82 if (std::find(current_.begin(), current_.end(), object) == current_.end())
83 added.push_back(object);
84
85 std::vector<std::shared_ptr<const sequence::SequenceProgram>> programs;
86 programs.reserve(added.size());
87 for (const auto& object : added)
88 {
89 auto loaded = playback.loadProgram(object.id);
90 if (!loaded)
91 return std::unexpected(
92 "UDStats calculator deed picker failed: " + loaded.error());
93 programs.push_back(std::move(*loaded));
94 }
95
96 const std::size_t backgroundCommands =
97 desiredBackground == backgroundVisible_ ? 0U : 1U;
98 const std::size_t required =
99 removed.size() + added.size() + backgroundCommands;
101 playback.commands().pendingCount())
102 {
103 return std::unexpected(
104 "sequence command queue cannot fit calculator deed picker transition");
105 }
106
107 std::shared_ptr<const sequence::SequenceProgram> backgroundProgram;
108 if (desiredBackground && !backgroundVisible_)
109 {
110 if (!background_)
111 {
112 const auto created = playback.runtimeBitmaps().create(
115 false);
116 if (!created)
117 return std::unexpected(created.error());
118 background_ = *created;
119 }
120
122 *background_, data::LegacyDataType::Native);
123 if (!raw)
124 return std::unexpected(raw.error().detail);
126
127 if (!playback.commands().enqueue(
129 backgroundProgram,
130 // Retail composites the miniatures into this background.
131 // Separate modern roots must paint above it; equal-priority
132 // roots insert newest first and would leave the black fill last.
133 CalculatorDeedPickerPriority - 1,
134 {},
138 return std::unexpected(
139 "validated calculator deed picker background start rejected");
140 }
141
142 for (const auto& object : removed)
143 {
144 if (!playback.commands().enqueue(
146 object.id, object.priority, false}))
147 return std::unexpected(
148 "validated calculator deed picker stop rejected");
149 }
150 for (std::size_t index = 0; index < added.size(); ++index)
151 {
152 const auto& object = added[index];
153 if (!playback.commands().enqueue(
155 programs[index], object.priority, {},
156 sequence::moveXYTransform(object.x, object.y)}))
157 return std::unexpected(
158 "validated calculator deed picker start rejected");
159 }
160
161 if (!desiredBackground && backgroundVisible_)
162 {
163 if (!background_ ||
164 !playback.commands().enqueue(
165 sequence::StopSequenceCommand{
166 *background_, CalculatorDeedPickerPriority - 1, false}))
167 return std::unexpected(
168 "validated calculator deed picker background stop rejected");
169 }
170
171 current_ = std::move(desired);
172 backgroundVisible_ = desiredBackground;
173 return {};
174 }
175}
data::DataId id
unsigned index
static std::expected< std::shared_ptr< const SequenceProgram >, RuntimeError > rawBitmap(data::DataId id, data::LegacyDataType sourceType, DescriptionLimits limits={})
std::expected< void, std::string > sync(const CalculatorUIState &ui, int city, display::Screen2D desiredView, engine::SequencePlayback &playback)
std::uint32_t DataId
Definition DataBanks.hpp:10
constexpr DataId EmptyDataId
Definition DataBanks.hpp:13
std::uint16_t DataTag
Definition DataBanks.hpp:11
constexpr DataId packDataId(std::uint16_t group, DataTag tag) noexcept
Definition DataBanks.hpp:39
int propertyIndex(int square) noexcept
constexpr std::size_t SquareCount
Definition RuleTypes.hpp:24
SequenceTransform moveXYTransform(std::int32_t x, std::int32_t y) noexcept
constexpr std::uint16_t CalculatorDeedPickerPriority
constexpr data::DataTag PlayerDeedNormalBaseTag
constexpr data::DataTag DeedFloaterCardBaseTag