yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_undo_actions.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_UNDO_ACTIONS_H_
2#define YAZE_APP_EDITOR_DUNGEON_UNDO_ACTIONS_H_
3
4#include <cstddef>
5#include <cstdint>
6#include <functional>
7#include <string>
8#include <utility>
9#include <vector>
10
11#include "absl/status/status.h"
12#include "absl/strings/str_format.h"
18
19namespace yaze {
20namespace editor {
21
32 public:
33 using RestoreFn = std::function<absl::Status(
34 int room_id, const std::vector<zelda3::RoomObject>&,
35 const std::vector<size_t>& selected_indices,
36 const std::vector<chest_data>& chests)>;
37
38 DungeonObjectsAction(int room_id, std::vector<zelda3::RoomObject> before,
39 std::vector<size_t> before_selection,
40 std::vector<zelda3::RoomObject> after,
41 std::vector<size_t> after_selection,
42 std::vector<chest_data> before_chests,
43 std::vector<chest_data> after_chests, RestoreFn restore)
44 : room_id_(room_id),
45 before_(std::move(before)),
46 before_selection_(std::move(before_selection)),
47 after_(std::move(after)),
48 after_selection_(std::move(after_selection)),
49 before_chests_(std::move(before_chests)),
50 after_chests_(std::move(after_chests)),
51 restore_(std::move(restore)) {}
52
53 absl::Status Undo() override {
54 if (!restore_) {
55 return absl::InternalError("DungeonObjectsAction: no restore callback");
56 }
58 }
59
60 absl::Status Redo() override {
61 if (!restore_) {
62 return absl::InternalError("DungeonObjectsAction: no restore callback");
63 }
65 }
66
67 std::string Description() const override {
68 return absl::StrFormat("Edit room %03X objects", room_id_);
69 }
70
71 size_t MemoryUsage() const override {
72 // Rough estimate: each RoomObject is ~40-80 bytes
73 return (before_.size() + after_.size()) * sizeof(zelda3::RoomObject) +
74 (before_selection_.size() + after_selection_.size()) *
75 sizeof(size_t) +
76 (before_chests_.size() + after_chests_.size()) * sizeof(chest_data);
77 }
78
79 bool CanMergeWith(const UndoAction& /*prev*/) const override {
80 // Object edits are already grouped per mutation (drag, delete, etc.)
81 // so merging is not needed.
82 return false;
83 }
84
85 private:
87 std::vector<zelda3::RoomObject> before_;
88 std::vector<size_t> before_selection_;
89 std::vector<zelda3::RoomObject> after_;
90 std::vector<size_t> after_selection_;
91 std::vector<chest_data> before_chests_, after_chests_;
93};
94
95// Only the vector named by domain is populated. Keeping domains independent
96// prevents a door undo from reverting a later sprite or item edit.
98 std::vector<zelda3::Room::Door> doors;
99 std::vector<DungeonSpriteSnapshot> sprites;
100 std::vector<zelda3::PotItem> items;
101 std::vector<SelectedEntity> entities;
102 std::vector<size_t> objects;
103};
104
106 public:
107 using RestoreFn = std::function<absl::Status(int, MutationDomain,
108 const DungeonEntitySnapshot&)>;
111 DungeonEntitySnapshot after, RestoreFn restore)
112 : room_id_(room_id),
113 domain_(domain),
114 before_(std::move(before)),
115 after_(std::move(after)),
116 restore_(std::move(restore)) {}
117 absl::Status Undo() override {
119 : absl::InternalError(
120 "DungeonEntitiesAction: no restore callback");
121 }
122 absl::Status Redo() override {
124 : absl::InternalError(
125 "DungeonEntitiesAction: no restore callback");
126 }
127 std::string Description() const override {
128 const char* label = domain_ == MutationDomain::kDoors ? "doors"
129 : domain_ == MutationDomain::kSprites ? "sprites"
130 : "pot items";
131 return absl::StrFormat("Edit room %03X %s", room_id_, label);
132 }
133 size_t MemoryUsage() const override {
134 auto bytes = [](const DungeonEntitySnapshot& state) {
135 return state.doors.size() * sizeof(zelda3::Room::Door) +
136 state.sprites.size() * sizeof(DungeonSpriteSnapshot) +
137 state.items.size() * sizeof(zelda3::PotItem) +
138 state.entities.size() * sizeof(SelectedEntity) +
139 state.objects.size() * sizeof(size_t);
140 };
141 return bytes(before_) + bytes(after_);
142 }
143 bool CanMergeWith(const UndoAction&) const override { return false; }
144
145 private:
150};
151
153 uint8_t sram_bit_mask = 0; // Bit in $7EF411 (0x00 = Auto/unspecified)
154 std::vector<uint16_t> offsets; // Each offset = Y*64 + X (0..4095)
155};
156
158 public:
159 using RestoreFn =
160 std::function<void(int room_id, const zelda3::CustomCollisionMap&)>;
161
164 RestoreFn restore)
165 : room_id_(room_id),
166 before_(std::move(before)),
167 after_(std::move(after)),
168 restore_(std::move(restore)) {}
169
170 absl::Status Undo() override {
171 if (!restore_) {
172 return absl::InternalError(
173 "DungeonCustomCollisionAction: no restore callback");
174 }
176 return absl::OkStatus();
177 }
178
179 absl::Status Redo() override {
180 if (!restore_) {
181 return absl::InternalError(
182 "DungeonCustomCollisionAction: no restore callback");
183 }
185 return absl::OkStatus();
186 }
187
188 std::string Description() const override {
189 return absl::StrFormat("Edit room %03X custom collision", room_id_);
190 }
191
192 size_t MemoryUsage() const override {
193 return sizeof(before_) + sizeof(after_);
194 }
195
196 bool CanMergeWith(const UndoAction& /*prev*/) const override { return false; }
197
198 private:
203};
204
209
211 public:
212 using RestoreFn = std::function<absl::Status(
213 const std::vector<DungeonCustomCollisionSnapshot>&)>;
214
216 std::vector<DungeonCustomCollisionSnapshot> before,
217 std::vector<DungeonCustomCollisionSnapshot> after, RestoreFn restore)
218 : before_(std::move(before)),
219 after_(std::move(after)),
220 restore_(std::move(restore)) {}
221
222 absl::Status Undo() override {
223 if (!restore_) {
224 return absl::InternalError(
225 "DungeonCustomCollisionBatchAction: no restore callback");
226 }
227 return restore_(before_);
228 }
229
230 absl::Status Redo() override {
231 if (!restore_) {
232 return absl::InternalError(
233 "DungeonCustomCollisionBatchAction: no restore callback");
234 }
235 return restore_(after_);
236 }
237
238 std::string Description() const override {
239 return absl::StrFormat("Generate minecart collision for %d rooms",
240 static_cast<int>(after_.size()));
241 }
242
243 size_t MemoryUsage() const override {
244 return (before_.size() + after_.size()) *
246 }
247
248 bool CanMergeWith(const UndoAction& /*prev*/) const override { return false; }
249
250 private:
251 std::vector<DungeonCustomCollisionSnapshot> before_;
252 std::vector<DungeonCustomCollisionSnapshot> after_;
254};
255
257 public:
258 using RestoreFn = std::function<void(int room_id, const WaterFillSnapshot&)>;
259
261 WaterFillSnapshot after, RestoreFn restore)
262 : room_id_(room_id),
263 before_(std::move(before)),
264 after_(std::move(after)),
265 restore_(std::move(restore)) {}
266
267 absl::Status Undo() override {
268 if (!restore_) {
269 return absl::InternalError("DungeonWaterFillAction: no restore callback");
270 }
272 return absl::OkStatus();
273 }
274
275 absl::Status Redo() override {
276 if (!restore_) {
277 return absl::InternalError("DungeonWaterFillAction: no restore callback");
278 }
280 return absl::OkStatus();
281 }
282
283 std::string Description() const override {
284 return absl::StrFormat("Edit room %03X water fill", room_id_);
285 }
286
287 size_t MemoryUsage() const override {
288 return before_.offsets.size() * sizeof(uint16_t) +
289 after_.offsets.size() * sizeof(uint16_t) + sizeof(before_) +
290 sizeof(after_);
291 }
292
293 bool CanMergeWith(const UndoAction& /*prev*/) const override { return false; }
294
295 private:
300};
301
302} // namespace editor
303} // namespace yaze
304
305#endif // YAZE_APP_EDITOR_DUNGEON_UNDO_ACTIONS_H_
size_t MemoryUsage() const override
Approximate memory footprint for budget enforcement.
std::string Description() const override
Human-readable description (e.g., "Paint 12 tiles on map 5")
std::function< void(int room_id, const zelda3::CustomCollisionMap &)> RestoreFn
DungeonCustomCollisionAction(int room_id, zelda3::CustomCollisionMap before, zelda3::CustomCollisionMap after, RestoreFn restore)
bool CanMergeWith(const UndoAction &) const override
size_t MemoryUsage() const override
Approximate memory footprint for budget enforcement.
std::string Description() const override
Human-readable description (e.g., "Paint 12 tiles on map 5")
std::vector< DungeonCustomCollisionSnapshot > after_
bool CanMergeWith(const UndoAction &) const override
std::vector< DungeonCustomCollisionSnapshot > before_
std::function< absl::Status( const std::vector< DungeonCustomCollisionSnapshot > &)> RestoreFn
DungeonCustomCollisionBatchAction(std::vector< DungeonCustomCollisionSnapshot > before, std::vector< DungeonCustomCollisionSnapshot > after, RestoreFn restore)
std::string Description() const override
Human-readable description (e.g., "Paint 12 tiles on map 5")
std::function< absl::Status(int, MutationDomain, const DungeonEntitySnapshot &)> RestoreFn
bool CanMergeWith(const UndoAction &) const override
DungeonEntitiesAction(int room_id, MutationDomain domain, DungeonEntitySnapshot before, DungeonEntitySnapshot after, RestoreFn restore)
size_t MemoryUsage() const override
Approximate memory footprint for budget enforcement.
Undoable action for dungeon room object edits.
std::vector< zelda3::RoomObject > after_
std::vector< chest_data > before_chests_
std::vector< zelda3::RoomObject > before_
std::function< absl::Status( int room_id, const std::vector< zelda3::RoomObject > &, const std::vector< size_t > &selected_indices, const std::vector< chest_data > &chests)> RestoreFn
bool CanMergeWith(const UndoAction &) const override
size_t MemoryUsage() const override
Approximate memory footprint for budget enforcement.
DungeonObjectsAction(int room_id, std::vector< zelda3::RoomObject > before, std::vector< size_t > before_selection, std::vector< zelda3::RoomObject > after, std::vector< size_t > after_selection, std::vector< chest_data > before_chests, std::vector< chest_data > after_chests, RestoreFn restore)
std::string Description() const override
Human-readable description (e.g., "Paint 12 tiles on map 5")
std::vector< chest_data > after_chests_
std::string Description() const override
Human-readable description (e.g., "Paint 12 tiles on map 5")
std::function< void(int room_id, const WaterFillSnapshot &)> RestoreFn
bool CanMergeWith(const UndoAction &) const override
size_t MemoryUsage() const override
Approximate memory footprint for budget enforcement.
DungeonWaterFillAction(int room_id, WaterFillSnapshot before, WaterFillSnapshot after, RestoreFn restore)
Abstract base for all undoable actions (Command pattern)
Definition undo_action.h:20
MutationDomain
Domain/type of mutation for undo + invalidation routing.
Legacy chest data structure.
Definition zelda.h:438
std::vector< DungeonSpriteSnapshot > sprites
std::vector< zelda3::PotItem > items
std::vector< SelectedEntity > entities
std::vector< zelda3::Room::Door > doors
Represents a selected entity in the dungeon editor.
Represents a door in a dungeon room.
Definition room.h:339