yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_object_selector.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_SELECTOR_H
2#define YAZE_APP_EDITOR_DUNGEON_DUNGEON_OBJECT_SELECTOR_H
3
4#include <array>
5#include <cstdint>
6#include <functional>
7#include <map>
8#include <memory>
9#include <set>
10#include <string>
11#include <utility>
13
14#include "absl/status/status.h"
16#include "app/editor/editor.h"
19#include "rom/rom.h"
20#include "zelda3/dungeon/room.h"
22#include "zelda3/game_data.h"
23// object_renderer.h removed - using ObjectDrawer for production rendering
24#include "imgui/imgui.h"
27
28namespace yaze {
29namespace editor {
30
31class ObjectTileEditorPanel;
32struct DungeonObjectSelectorTestAccess;
33
35 int columns = 1;
36 float item_size = 1.0f;
37 float leading_inset = 0.0f;
38};
39
41 bool valid = false;
42 float x = 0.0f;
43 float y = 0.0f;
44 float width = 0.0f;
45 float height = 0.0f;
46};
47
48// Pure responsive-layout helpers shared by the selector and its unit tests.
50 float available_width, float preferred_item_size, float item_spacing,
51 float min_item_size = 32.0f);
53 float source_height,
54 float box_width,
55 float box_height);
56bool MatchesDungeonObjectStreamFilter(int object_id, int selected_filter);
57bool IsDungeonCustomObjectRuntimeSlot(int object_id, int subtype);
58bool IsMinecartGraphicsRuntimeSlot(int object_id, int subtype);
59std::string GetDungeonCustomObjectSlotName(int object_id, int subtype);
60
65 public:
66 explicit DungeonObjectSelector(Rom* rom = nullptr) : rom_(rom) {}
68
69 // Unified context setter (preferred)
71 rom_ = ctx.rom;
73 }
74 EditorContext context() const { return {rom_, game_data_}; }
75
76 // Individual setters for compatibility
77 void SetRom(Rom* rom) { rom_ = rom; }
78 Rom* rom() const { return rom_; }
81
82 // Room data access
83 void set_rooms(DungeonRoomStore* rooms) { rooms_ = rooms; }
85 void set_current_room_id(int room_id) { current_room_id_ = room_id; }
86
87 // Palette access
88 // Replace the active palette group used by preview rendering. The preview
89 // cache is keyed on object identity plus room blockset, palette, and floor
90 // graphics, none of which capture the *contents* of the palette group: switching
91 // dungeons between two palette banks that happen to use the same numeric
92 // slot value will keep cache hits valid by key but stale by color. Since
93 // the cache rebuilds in well under a frame, we conservatively invalidate
94 // on every palette-group swap rather than fingerprint the group.
95 void SetCurrentPaletteGroup(const gfx::PaletteGroup& palette_group) {
96 current_palette_group_ = palette_group;
98 }
99 // Object selection callbacks
101 std::function<void(const zelda3::RoomObject&)> callback) {
102 object_selected_callback_ = callback;
103 }
104 void SetPlacementInvalidatedCallback(std::function<void()> callback) {
105 placement_invalidated_callback_ = std::move(callback);
106 }
107
108 // Get current preview object for placement
110 bool IsObjectLoaded() const { return object_loaded_; }
111
112 // AssetBrowser-style object selection
113 void DrawObjectAssetBrowser(float minimum_grid_height = 1.0f);
115
116 // Rail palette shares the room-context thumbnail cache and placement path.
117 bool DrawMinecartPalette();
118
119 // Programmatic selection
120 void SelectObject(int obj_id, int subtype = -1);
121
123 std::function<absl::Status(int, const zelda3::RoomObject&)> callback) {
124 edit_object_tiles_callback_ = std::move(callback);
125 }
126
127 // Fixed-slot custom-object management actions.
131 void SetOpenTileEditorWindowCallback(std::function<bool()> callback) {
132 open_tile_editor_window_callback_ = std::move(callback);
133 }
134 void SetOpenMinecartEditorWindowCallback(std::function<bool()> callback) {
135 open_minecart_editor_window_callback_ = std::move(callback);
136 }
137
138 // Invalidate preview and layout caches (e.g., after new custom object added)
141
142 // Break references to one DungeonEditorV2 session without mutating the
143 // process-wide custom-object manager used by other sessions.
145
146 // Test-only inspection. Increments every time InvalidatePreviewCache runs
147 // so unit tests can pin behavioral contracts (e.g. SetCurrentPaletteGroup
148 // must invalidate) without needing a full rendering pipeline.
156 bool matches_object_filter_for_testing(int obj_id, int filter_type) {
157 return MatchesObjectFilter(obj_id, filter_type);
158 }
159 std::string object_type_symbol_for_testing(int object_id) {
160 return GetObjectTypeSymbol(object_id);
161 }
162 static bool IsRepresentableChestObjectId(int object_id);
163
164 private:
166 enum class BrowserMode {
167 kObjects,
169 };
170
171 bool MatchesObjectFilter(int obj_id, int filter_type);
172 bool MatchesRoomUsage(int obj_id) const;
173 bool MatchesObjectSearch(int obj_id, const std::string& name,
174 int subtype = -1) const;
175 void CalculateObjectDimensions(const zelda3::RoomObject& object, int& width,
176 int& height);
177 bool DrawObjectPreview(const zelda3::RoomObject& object, ImVec2 top_left,
178 ImVec2 box_size);
179 zelda3::RoomObject MakePreviewObject(int obj_id) const;
181 ImU32 GetObjectTypeColor(int object_id);
182 std::string GetObjectTypeSymbol(int object_id);
183 absl::Status GetCustomObjectAssetStatus(int object_id, int subtype);
185 absl::Status OpenExistingCustomObjectEditor(int16_t object_id, int subtype,
186 int room_id);
187
191
192 // References for custom-object management.
193 std::function<absl::Status(int, const zelda3::RoomObject&)>
195 void DrawObjectContextMenu(int object_id, int subtype = -1);
196 void DrawObjectDetails(int object_id, int subtype);
201
202 Rom* rom_ = nullptr;
206 std::map<uint32_t, absl::Status> custom_asset_status_cache_;
207
208 // Room data
211
212 // Palette data
214
216
217 // Object preview system
219 bool object_loaded_ = false;
221
222 // Callback for object selection
224 std::function<void()> placement_invalidated_callback_;
225
226 // Object selection state
229
230 // UI state for object browser filter
232 int object_stream_filter_ = 0; // 0=All, 1=Type1, 2=Type2, 3=Type3
233 bool used_here_only_ = false;
234 int object_grid_density_ = 0; // 0=Compact, 1=Medium, 2=Large
235 char object_search_buffer_[64] = {0};
236
237 // Registry initialization flag
239
240 // Performance: enable/disable graphical preview rendering
242
243 // Preview cache for object selector grid, keyed by object/subtype and the
244 // room graphics context that can change its rendered tiles.
245 // Value: BackgroundBuffer with rendered preview
246 std::map<uint64_t, std::unique_ptr<gfx::BackgroundBuffer>> preview_cache_;
247 std::set<uint64_t> failed_preview_keys_; // cleared with preview_cache_
255
256 std::map<uint32_t, zelda3::ObjectTileLayout> layout_cache_;
257
258 // Bumped by InvalidatePreviewCache() to give tests a way to assert the
259 // cache invalidation contract without poking at the cache directly.
261
262 void RetirePreviewCache();
264 static uint32_t MakeLayoutCacheKey(int object_id, uint8_t preview_size,
265 const zelda3::Room* room);
266 bool GetOrCreatePreview(const zelda3::RoomObject& object,
268};
269
270} // namespace editor
271} // namespace yaze
272
273#endif
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:52
Handles object selection, preview, and editing UI.
void SynchronizePreviewCacheRoomContext(const zelda3::Room &room)
std::function< void()> placement_invalidated_callback_
std::function< bool()> open_minecart_editor_window_callback_
std::string object_type_symbol_for_testing(int object_id)
absl::Status OpenExistingCustomObjectEditor(int16_t object_id, int subtype, int room_id)
std::map< uint32_t, absl::Status > custom_asset_status_cache_
void DrawObjectContextMenu(int object_id, int subtype=-1)
void CalculateObjectDimensions(const zelda3::RoomObject &object, int &width, int &height)
zelda3::DungeonObjectRegistry object_registry_
void SetGameData(zelda3::GameData *game_data)
bool MatchesObjectSearch(int obj_id, const std::string &name, int subtype=-1) const
void DrawObjectDetails(int object_id, int subtype)
void set_rooms(DungeonRoomStore *rooms)
std::function< absl::Status(int, const zelda3::RoomObject &) edit_object_tiles_callback_)
void DrawObjectAssetBrowser(float minimum_grid_height=1.0f)
void SetCurrentPaletteGroup(const gfx::PaletteGroup &palette_group)
bool matches_object_filter_for_testing(int obj_id, int filter_type)
std::size_t preview_cache_invalidations_for_testing() const
static bool IsRepresentableChestObjectId(int object_id)
absl::Status GetCustomObjectAssetStatus(int object_id, int subtype)
void SetOpenMinecartEditorWindowCallback(std::function< bool()> callback)
void SelectObject(int obj_id, int subtype=-1)
const zelda3::RoomObject & GetPreviewObject() const
std::function< bool()> open_tile_editor_window_callback_
workbench::DungeonBrowserState browser_state_
std::function< void(const zelda3::RoomObject &) object_selected_callback_)
std::map< uint64_t, std::unique_ptr< gfx::BackgroundBuffer > > preview_cache_
void SetOpenTileEditorWindowCallback(std::function< bool()> callback)
void SetPlacementInvalidatedCallback(std::function< void()> callback)
void SetTileEditorPanel(ObjectTileEditorPanel *panel)
zelda3::RoomObject MakePreviewObject(int obj_id) const
std::map< uint32_t, zelda3::ObjectTileLayout > layout_cache_
bool GetOrCreatePreview(const zelda3::RoomObject &object, gfx::BackgroundBuffer **out)
static uint32_t MakeLayoutCacheKey(int object_id, uint8_t preview_size, const zelda3::Room *room)
bool MatchesObjectFilter(int obj_id, int filter_type)
void SetObjectSelectedCallback(std::function< void(const zelda3::RoomObject &)> callback)
bool DrawObjectPreview(const zelda3::RoomObject &object, ImVec2 top_left, ImVec2 box_size)
void SetEditObjectTilesCallback(std::function< absl::Status(int, const zelda3::RoomObject &)> callback)
Panel for editing the tile8 composition of dungeon objects.
Minimal registry for dungeon objects (vanilla or custom).
bool MatchesDungeonObjectStreamFilter(int object_id, int selected_filter)
bool IsMinecartGraphicsRuntimeSlot(int object_id, int subtype)
bool IsDungeonCustomObjectRuntimeSlot(int object_id, int subtype)
DungeonObjectPreviewFit ResolveDungeonObjectPreviewFit(float source_width, float source_height, float box_width, float box_height)
std::string GetDungeonCustomObjectSlotName(int object_id, int subtype)
DungeonObjectSelectorGridLayout ResolveDungeonObjectSelectorGridLayout(float available_width, float preferred_item_size, float item_spacing, float min_item_size)
Lightweight view into the essential runtime context (Rom + GameData)
Definition editor.h:73
zelda3::GameData * game_data
Definition editor.h:75
Represents a group of palettes.