yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_editor_v2.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
2#define YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
3
4#include <array>
5#include <cstdint>
6#include <deque>
7#include <functional>
8#include <future>
9#include <memory>
10#include <optional>
11#include <string>
12#include <unordered_map>
13#include <utility>
14#include <vector>
15
16#include "absl/status/status.h"
17#include "absl/status/statusor.h"
18#include "absl/strings/str_format.h"
19#include "app/editor/editor.h"
29#include "dungeon_room_loader.h"
31#include "dungeon_room_store.h"
33#include "imgui/imgui.h"
35#include "rom/rom.h"
37#include "util/lru_cache.h"
38#include "util/stop_token.h"
41#include "zelda3/dungeon/room.h"
46#include "zelda3/game_data.h"
47
48namespace yaze {
49namespace editor {
50
51class CustomCollisionPanel;
52class DungeonEntrancesPanel;
53class DungeonEditorPaletteRefreshTestPeer;
54class DungeonEditorV2MinecartTrackTestPeer;
55class DungeonEditorV2ObjectTileEditorTestPeer;
56class DungeonEditorV2EntranceCameraTestPeer;
57class DungeonEditorEntrancePropertiesTestPeer;
58class DungeonEditorV2RegularEntranceTestPeer;
59class DungeonEditorV2ReloadTestPeer;
60class DungeonEditorV2ShortcutTestPeer;
61class DungeonEditorV2SpawnPointTestPeer;
62class DungeonEditorV2SpawnRejectionTestPeer;
63class MinecartTrackEditorPanel;
64struct MinecartCollisionStamp;
65struct MinecartTrack;
66class ObjectCoveragePanel;
67class ObjectTileEditorPanel;
68class OverlayManagerPanel;
69class PaletteEditorContent;
70class RoomTagEditorPanel;
71class RoomMatrixContent;
72class WaterFillPanel;
73
75 kUp,
76 kDown,
77 kLeft,
78 kRight,
79};
80
121class DungeonEditorV2 : public Editor {
122 public:
123 explicit DungeonEditorV2(Rom* rom = nullptr);
124
125 ~DungeonEditorV2() override;
126 // Visit loaded models using the dungeon canvas's entrance resolver.
128 const std::function<void(int, zelda3::Room&, const std::string&, bool,
129 int)>& visitor);
130 void PrepareForSessionTeardown() override;
131
134 dependencies_.game_data = game_data; // Also set base class dependency
138 }
140 dungeon_editor_system_->SetGameData(game_data);
141 }
143 // Note: Canvas viewer game data is set lazily in GetViewerForRoom
144 // but we should update existing viewers
145 room_viewers_.ForEach(
146 [game_data](int, std::unique_ptr<DungeonCanvasViewer>& viewer) {
147 if (viewer)
148 viewer->SetGameData(game_data);
149 });
150 if (workbench_viewer_) {
151 workbench_viewer_->SetGameData(game_data);
152 }
155 }
156 }
157
158 // Editor interface
159 void SetDependencies(const EditorDependencies& deps) override;
160 void Initialize() override;
161 absl::Status Load() override;
162 absl::Status Update() override;
163 absl::Status Undo() override;
164 absl::Status Redo() override;
165 absl::Status Cut() override;
166 absl::Status Copy() override;
167 absl::Status Paste() override;
168 absl::Status Find() override { return absl::UnimplementedError("Find"); }
169 // Undo() first finalizes pending gestures into history, so any pending
170 // snapshot makes Undo available even while undo_manager_ is still empty.
171 bool CanUndo() const override {
173 }
174 absl::Status Save() override;
175 // Reject excluded model edits before any writer runs. Apply Room narrows
176 // room-local streams; shared tables still include all pending room records.
177 absl::Status ValidateSaveScope(int only_room = -1,
178 bool room_data_only = false) const;
179 absl::Status BeginSaveTransaction() override;
180 void RollbackSaveTransaction() override;
181 void CommitSaveTransaction() override;
182 void ContributeStatus(StatusBar* status_bar) override;
184 absl::Status SaveRoom(int room_id);
185 // Discrete room property edits share the dungeon undo history in both views.
186 absl::StatusOr<DungeonConnectionPlan> PreviewDoorConnection(
187 const DungeonConnectionRequest& request);
188 absl::Status ApplyDoorConnection(const DungeonConnectionPlan& plan);
189 absl::StatusOr<std::string> ExportRoomDocument(int room_id);
190 absl::StatusOr<DungeonRoomTransferPlan> PreviewRoomTransfer(
191 int target_room_id, int source_room_id, const std::string& json,
192 const DungeonRoomTransferOptions& options);
193 absl::Status ApplyRoomTransfer(const DungeonRoomTransferPlan& plan);
194 absl::Status EditRoomMetadata(int room_id, const RoomMetadataEdit& edit);
195 // Shared roomset assignment (background slots 3-6); zero inherits main.
196 absl::Status EditRoomGraphicsSheet(int room_id, int slot, int sheet_id);
197 // The owning EditorSet supplies an existing model only; usage queries must
198 // not create another editor or read another ROM session's window context.
200 std::function<const zelda3::Overworld*()> provider) {
201 room_graphics_overworld_provider_ = std::move(provider);
202 }
203 absl::StatusOr<zelda3::RoomsetUsageReport> GetRoomGraphicsUsage(
204 int roomset) const;
205 absl::Status EditRoomMetadataBatch(
206 const std::vector<RoomMetadataRequest>& requests);
207 absl::Status EditChest(int room_id, size_t index, uint8_t item_id,
208 bool big_chest);
209 absl::Status DeleteChest(int room_id, size_t index);
210 int LoadedRoomCount() const;
211 // Room-specific pending state used by room counts and room-level UI.
212 int PendingRoomCount() const;
213 bool HasPendingRoomChanges() const;
214 // All dungeon save domains plus unapplied editor-local work.
215 bool HasPendingDungeonChanges() const;
216 // Track source must be published separately from the ROM save domains.
219 absl::Status PrepareProjectSave();
220 bool CurrentRoomHasPendingChanges() const;
221 int TotalRoomCount() const { return static_cast<int>(rooms_.size()); }
222
223 // Collect PC write ranges for all dirty/loaded rooms (for write conflict
224 // analysis). Returns pairs of (start_pc, end_pc) covering header and object
225 // regions that would be written during save.
226 std::vector<std::pair<uint32_t, uint32_t>> CollectWriteRanges() const;
227
228 // ROM management
229 void SetRom(Rom* rom) {
230 const bool rom_changed = rom_ != rom;
231 rom_ = rom;
235
236 // Propagate ROM to all rooms
238 // Reset viewers and copied room data on ROM change.
239 if (rom_changed) {
244 rooms_.Clear();
245 room_viewers_.Clear();
246 workbench_viewer_.reset();
249 }
250 }
251 // Reloads same-address ROM state in place so rooms, viewers, and workspace
252 // panel bindings retain stable addresses.
253 absl::Status RefreshRomBackedState();
254 Rom* rom() const { return rom_; }
255
256 // Room management
257 void add_room(int room_id);
258 void FocusRoom(int room_id);
259
260 // Agent/Automation controls
261 void SelectObject(int obj_id);
262 void SetAgentMode(bool enabled);
265 bool CycleRoomSelection(int direction);
266 // Select the next or previous room object in the active editable canvas.
267 bool CycleObjectSelection(int direction);
268
269 // ROM state
270 bool IsRomLoaded() const override { return rom_ && rom_->is_loaded(); }
271 std::string GetRomStatus() const override {
272 if (!rom_)
273 return "No ROM loaded";
274 if (!rom_->is_loaded())
275 return "ROM failed to load";
276 return absl::StrFormat("ROM loaded: %s", rom_->title());
277 }
278
279 // Open a workspace window by its id using WorkspaceWindowManager.
280 void OpenWindow(const std::string& window_id) {
283 }
284 }
285
286 // Create and register the project-only Minecart Tracks surface on demand.
287 // This supports enabling custom objects after the Dungeon editor has loaded.
288 absl::Status EnsureMinecartTrackEditorPanel();
289
290 // Explicit workflow toggle between integrated Workbench and standalone panels.
291 void SetWorkbenchWorkflowMode(bool enabled, bool show_toast = true);
292 // Queue a workflow mode change to run at a safe point in the next update.
293 void QueueWorkbenchWorkflowMode(bool enabled, bool show_toast = true);
294 // Queue a mode flip (Workbench <-> Standalone) for next update.
295 void ToggleWorkbenchWorkflowMode(bool show_toast = true);
296 bool IsWorkbenchWorkflowEnabled() const;
297
298 // ShortcutManager runs before this editor draws. Queue destructive keyboard
299 // actions so the room canvas can establish ownership for the current frame
300 // before the action is evaluated.
302
303 // Panel card IDs for programmatic access
304 static constexpr const char* kRoomSelectorId = "dungeon.room_selector";
305 static constexpr const char* kEntranceListId = "dungeon.entrance_list";
306 static constexpr const char* kRoomMatrixId = "dungeon.room_matrix";
307 static constexpr const char* kRoomGraphicsId = "dungeon.room_graphics";
308 static constexpr const char* kObjectSelectorId = "dungeon.object_selector";
309 static constexpr const char* kObjectToolsId = kObjectSelectorId;
310 static constexpr const char* kDoorEditorId = "dungeon.door_editor";
311 static constexpr const char* kPaletteEditorId = "dungeon.palette_editor";
312 static constexpr const char* kMinecartTrackEditorId =
313 "dungeon.minecart_tracks";
314
315 // Public accessors for WASM API and automation
318 const ImVector<int>& active_rooms() const {
320 }
322 const DungeonRoomStore& rooms() const { return rooms_; }
323 gfx::IRenderer* renderer() const { return renderer_; }
331
336 const std::deque<int>& GetRecentRooms() const { return recent_rooms_; }
337
338 private:
359 friend class
362 friend class
364 friend class
366 friend class
368 friend class
370 friend class
372 friend class
374 friend class
376 friend class
378
380
381 // Draw the Room Panels
382 void DrawRoomPanels();
383 void DrawRoomTab(int room_id);
384
385 // Texture processing (critical for rendering)
388
389 // Room selection callback
390 void OnRoomSelected(int room_id, bool request_focus = true);
391 void OnRoomSelected(int room_id, RoomSelectionIntent intent);
392 // Opens `room_id` and selects its placed object `object_index`. If the room
393 // changed since the index was built, falls back to the first object with
394 // `object_id`.
395 void NavigateToPlacedObject(int room_id, size_t object_index, int object_id);
396 // Object Coverage wiring, in dungeon_editor_v2_object_coverage.cc.
397 std::unique_ptr<ObjectCoveragePanel> CreateObjectCoveragePanel();
398 void FocusObjectCoverage(int room_id, const zelda3::RoomObject& object);
399 void OnEntranceSelected(int entrance_id);
400 void SetGraphicsPreviewEntrance(int entrance_id);
401 int ResolveEntranceRoomId(int entrance_id) const;
402
403 // Sync all sub-panels to the current room configuration
404 void SyncPanelsToRoom(int room_id);
406 void HandleArenaPaletteChanged(const std::string& group_name,
407 int palette_index);
411 uint8_t ResolveSelectedEntranceBlocksetForRoom(int room_id) const;
412 std::vector<DungeonRenderEntranceCandidate>
416 void ApplyEntranceRenderContext(int room_id);
417 void ConfigureViewerRenderContext(DungeonCanvasViewer* viewer, int room_id);
418 std::optional<DungeonEntranceCameraState> GetEntranceCameraState(
419 int slot_index) const;
420 absl::Status RepairEntranceCamera(int slot_index);
421 absl::Status RestoreEntranceCameraState(
422 int slot_index, const DungeonEntranceCameraState& state);
425 void RecordEntrancePropertyEdit(int slot_index,
426 const zelda3::RoomEntrance& before,
427 const zelda3::RoomEntrance& after,
428 std::shared_ptr<const int> gesture);
429 void RecordSpawnPropertyEdit(int slot_index,
430 const zelda3::DungeonSpawnPoint& before,
431 const zelda3::DungeonSpawnPoint& after,
432 std::shared_ptr<const int> gesture);
433 absl::Status RestoreEntranceProperties(int slot_index,
434 const zelda3::RoomEntrance& entrance);
435 absl::Status RestoreSpawnProperties(int slot_index,
436 const zelda3::DungeonSpawnPoint& spawn);
437 void RefreshEntranceDirtyState(int slot_index);
440 absl::Status ApplyMinecartTrackEdit(const MinecartTrack& before,
441 const MinecartTrack& after,
442 bool move_cart);
444
445 // Show or create a standalone room panel
446 void ShowRoomPanel(int room_id);
447
448 // Convenience action for Settings panel.
449 void SaveAllRooms();
450
451 // Object placement callback
452 void HandleObjectPlaced(const zelda3::RoomObject& obj);
453 void OpenGraphicsEditorForObject(int room_id,
454 const zelda3::RoomObject& object);
455 absl::Status OpenObjectTileEditorForObject(int room_id,
456 const zelda3::RoomObject& object);
457
458 // Helper to get or create a viewer for a specific room
460 // An explicitly open room panel keeps its own viewer even while the
461 // Workbench is the active workflow (for example, a pinned room panel).
465 void RefreshViewerRuntimeContext(DungeonCanvasViewer* viewer, int room_id,
466 bool rebind_project = false);
470 void TouchViewerLru(int room_id);
471 void RemoveViewerFromLru(int room_id);
472
473 absl::Status SaveRoomData(int room_id);
474 absl::Status SaveRoomImpl(int room_id, bool room_data_only);
475 absl::Status RunWithSaveTransaction(
476 const std::function<absl::Status()>& operation);
477
478 // Data
482 std::array<zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots> entrances_;
483 std::array<zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints>
485 mutable std::optional<zelda3::RoomCensus> dungeon_render_context_census_;
486 mutable std::future<absl::StatusOr<zelda3::RoomCensus>>
495
497 std::vector<std::pair<int, zelda3::Room::SaveDirtySnapshot>> room_states;
498 std::array<bool, zelda3::kNumDungeonEntranceSlots> entrance_dirty_states{};
499 std::array<bool, zelda3::kNumDungeonSpawnPoints> spawn_dirty_states{};
501 bool pit_damage_dirty = false;
503 };
504 std::optional<SaveTransactionSnapshot> save_transaction_snapshot_;
506
508
509 // Current selection state
510 // Combined slots begin with spawn points; regular Entrance 00 follows them.
513
514 // Active room tabs and card tracking for jump-to
515 ImVector<int> active_rooms_;
517
518 // Recent rooms history for quick navigation (most recent first, max 10)
519 static constexpr size_t kMaxRecentRooms = 10;
520 std::deque<int> recent_rooms_;
521 std::vector<int> pinned_rooms_;
522
523 // Workbench panel pointer (owned by WorkspaceWindowManager, stored for notifications).
527
528 // Palette management
534
535 // Components - these do all the work
538 static constexpr int kMaxCachedViewers = 20;
539 // Shared by this editor's room panels, never by other ROM sessions.
543 std::unique_ptr<DungeonCanvasViewer> workbench_viewer_;
544 std::unique_ptr<DungeonCanvasViewer> workbench_compare_viewer_;
545
547 // Panel pointers. WorkspaceWindowManager owns these when available; fallback
548 // unique_ptrs keep non-workspace tests and direct embedding paths alive.
549 // Workbench mode embeds room-local utilities in the Tools inspector. Their
550 // standalone entries remain discoverable, but one content instance has only
551 // one active presentation owner at a time.
566
567 // Owned content fields are fallbacks for tests without WorkspaceWindowManager.
568 std::unique_ptr<ObjectSelectorContent> owned_object_selector_panel_;
569 std::unique_ptr<DoorEditorContent> owned_door_editor_panel_;
570 std::unique_ptr<RoomTagEditorPanel> owned_room_tag_editor_panel_;
571 std::unique_ptr<ObjectCoveragePanel> owned_object_coverage_panel_;
572 std::unique_ptr<CustomCollisionPanel> owned_custom_collision_panel_;
573 std::unique_ptr<WaterFillPanel> owned_water_fill_panel_;
574 std::unique_ptr<MinecartTrackEditorPanel> owned_minecart_track_editor_panel_;
575 std::unique_ptr<zelda3::DungeonEditorSystem> dungeon_editor_system_;
576 std::unique_ptr<emu::render::EmulatorRenderService> render_service_;
577
578 bool is_loaded_ = false;
581
582 // Docking class for room windows to dock together
583 ImGuiWindowClass room_window_class_;
584
585 // Shared dock ID for all room panels to auto-dock together
586 ImGuiID room_dock_id_ = 0;
587
588 // Dynamic room cards - created per open room
589 std::unordered_map<int, std::shared_ptr<gui::PanelWindow>> room_cards_;
590
591 // Stable window slot mapping: room_id -> slot_id.
592 // Slot IDs are used in the "###" part of the window title so ImGui treats the
593 // window as the same entity even when its displayed room changes.
595 std::unordered_map<int, int> room_panel_slot_ids_;
596
597 // Pending undo snapshot: captured on mutation callback (before edit),
598 // finalized on cache invalidation callback (after edit) by pushing an undo
599 // action to the inherited undo_manager_.
600 struct PendingUndo {
601 int room_id = -1;
602 std::vector<zelda3::RoomObject> before_objects;
603 std::vector<chest_data> before_chests;
604 std::vector<size_t> before_selection;
605 };
607 bool has_pending_undo_ = false;
609
611 std::optional<DungeonSelectionEditPlan> plan;
613 };
615
620 // Doors, sprites and pot items can be dragged together; keep each domain's
621 // original snapshot until its corresponding completion notification.
622 std::array<PendingEntityUndo, 3> pending_entity_undo_;
623
629
635
636 // True while any gesture snapshot is waiting for FinalizePendingUndoActions.
640 pending_selection_undo_.plan.has_value()) {
641 return true;
642 }
643 for (const auto& pending : pending_entity_undo_) {
644 if (pending.room_id >= 0) {
645 return true;
646 }
647 }
648 return false;
649 }
650
651 // Pending room swap (deferred until after draw phase completes)
652 struct PendingSwap {
653 int old_room_id = -1;
654 int new_room_id = -1;
655 bool pending = false;
656 };
658
660 bool enabled = false;
661 bool show_toast = true;
662 bool pending = false;
663 };
665
666 // Opening or focusing a standalone tool mutates WorkspaceWindowManager and
667 // Dear ImGui focus state. Workbench buttons are drawn inside child windows,
668 // so defer that mutation to the next Update() safe point. Capture the
669 // originating session so a session switch cannot redirect the request.
671 size_t session_id = 0;
672 std::string window_id;
673 bool pending = false;
674 };
676
677 // Unpinned room-navigation panels hidden by the most recent transition into
678 // the integrated Workbench. Standalone editing tools remain user-owned and
679 // are never added to this restoration set.
681
682 // Two-phase undo capture: BeginUndoSnapshot saves state before mutation,
683 // FinalizeUndoAction captures state after mutation and pushes the action.
684 void BeginUndoSnapshot(int room_id);
685 void FinalizeUndoAction(int room_id);
686 absl::Status RestoreRoomObjects(
687 int room_id, const std::vector<zelda3::RoomObject>& objects,
688 const std::vector<size_t>& selected_indices,
689 const std::vector<chest_data>& chests);
690 absl::Status PreflightObjectMutation(
691 int room_id, const std::vector<zelda3::RoomObject>& objects,
692 const std::vector<chest_data>& chests, bool check_streams = true);
693 absl::Status PreflightStreamMutation(
694 int room_id, const DungeonSelectionEditState& candidate, uint8_t domains);
695 absl::Status PreflightSpriteMutation(
696 int room_id, const std::vector<zelda3::Sprite>& sprites);
697 absl::Status PreflightPotItemPlacement(
698 int room_id, const std::vector<zelda3::PotItem>& items);
699 absl::StatusOr<std::vector<std::pair<uint32_t, uint32_t>>>
701 const std::vector<DungeonSelectionEditPlan>& candidates) const;
702 absl::Status PreflightDoorMutation(
703 int room_id, const std::vector<zelda3::Room::Door>& doors);
704 absl::Status ApplyChestObjectEdit(
705 int room_id, const std::vector<zelda3::RoomObject>& objects,
706 const std::vector<chest_data>& chests,
707 const std::vector<size_t>& selection);
708
709 absl::Status CommitSelectionEdit(const DungeonSelectionEditPlan& plan,
710 bool continuous);
712 absl::Status RestoreSelectionEditBatch(
713 const std::vector<DungeonSelectionEditPlan>& plans, bool after);
714 absl::Status EnsureConnectionRoomLoaded(int room_id);
715 absl::Status EnsureRoomTransferLoaded(int room_id);
716 absl::Status PreflightRoomTransfer(const DungeonRoomTransferPlan& plan);
717 absl::Status RestoreRoomTransfer(int room_id,
718 const DungeonRoomDocument& document);
719 void RefreshSelectionEditViews(int room_id,
720 const DungeonSelectionEditState* selection);
722 void PushSelectionUndoBatch(std::vector<DungeonSelectionEditPlan> plans,
723 std::string description);
726 absl::Status RestoreRoomMetadataBatch(
727 const std::vector<std::pair<int, zelda3::Room::MetadataSnapshot>>&
728 states);
729 absl::Status RestoreChest(int room_id, size_t index, chest_data chest);
730 void RefreshRoomMetadataViews(int room_id);
732 void BeginEntityUndoSnapshot(int room_id, MutationDomain domain);
733 void FinalizeEntityUndoAction(int room_id, MutationDomain domain);
735 absl::Status RestoreRoomEntities(int room_id, MutationDomain domain,
736 const DungeonEntitySnapshot& snapshot);
737
738 void BeginCollisionUndoSnapshot(int room_id);
739 void FinalizeCollisionUndoAction(int room_id);
740 void RestoreRoomCustomCollision(int room_id,
741 const zelda3::CustomCollisionMap& map);
742 absl::Status ApplyMinecartCollisionStamp(
743 int room_id, const zelda3::CustomCollisionMap& expected,
744 const MinecartCollisionStamp& stamp);
745 absl::Status ApplyMinecartCollisionBatch(
746 const std::vector<zelda3::TrackCollisionResult>& preview,
747 const zelda3::GeneratorOptions& options);
749 const std::vector<DungeonCustomCollisionSnapshot>& snapshots);
750
751 void BeginWaterFillUndoSnapshot(int room_id);
752 void FinalizeWaterFillUndoAction(int room_id);
753 void RestoreRoomWaterFill(int room_id, const WaterFillSnapshot& snap);
754 void SwapRoomInPanel(int old_room_id, int new_room_id);
755 void ProcessPendingSwap(); // Process deferred swap after draw
758
759 // Room panel slot IDs provide stable ImGui window IDs across "swap room in
760 // panel" navigation. This keeps the window position/dock state when the room
761 // changes via the directional arrows.
762 int GetOrCreateRoomPanelSlotId(int room_id);
763 void ReleaseRoomPanelSlotId(int room_id);
764
765 // Defensive guard: returns true iff room_id is within the valid range
766 // [0, kNumberOfRooms). Use this instead of open-coded range checks.
767 static bool IsValidRoomId(int room_id) {
768 return room_id >= 0 && room_id < zelda3::kNumberOfRooms;
769 }
770};
771
772} // namespace editor
773} // namespace yaze
774
775#endif // YAZE_APP_EDITOR_DUNGEON_EDITOR_V2_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:49
bool is_loaded() const
Definition rom.h:187
auto title() const
Definition rom.h:199
DungeonEditorV2 - Simplified dungeon editor using component delegation.
class MinecartTrackEditorPanel * minecart_track_editor_panel_
EditorContextSnapshot BuildContextSnapshot() const override
std::optional< zelda3::RoomCensus > dungeon_render_context_census_
DungeonRenderContext ResolveDungeonRenderContextForRoom(int room_id) const
absl::Status EditRoomGraphicsSheet(int room_id, int slot, int sheet_id)
absl::Status RestoreEntranceCameraState(int slot_index, const DungeonEntranceCameraState &state)
friend class DungeonEditorV2SpawnRejectionTestPeer
friend class DungeonEditorEntrancePropertiesTestPeer
std::unique_ptr< CustomCollisionPanel > owned_custom_collision_panel_
friend class DungeonEditorV2MinecartTrackTestPeer
class CustomCollisionPanel * custom_collision_panel_
void ConfigureViewerUndoHooks(DungeonCanvasViewer *viewer)
std::function< const zelda3::Overworld *()> room_graphics_overworld_provider_
std::optional< int > room_canvas_delete_shortcut_frame_
friend class DungeonEditorV2RegularEntranceTestPeer
friend class DungeonEditorV2RomSafetyTest_SaveAllRoomsRollsBackEarlierWritesOnLateFailure_Test
friend class DungeonEditorPaletteRefreshTest_CachedRoomRefreshesThroughViewerCompositePreparation_Test
absl::Status PreflightObjectMutation(int room_id, const std::vector< zelda3::RoomObject > &objects, const std::vector< chest_data > &chests, bool check_streams=true)
void RefreshViewerRuntimeContext(DungeonCanvasViewer *viewer, int room_id, bool rebind_project=false)
absl::Status PreflightRoomTransfer(const DungeonRoomTransferPlan &plan)
void ToggleWorkbenchWorkflowMode(bool show_toast=true)
friend class DungeonEditorPaletteRefreshTest_SharedHudEditRefreshesRoomUsingDifferentDungeonPalette_Test
void RestoreRoomWaterFill(int room_id, const WaterFillSnapshot &snap)
absl::Status RestoreRoomEntities(int room_id, MutationDomain domain, const DungeonEntitySnapshot &snapshot)
void ContributeStatus(StatusBar *status_bar) override
void OpenGraphicsEditorForObject(int room_id, const zelda3::RoomObject &object)
absl::Status OpenObjectTileEditorForObject(int room_id, const zelda3::RoomObject &object)
class ItemEditorPanel * item_editor_panel_
std::unique_ptr< RoomTagEditorPanel > owned_room_tag_editor_panel_
class ObjectCoveragePanel * object_coverage_panel_
std::unique_ptr< ObjectCoveragePanel > CreateObjectCoveragePanel()
absl::StatusOr< zelda3::RoomsetUsageReport > GetRoomGraphicsUsage(int roomset) const
void SetDependencies(const EditorDependencies &deps) override
void BeginEntityUndoSnapshot(int room_id, MutationDomain domain)
std::unique_ptr< ObjectCoveragePanel > owned_object_coverage_panel_
ObjectSelectorContent * object_selector_panel() const
absl::Status ApplyRoomTransfer(const DungeonRoomTransferPlan &plan)
util::LruCache< int, std::unique_ptr< DungeonCanvasViewer > > room_viewers_
gfx::PaletteGroup current_palette_group_
void OnEntranceSelected(int entrance_id)
static constexpr const char * kEntranceListId
DungeonEntitySnapshot CaptureRoomEntities(int room_id, MutationDomain domain)
absl::Status CommitSelectionEdit(const DungeonSelectionEditPlan &plan, bool continuous)
friend class DungeonEditorV2EntranceCameraTestPeer
PendingStandaloneToolWindow pending_standalone_tool_window_
class SpriteEditorPanel * sprite_editor_panel_
void HandleObjectPlaced(const zelda3::RoomObject &obj)
std::string GetRomStatus() const override
DoorEditorContent * door_editor_panel() const
std::unique_ptr< zelda3::DungeonEditorSystem > dungeon_editor_system_
std::array< zelda3::RoomEntrance, zelda3::kNumDungeonEntranceSlots > entrances_
void OpenWindow(const std::string &window_id)
absl::Status PreflightPotItemPlacement(int room_id, const std::vector< zelda3::PotItem > &items)
friend class DungeonEditorV2ObjectTileEditorTestPeer
DoorEditorContent * door_editor_panel_
absl::Status ApplyDoorConnection(const DungeonConnectionPlan &plan)
std::unordered_map< int, int > room_panel_slot_ids_
friend class DungeonEditorV2RomSafetyTest_UndoSnapshotLeakDetection_Test
absl::Status EditRoomMetadataBatch(const std::vector< RoomMetadataRequest > &requests)
class DungeonWorkbenchContent * workbench_panel_
int ResolveEntranceRoomId(int entrance_id) const
absl::Status ValidateSaveScope(int only_room=-1, bool room_data_only=false) const
friend class DungeonEditorV2RomSafetyTest_ViewerCacheLRUEviction_Test
void OnRoomSelected(int room_id, bool request_focus=true)
void RefreshSelectionEditViews(int room_id, const DungeonSelectionEditState *selection)
absl::Status ApplyMinecartCollisionStamp(int room_id, const zelda3::CustomCollisionMap &expected, const MinecartCollisionStamp &stamp)
absl::StatusOr< std::vector< std::pair< uint32_t, uint32_t > > > PlanPendingRoomStreamRanges(const std::vector< DungeonSelectionEditPlan > &candidates) const
friend class DungeonEditorV2RomSafetyTest_ViewerCacheNeverEvictsActiveRooms_Test
std::optional< DungeonEntranceCameraState > GetEntranceCameraState(int slot_index) const
absl::Status RestoreEntranceProperties(int slot_index, const zelda3::RoomEntrance &entrance)
void FinalizeEntityUndoAction(int room_id, MutationDomain domain)
PendingCollisionUndo pending_collision_undo_
void FocusObjectCoverage(int room_id, const zelda3::RoomObject &object)
void ConfigureEntrancePropertyEditCallbacks(DungeonEntrancesPanel *panel)
ObjectTileEditorPanel * object_tile_editor_panel_
absl::Status PreflightDoorMutation(int room_id, const std::vector< zelda3::Room::Door > &doors)
ObjectSelectorContent * object_selector_panel_
OverlayManagerPanel * overlay_manager_panel_
absl::Status RestoreRoomObjects(int room_id, const std::vector< zelda3::RoomObject > &objects, const std::vector< size_t > &selected_indices, const std::vector< chest_data > &chests)
uint8_t ResolveSelectedEntranceBlocksetForRoom(int room_id) const
absl::Status PreflightSpriteMutation(int room_id, const std::vector< zelda3::Sprite > &sprites)
DungeonCanvasViewer * GetWorkbenchCompareViewer(int room_id)
bool CycleObjectSelection(int direction)
void WireViewerPanelCallbacks(DungeonCanvasViewer *viewer)
absl::Status RestoreSelectionEditBatch(const std::vector< DungeonSelectionEditPlan > &plans, bool after)
absl::Status EditRoomMetadata(int room_id, const RoomMetadataEdit &edit)
gfx::IRenderer * renderer() const
std::vector< DungeonRenderEntranceCandidate > BuildDungeonRenderEntranceCandidates() const
std::unique_ptr< DungeonCanvasViewer > workbench_compare_viewer_
PendingWaterFillUndo pending_water_fill_undo_
RoomMatrixContent * room_matrix_panel_
std::unique_ptr< MinecartTrackEditorPanel > owned_minecart_track_editor_panel_
absl::Status ApplyMinecartTrackEdit(const MinecartTrack &before, const MinecartTrack &after, bool move_cart)
void SetGraphicsPreviewEntrance(int entrance_id)
std::array< PendingEntityUndo, 3 > pending_entity_undo_
bool IsRomLoaded() const override
gui::PaletteEditorWidget palette_editor_
std::unique_ptr< DoorEditorContent > owned_door_editor_panel_
const std::deque< int > & GetRecentRooms() const
Get the list of recently visited room IDs.
bool ConsumeRoomCanvasDeleteShortcut(DungeonCanvasViewer &viewer)
static bool IsValidRoomId(int room_id)
void VisitGraphicsUsageRooms(const std::function< void(int, zelda3::Room &, const std::string &, bool, int)> &visitor)
void SwapRoomInPanel(int old_room_id, int new_room_id)
void RecordEntrancePropertyEdit(int slot_index, const zelda3::RoomEntrance &before, const zelda3::RoomEntrance &after, std::shared_ptr< const int > gesture)
RoomGraphicsContent * room_graphics_panel_
absl::Status RunWithSaveTransaction(const std::function< absl::Status()> &operation)
const DungeonRoomStore & rooms() const
static constexpr int kMaxCachedViewers
static constexpr size_t kMaxRecentRooms
std::array< zelda3::DungeonSpawnPoint, zelda3::kNumDungeonSpawnPoints > spawn_points_
void SetWorkbenchWorkflowMode(bool enabled, bool show_toast=true)
const zelda3::RoomCensus * GetDungeonRenderContextCensus() const
class RoomTagEditorPanel * room_tag_editor_panel_
std::optional< SaveTransactionSnapshot > save_transaction_snapshot_
std::unique_ptr< ObjectSelectorContent > owned_object_selector_panel_
friend class DungeonEditorV2RomSafetyTest_ViewerCacheLRUAccessOrderUpdate_Test
friend class DungeonEditorPaletteRefreshTest_CompareViewerScopesEntranceContextToRequestedRoom_Test
static constexpr const char * kDoorEditorId
friend class DungeonEditorV2RomSafetyTest_LateCoordinatorRollbackRestoresEntranceDirtyState_Test
static constexpr const char * kObjectToolsId
DungeonCanvasViewer * GetViewerForRoom(int room_id)
PendingSelectionUndo pending_selection_undo_
void SetRoomGraphicsOverworldProvider(std::function< const zelda3::Overworld *()> provider)
absl::StatusOr< std::string > ExportRoomDocument(int room_id)
class WaterFillPanel * water_fill_panel_
std::future< absl::StatusOr< zelda3::RoomCensus > > dungeon_render_context_census_pending_
absl::Status RestoreRoomCustomCollisionBatch(const std::vector< DungeonCustomCollisionSnapshot > &snapshots)
absl::Status Find() override
bool NavigateToAdjacentRoom(DungeonRoomNavigationDirection direction)
friend class DungeonEditorPaletteRefreshTest_DungeonMainEditRefreshesResolvedAliasesOnly_Test
ObjectSelectorContent * object_editor_panel() const
std::unique_ptr< emu::render::EmulatorRenderService > render_service_
DungeonCanvasViewer * GetWorkbenchViewer()
std::unordered_map< int, std::shared_ptr< gui::PanelWindow > > room_cards_
absl::Status DeleteChest(int room_id, size_t index)
void ApplyEntranceRenderContext(int room_id)
void SetGameData(zelda3::GameData *game_data) override
friend class DungeonEditorV2RomSafetyTest_ObjectStreamUndoRedoRestoresSelectionIdentity_Test
absl::Status RestoreRoomMetadataBatch(const std::vector< std::pair< int, zelda3::Room::MetadataSnapshot > > &states)
static constexpr const char * kObjectSelectorId
absl::StatusOr< DungeonRoomTransferPlan > PreviewRoomTransfer(int target_room_id, int source_room_id, const std::string &json, const DungeonRoomTransferOptions &options)
void ConfigureViewerRenderContext(DungeonCanvasViewer *viewer, int room_id)
static constexpr const char * kRoomGraphicsId
void QueueWorkbenchWorkflowMode(bool enabled, bool show_toast=true)
static constexpr const char * kRoomMatrixId
void HandleDungeonPaletteChanged(gui::DungeonPaletteChange change)
static constexpr const char * kRoomSelectorId
const ImVector< int > & active_rooms() const
void ConfigureEditableViewer(DungeonCanvasViewer *viewer)
PaletteEditorContent * palette_editor_panel_
static constexpr const char * kMinecartTrackEditorId
DungeonSelectionClipboard selection_clipboard_
std::unique_ptr< DungeonCanvasViewer > workbench_viewer_
void RestoreRoomCustomCollision(int room_id, const zelda3::CustomCollisionMap &map)
absl::Status SaveRoomImpl(int room_id, bool room_data_only)
void RecordSpawnPropertyEdit(int slot_index, const zelda3::DungeonSpawnPoint &before, const zelda3::DungeonSpawnPoint &after, std::shared_ptr< const int > gesture)
util::StopSource dungeon_render_context_census_stop_
absl::Status PreflightStreamMutation(int room_id, const DungeonSelectionEditState &candidate, uint8_t domains)
absl::Status RestoreChest(int room_id, size_t index, chest_data chest)
absl::Status EditChest(int room_id, size_t index, uint8_t item_id, bool big_chest)
absl::Status ApplyChestObjectEdit(int room_id, const std::vector< zelda3::RoomObject > &objects, const std::vector< chest_data > &chests, const std::vector< size_t > &selection)
DungeonCanvasViewer * GetStandaloneViewerForRoom(int room_id)
absl::Status RestoreSpawnProperties(int slot_index, const zelda3::DungeonSpawnPoint &spawn)
std::vector< std::pair< uint32_t, uint32_t > > CollectWriteRanges() const
std::unique_ptr< WaterFillPanel > owned_water_fill_panel_
absl::Status ApplyMinecartCollisionBatch(const std::vector< zelda3::TrackCollisionResult > &preview, const zelda3::GeneratorOptions &options)
absl::Status RestoreRoomTransfer(int room_id, const DungeonRoomDocument &document)
DungeonEntrancesPanel * entrance_navigator_panel_
absl::StatusOr< DungeonConnectionPlan > PreviewDoorConnection(const DungeonConnectionRequest &request)
static constexpr const char * kPaletteEditorId
void PushSelectionUndoBatch(std::vector< DungeonSelectionEditPlan > plans, std::string description)
void PushSelectionUndoAction(DungeonSelectionEditPlan plan)
PendingWorkflowMode pending_workflow_mode_
void InvalidateDungeonPaletteUsers(gui::DungeonPaletteChange change)
void HandleArenaPaletteChanged(const std::string &group_name, int palette_index)
std::vector< std::string > workbench_suspended_navigation_window_ids_
void NavigateToPlacedObject(int room_id, size_t object_index, int object_id)
WindowContent for displaying and editing dungeon entrances.
Manages loading and saving of dungeon room data.
void SetGameData(zelda3::GameData *game_data)
Handles room and entrance selection UI.
const ImVector< int > & active_rooms() const
void set_current_entrance_id(int entrance_id)
void SetGameData(zelda3::GameData *game_data)
Interface for editor classes.
Definition editor.h:249
UndoManager undo_manager_
Definition editor.h:371
zelda3::GameData * game_data() const
Definition editor.h:357
EditorDependencies dependencies_
Definition editor.h:370
WindowContent for placing and managing dungeon pot items.
Checklist for proving each dungeon object draws like the game.
Browse and place dungeon objects.
void SetGameData(zelda3::GameData *game_data)
Panel for editing the tile8 composition of dungeon objects.
WindowContent wrapper for PaletteEditorWidget in dungeon context.
WindowContent for displaying room graphics blocks.
WindowContent for displaying a visual 16x19 grid of all dungeon rooms.
WindowContent showing all room tag slots and their usage across rooms.
WindowContent for placing and managing dungeon sprites.
A session-aware status bar displayed at the bottom of the application.
Definition status_bar.h:57
bool OpenWindow(size_t session_id, const std::string &base_window_id)
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Dungeon Room Entrance or Spawn Point.
MutationDomain
Domain/type of mutation for undo + invalidation routing.
RoomSelectionIntent
Intent for room selection in the dungeon editor.
constexpr NoStopStateTag kNoStopState
Definition stop_token.h:11
constexpr int kNumDungeonSpawnPoints
constexpr int kNumberOfRooms
Legacy chest data structure.
Definition zelda.h:438
Treasure chest.
Definition zelda.h:425
std::optional< DungeonSelectionEditPlan > plan
std::vector< zelda3::RoomObject > before_objects
std::vector< std::pair< int, zelda3::Room::SaveDirtySnapshot > > room_states
std::array< bool, zelda3::kNumDungeonSpawnPoints > spawn_dirty_states
std::array< bool, zelda3::kNumDungeonEntranceSlots > entrance_dirty_states
Unified dependency container for all editor types.
Definition editor.h:170
zelda3::GameData * game_data
Definition editor.h:173
WorkspaceWindowManager * window_manager
Definition editor.h:182
Represents a group of palettes.