yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
palette_manager.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GFX_PALETTE_MANAGER_H
2#define YAZE_APP_GFX_PALETTE_MANAGER_H
3
4#include <cstdint>
5#include <deque>
6#include <functional>
7#include <memory>
8#include <string>
9#include <unordered_map>
10#include <unordered_set>
11#include <vector>
12
13#include "absl/status/status.h"
14#include "absl/status/statusor.h"
17
18namespace yaze {
19
20// Forward declarations
21class Rom;
22namespace zelda3 {
23struct GameData;
24}
25
26namespace gfx {
27
39
52
54 std::string group_name;
55 int palette_index = -1;
56 int color_index = -1;
57};
58
75 public:
76 using ChangeCallback = std::function<void(const PaletteChangeEvent&)>;
77
79 static PaletteManager& Get() {
80 static PaletteManager instance;
81 return instance;
82 }
83
84 // Delete copy/move constructors and assignment operators
89
90 // ========== Initialization ==========
91
96 void Initialize(zelda3::GameData* game_data);
97
102 void Initialize(Rom* rom);
103
107 bool IsInitialized() const { return game_data_ != nullptr || rom_ != nullptr; }
108
112 void ResetForTesting();
113
114 // ========== Color Operations ==========
115
123 SnesColor GetColor(const std::string& group_name, int palette_index,
124 int color_index) const;
125
134 absl::Status SetColor(const std::string& group_name, int palette_index,
135 int color_index, const SnesColor& new_color);
136
140 absl::Status ResetColor(const std::string& group_name, int palette_index,
141 int color_index);
142
146 absl::Status ResetPalette(const std::string& group_name, int palette_index);
147
148 // ========== Dirty Tracking ==========
149
153 bool HasUnsavedChanges() const;
154
158 std::vector<std::string> GetModifiedGroups() const;
159
163 bool IsGroupModified(const std::string& group_name) const;
164
168 bool IsPaletteModified(const std::string& group_name,
169 int palette_index) const;
170
174 bool IsColorModified(const std::string& group_name, int palette_index,
175 int color_index) const;
176
180 size_t GetModifiedColorCount() const;
181
182 // ========== Persistence ==========
183
187 absl::Status SaveGroup(const std::string& group_name);
188
192 absl::Status SaveAllToRom();
193
197 void DiscardGroup(const std::string& group_name);
198
202 void DiscardAllChanges();
203
204 // ========== Preview Mode ==========
205
213 absl::Status ApplyPreviewChanges();
214
215 // ========== Undo/Redo ==========
216
220 void Undo();
221
225 void Redo();
226
230 bool CanUndo() const { return !undo_stack_.empty(); }
231
235 bool CanRedo() const { return !redo_stack_.empty(); }
236
240 size_t GetUndoStackSize() const { return undo_stack_.size(); }
241
245 size_t GetRedoStackSize() const { return redo_stack_.size(); }
246
250 void ClearHistory();
251
252 // ========== Change Notifications ==========
253
259
263 void UnregisterChangeListener(int callback_id);
264
265 // ========== Batch Operations ==========
266
271 void BeginBatch();
272
276 void EndBatch();
277
281 bool InBatch() const { return batch_depth_ > 0; }
282
283 private:
284 PaletteManager() = default;
285 ~PaletteManager() = default;
286
288 PaletteGroup* GetMutableGroup(const std::string& group_name);
289
291 const PaletteGroup* GetGroup(const std::string& group_name) const;
292
294 SnesColor GetOriginalColor(const std::string& group_name, int palette_index,
295 int color_index) const;
296
298 void RecordChange(const PaletteColorChange& change);
299
301 void NotifyListeners(const PaletteChangeEvent& event);
302
304 void MarkModified(const std::string& group_name, int palette_index,
305 int color_index);
306
308 void ClearModifiedFlags(const std::string& group_name);
309
310 // ========== Member Variables ==========
311
314
316 Rom* rom_ = nullptr;
317
320 std::unordered_map<std::string, std::vector<SnesPalette>> original_palettes_;
321
324 std::unordered_map<std::string, std::unordered_set<int>> modified_palettes_;
325
328 std::unordered_map<std::string,
329 std::unordered_map<int, std::unordered_set<int>>>
331
333 std::deque<PaletteColorChange> undo_stack_;
334 std::deque<PaletteColorChange> redo_stack_;
335 static constexpr size_t kMaxUndoHistory = 500;
336
338 std::unordered_map<int, ChangeCallback> change_listeners_;
340
343 std::vector<PaletteColorChange> batch_changes_;
344};
345
346} // namespace gfx
347} // namespace yaze
348
349#endif // YAZE_APP_GFX_PALETTE_MANAGER_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:24
Centralized palette management system.
void RecordChange(const PaletteColorChange &change)
Helper: Record a change for undo.
absl::Status SetColor(const std::string &group_name, int palette_index, int color_index, const SnesColor &new_color)
Set a color in a palette (records change for undo)
std::vector< std::string > GetModifiedGroups() const
Get list of modified palette group names.
static constexpr size_t kMaxUndoHistory
bool HasUnsavedChanges() const
Check if there are ANY unsaved changes.
bool IsGroupModified(const std::string &group_name) const
Check if a specific palette group has modifications.
absl::Status SaveGroup(const std::string &group_name)
Save a specific palette group to ROM.
void BeginBatch()
Begin a batch operation (groups multiple changes into one undo step)
PaletteGroup * GetMutableGroup(const std::string &group_name)
Helper: Get mutable palette group.
size_t GetUndoStackSize() const
Get size of undo stack.
void Undo()
Undo the most recent change.
size_t GetRedoStackSize() const
Get size of redo stack.
void ClearHistory()
Clear undo/redo history.
std::unordered_map< int, ChangeCallback > change_listeners_
Change listeners.
int batch_depth_
Batch operation support.
std::deque< PaletteColorChange > redo_stack_
std::unordered_map< std::string, std::unordered_set< int > > modified_palettes_
void UnregisterChangeListener(int callback_id)
Unregister a change listener.
Rom * rom_
ROM instance (not owned) - legacy, used when game_data_ is null.
std::unordered_map< std::string, std::unordered_map< int, std::unordered_set< int > > > modified_colors_
bool CanRedo() const
Check if redo is available.
bool InBatch() const
Check if currently in a batch operation.
bool CanUndo() const
Check if undo is available.
void Initialize(zelda3::GameData *game_data)
Initialize the palette manager with GameData.
void ResetForTesting()
Reset all state for test isolation.
absl::Status ResetColor(const std::string &group_name, int palette_index, int color_index)
Reset a single color to its original ROM value.
void NotifyListeners(const PaletteChangeEvent &event)
Helper: Notify all listeners of an event.
void ClearModifiedFlags(const std::string &group_name)
Helper: Clear modified flags for a group.
void EndBatch()
End a batch operation.
int RegisterChangeListener(ChangeCallback callback)
Register a callback for palette change events.
PaletteManager(PaletteManager &&)=delete
std::deque< PaletteColorChange > undo_stack_
Undo/redo stacks.
absl::Status ResetPalette(const std::string &group_name, int palette_index)
Reset an entire palette to original ROM values.
SnesColor GetOriginalColor(const std::string &group_name, int palette_index, int color_index) const
Helper: Get original color from snapshot.
PaletteManager & operator=(const PaletteManager &)=delete
bool IsColorModified(const std::string &group_name, int palette_index, int color_index) const
Check if a specific color is modified.
void MarkModified(const std::string &group_name, int palette_index, int color_index)
Helper: Mark a color as modified.
void DiscardGroup(const std::string &group_name)
Discard changes for a specific group.
bool IsInitialized() const
Check if manager is initialized.
zelda3::GameData * game_data_
GameData instance (not owned) - preferred.
void DiscardAllChanges()
Discard ALL unsaved changes.
size_t GetModifiedColorCount() const
Get count of modified colors across all groups.
std::unordered_map< std::string, std::vector< SnesPalette > > original_palettes_
PaletteManager & operator=(PaletteManager &&)=delete
std::vector< PaletteColorChange > batch_changes_
static PaletteManager & Get()
Get the singleton instance.
PaletteManager(const PaletteManager &)=delete
const PaletteGroup * GetGroup(const std::string &group_name) const
Helper: Get const palette group.
SnesColor GetColor(const std::string &group_name, int palette_index, int color_index) const
Get a color from a palette.
std::function< void(const PaletteChangeEvent &)> ChangeCallback
absl::Status SaveAllToRom()
Save ALL modified palettes to ROM.
bool IsPaletteModified(const std::string &group_name, int palette_index) const
Check if a specific palette is modified.
absl::Status ApplyPreviewChanges()
Apply preview changes to other editors without saving to ROM.
void Redo()
Redo the most recently undone change.
SNES Color container.
Definition snes_color.h:110
Event notification for palette changes.
@ kColorChanged
Single color was modified.
@ kPaletteReset
Entire palette was reset.
@ kAllDiscarded
All changes discarded.
@ kGroupDiscarded
Palette group changes were discarded.
@ kAllSaved
All changes saved to ROM.
@ kGroupSaved
Palette group was saved to ROM.
Represents a single color change operation.
SnesColor new_color
New color after change.
int color_index
Index of color within palette.
std::string group_name
Palette group name (e.g., "ow_main")
int palette_index
Index of palette within group.
uint64_t timestamp_ms
Timestamp in milliseconds.
SnesColor original_color
Original color before change.
Represents a group of palettes.