yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
content_registry.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <memory>
5#include <mutex>
6#include <string>
7#include <unordered_map>
8#include <vector>
9
10#include "app/editor/editor.h"
17#include "core/project.h"
18#include "rom/rom.h"
19#include "zelda3/game_data.h"
20
21namespace yaze::editor {
22
23namespace {
24
25// Singleton storage for ContentRegistry state
26// Uses lazy initialization to avoid static initialization order issues
28 std::mutex mutex;
29
30 // When global_context is set, Context delegates to it.
31 // The raw pointers below are fallback storage used only before
32 // GlobalEditorContext is wired in (early startup / tests).
33 GlobalEditorContext* global_context = nullptr;
34
35 Rom* current_rom = nullptr;
36 ::yaze::EventBus* event_bus = nullptr;
37 Editor* current_editor = nullptr;
38 std::unordered_map<std::string, Editor*> current_window_editors;
39 ::yaze::zelda3::GameData* game_data = nullptr;
40 ::yaze::project::YazeProject* current_project = nullptr;
41 workflow::HackWorkflowBackend* hack_workflow_backend = nullptr;
42 UserSettings* user_settings = nullptr;
43 LayoutManager* layout_manager = nullptr;
46 std::string build_workflow_log;
47 std::vector<ProjectWorkflowHistoryEntry> workflow_history;
48 std::function<void()> start_build_workflow_callback;
49 std::function<void()> run_project_workflow_callback;
50 std::function<void()> show_workflow_output_callback;
51 std::function<void()> cancel_build_workflow_callback;
52 std::vector<std::unique_ptr<WindowContent>> panels;
53 std::vector<ContentRegistry::Panels::PanelFactory> factories;
54 std::vector<ContentRegistry::Editors::EditorFactory> editor_factories;
55 std::vector<ContentRegistry::Shortcuts::ShortcutDef> shortcuts;
56 std::vector<ContentRegistry::WorkflowActions::ActionDef> workflow_actions;
57 std::vector<ContentRegistry::Settings::SettingDef> settings;
58
59 static RegistryState& Get() {
60 static RegistryState instance;
61 return instance;
62 }
63};
64
65} // namespace
66
67// =============================================================================
68// Context Implementation
69// =============================================================================
70
71namespace ContentRegistry {
72
73namespace Context {
74
76 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
77 RegistryState::Get().global_context = ctx;
78}
79
80Rom* rom() {
81 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
82 auto& state = RegistryState::Get();
83 if (state.global_context)
84 return state.global_context->GetCurrentRom();
85 return state.current_rom;
86}
87
88void SetRom(Rom* rom) {
89 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
90 auto& state = RegistryState::Get();
91 if (state.global_context) {
92 state.global_context->SetCurrentRom(rom);
93 }
94 state.current_rom = rom; // keep fallback in sync
95}
96
98 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
99 auto& state = RegistryState::Get();
100 if (state.global_context)
101 return &state.global_context->GetEventBus();
102 return state.event_bus;
103}
104
106 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
107 auto& state = RegistryState::Get();
108 // EventBus in GlobalEditorContext is a reference set at construction,
109 // so we don't update it here. Just keep fallback in sync.
110 state.event_bus = bus;
111}
112
114 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
115 auto& state = RegistryState::Get();
116 if (state.global_context)
117 return state.global_context->GetCurrentEditor();
118 return state.current_editor;
119}
120
122 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
123 auto& state = RegistryState::Get();
124 if (state.global_context) {
125 state.global_context->SetCurrentEditor(editor);
126 }
127 state.current_editor = editor;
128}
129
130Editor* editor_window_context(const std::string& category) {
131 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
132 auto& state = RegistryState::Get();
133 auto it = state.current_window_editors.find(category);
134 return it != state.current_window_editors.end() ? it->second : nullptr;
135}
136
137void SetEditorWindowContext(const std::string& category, Editor* editor) {
138 if (category.empty()) {
139 return;
140 }
141 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
142 RegistryState::Get().current_window_editors[category] = editor;
143}
144
146 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
147 auto& state = RegistryState::Get();
148 if (state.global_context)
149 return state.global_context->GetGameData();
150 return state.game_data;
151}
152
154 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
155 auto& state = RegistryState::Get();
156 if (state.global_context) {
157 state.global_context->SetGameData(data);
158 }
159 state.game_data = data;
160}
161
163 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
164 auto& state = RegistryState::Get();
165 if (state.global_context)
166 return state.global_context->GetCurrentProject();
167 return state.current_project;
168}
169
171 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
172 auto& state = RegistryState::Get();
173 if (state.global_context) {
174 state.global_context->SetCurrentProject(project);
175 }
176 state.current_project = project;
177}
178
180 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
181 return RegistryState::Get().user_settings;
182}
183
185 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
186 RegistryState::Get().user_settings = settings;
187}
188
190 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
191 return RegistryState::Get().layout_manager;
192}
193
195 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
196 RegistryState::Get().layout_manager = manager;
197}
198
200 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
201 return RegistryState::Get().hack_workflow_backend;
202}
203
205 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
206 return dynamic_cast<workflow::ValidationCapability*>(
207 RegistryState::Get().hack_workflow_backend);
208}
209
211 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
212 return dynamic_cast<workflow::ProgressionCapability*>(
213 RegistryState::Get().hack_workflow_backend);
214}
215
217 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
218 return dynamic_cast<workflow::PlanningCapability*>(
219 RegistryState::Get().hack_workflow_backend);
220}
221
223 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
224 RegistryState::Get().hack_workflow_backend = backend;
225}
226
228 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
229 return RegistryState::Get().build_workflow_status;
230}
231
233 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
234 RegistryState::Get().build_workflow_status = status;
235}
236
238 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
239 return RegistryState::Get().run_workflow_status;
240}
241
243 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
244 RegistryState::Get().run_workflow_status = status;
245}
246
247std::string build_workflow_log() {
248 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
249 return RegistryState::Get().build_workflow_log;
250}
251
252void SetBuildWorkflowLog(const std::string& output) {
253 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
254 RegistryState::Get().build_workflow_log = output;
255}
256
257std::vector<ProjectWorkflowHistoryEntry> workflow_history() {
258 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
259 return RegistryState::Get().workflow_history;
260}
261
263 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
264 auto& history = RegistryState::Get().workflow_history;
265 history.insert(history.begin(), entry);
266 constexpr size_t kMaxEntries = 20;
267 if (history.size() > kMaxEntries) {
268 history.resize(kMaxEntries);
269 }
270}
271
273 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
274 RegistryState::Get().workflow_history.clear();
275}
276
277std::function<void()> start_build_workflow_callback() {
278 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
279 return RegistryState::Get().start_build_workflow_callback;
280}
281
282void SetStartBuildWorkflowCallback(std::function<void()> callback) {
283 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
284 RegistryState::Get().start_build_workflow_callback = std::move(callback);
285}
286
287std::function<void()> run_project_workflow_callback() {
288 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
289 return RegistryState::Get().run_project_workflow_callback;
290}
291
292void SetRunProjectWorkflowCallback(std::function<void()> callback) {
293 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
294 RegistryState::Get().run_project_workflow_callback = std::move(callback);
295}
296
297std::function<void()> show_workflow_output_callback() {
298 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
299 return RegistryState::Get().show_workflow_output_callback;
300}
301
302void SetShowWorkflowOutputCallback(std::function<void()> callback) {
303 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
304 RegistryState::Get().show_workflow_output_callback = std::move(callback);
305}
306
307std::function<void()> cancel_build_workflow_callback() {
308 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
309 return RegistryState::Get().cancel_build_workflow_callback;
310}
311
312void SetCancelBuildWorkflowCallback(std::function<void()> callback) {
313 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
314 RegistryState::Get().cancel_build_workflow_callback = std::move(callback);
315}
316
317void Clear() {
318 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
319 auto& state = RegistryState::Get();
320 if (state.global_context) {
321 state.global_context->Clear();
322 }
323 state.current_rom = nullptr;
324 state.event_bus = nullptr;
325 state.current_editor = nullptr;
326 state.game_data = nullptr;
327 state.current_project = nullptr;
328 state.hack_workflow_backend = nullptr;
329 state.user_settings = nullptr;
330 state.layout_manager = nullptr;
331 state.current_window_editors.clear();
332 state.build_workflow_status = ProjectWorkflowStatus{};
333 state.run_workflow_status = ProjectWorkflowStatus{};
334 state.build_workflow_log.clear();
335 state.workflow_history.clear();
336 state.start_build_workflow_callback = nullptr;
337 state.run_project_workflow_callback = nullptr;
338 state.show_workflow_output_callback = nullptr;
339 state.cancel_build_workflow_callback = nullptr;
340}
341
342} // namespace Context
343
344// =============================================================================
345// Panels Implementation
346// =============================================================================
347
348namespace Panels {
349
351 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
352 RegistryState::Get().factories.push_back(std::move(factory));
353}
354
355std::vector<std::unique_ptr<WindowContent>> CreateAll() {
356 std::vector<PanelFactory> factories;
357 {
358 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
359 factories = RegistryState::Get().factories;
360 }
361
362 std::vector<std::unique_ptr<WindowContent>> result;
363 result.reserve(factories.size());
364
365 for (const auto& factory : factories) {
366 if (auto panel = factory()) {
367 result.push_back(std::move(panel));
368 }
369 }
370 return result;
371}
372
373void Register(std::unique_ptr<WindowContent> panel) {
374 if (!panel)
375 return;
376
377 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
378 RegistryState::Get().panels.push_back(std::move(panel));
379}
380
381std::vector<WindowContent*> GetAll() {
382 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
383
384 std::vector<WindowContent*> result;
385 result.reserve(RegistryState::Get().panels.size());
386
387 for (const auto& panel : RegistryState::Get().panels) {
388 result.push_back(panel.get());
389 }
390
391 return result;
392}
393
394WindowContent* Get(const std::string& id) {
395 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
396
397 for (const auto& panel : RegistryState::Get().panels) {
398 if (panel->GetId() == id) {
399 return panel.get();
400 }
401 }
402
403 return nullptr;
404}
405
406void Clear() {
407 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
408 RegistryState::Get().panels.clear();
409}
410
411} // namespace Panels
412
413// =============================================================================
414// Editors Implementation
415// =============================================================================
416
417namespace Editors {
418
420 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
421 RegistryState::Get().editor_factories.push_back(std::move(factory));
422}
423
424std::vector<std::unique_ptr<Editor>> CreateAll(const EditorDependencies& deps) {
425 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
426 std::vector<std::unique_ptr<Editor>> result;
427 result.reserve(RegistryState::Get().editor_factories.size());
428
429 for (const auto& factory : RegistryState::Get().editor_factories) {
430 if (auto editor = factory(deps)) {
431 result.push_back(std::move(editor));
432 }
433 }
434 return result;
435}
436
437} // namespace Editors
438
439// =============================================================================
440// Shortcuts Implementation
441// =============================================================================
442
443namespace Shortcuts {
444
445void Register(const ShortcutDef& shortcut) {
446 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
447 RegistryState::Get().shortcuts.push_back(shortcut);
448}
449
450void add(const std::string& id, const std::string& key,
451 const std::string& desc) {
452 Register({id, key, desc});
453}
454
455std::vector<ShortcutDef> GetAll() {
456 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
457 return RegistryState::Get().shortcuts;
458}
459
460} // namespace Shortcuts
461
462// =============================================================================
463// WorkflowActions Implementation
464// =============================================================================
465
466namespace WorkflowActions {
467
468void Register(const ActionDef& action) {
469 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
470 auto& actions = RegistryState::Get().workflow_actions;
471 auto it = std::find_if(
472 actions.begin(), actions.end(),
473 [&](const ActionDef& existing) { return existing.id == action.id; });
474 if (it != actions.end()) {
475 *it = action;
476 return;
477 }
478 actions.push_back(action);
479}
480
481std::vector<ActionDef> GetAll() {
482 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
483 return RegistryState::Get().workflow_actions;
484}
485
486void Clear() {
487 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
488 RegistryState::Get().workflow_actions.clear();
489}
490
491} // namespace WorkflowActions
492
493// =============================================================================
494// Settings Implementation
495// =============================================================================
496
497namespace Settings {
498
499void Register(const SettingDef& setting) {
500 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
501 RegistryState::Get().settings.push_back(setting);
502}
503
504void add(const std::string& section, const std::string& key,
505 const std::string& default_val, const std::string& desc) {
506 Register({key, section, default_val, desc});
507}
508
509std::vector<SettingDef> GetAll() {
510 std::lock_guard<std::mutex> lock(RegistryState::Get().mutex);
511 return RegistryState::Get().settings;
512}
513
514} // namespace Settings
515
516} // namespace ContentRegistry
517
518} // namespace yaze::editor
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
Interface for editor classes.
Definition editor.h:245
Instance-based runtime context replacing ContentRegistry::Context.
Manages ImGui DockBuilder layouts for each editor type.
Manages user preferences and settings persistence.
Base interface for all logical window content components.
std::vector< ProjectWorkflowHistoryEntry > workflow_history()
void SetGlobalContext(GlobalEditorContext *ctx)
void SetShowWorkflowOutputCallback(std::function< void()> callback)
void SetEditorWindowContext(const std::string &category, Editor *editor)
Rom * rom()
Get the current ROM instance.
void SetEventBus(::yaze::EventBus *bus)
Set the current EventBus instance.
::yaze::EventBus * event_bus()
Get the current EventBus instance.
void SetRom(Rom *rom)
Set the current ROM instance.
void SetGameData(::yaze::zelda3::GameData *data)
Set the current game data instance.
void AppendWorkflowHistory(const ProjectWorkflowHistoryEntry &entry)
UserSettings * user_settings()
Get the current UserSettings instance.
Editor * current_editor()
Get the currently active editor.
void SetRunProjectWorkflowCallback(std::function< void()> callback)
LayoutManager * layout_manager()
Get the shared LayoutManager instance.
void SetBuildWorkflowStatus(const ProjectWorkflowStatus &status)
void SetCancelBuildWorkflowCallback(std::function< void()> callback)
std::function< void()> cancel_build_workflow_callback()
void SetCurrentEditor(Editor *editor)
Set the currently active editor.
::yaze::zelda3::GameData * game_data()
Get the current game data instance.
void SetLayoutManager(LayoutManager *manager)
ProjectWorkflowStatus build_workflow_status()
workflow::PlanningCapability * hack_planning_backend()
::yaze::project::YazeProject * current_project()
Get the current project instance.
void SetBuildWorkflowLog(const std::string &output)
void SetStartBuildWorkflowCallback(std::function< void()> callback)
void SetRunWorkflowStatus(const ProjectWorkflowStatus &status)
workflow::ValidationCapability * hack_validation_backend()
std::function< void()> run_project_workflow_callback()
void SetHackWorkflowBackend(workflow::HackWorkflowBackend *backend)
void SetUserSettings(UserSettings *settings)
void Clear()
Clear all context state.
workflow::HackWorkflowBackend * hack_workflow_backend()
std::function< void()> show_workflow_output_callback()
std::function< void()> start_build_workflow_callback()
Editor * editor_window_context(const std::string &category)
workflow::ProgressionCapability * hack_progression_backend()
void SetCurrentProject(::yaze::project::YazeProject *project)
Set the current project instance.
void RegisterFactory(EditorFactory factory)
std::function< std::unique_ptr< Editor >(const EditorDependencies &)> EditorFactory
std::vector< std::unique_ptr< Editor > > CreateAll(const EditorDependencies &deps)
void Clear()
Clear all registered panels.
void Register(std::unique_ptr< WindowContent > panel)
Register a panel instance (Legacy/Global).
std::vector< WindowContent * > GetAll()
Get all registered panels.
WindowContent * Get(const std::string &id)
Get a specific panel by its ID.
std::function< std::unique_ptr< WindowContent >()> PanelFactory
void RegisterFactory(PanelFactory factory)
Register a panel factory.
std::vector< std::unique_ptr< WindowContent > > CreateAll()
Create new instances of all registered panels.
void Register(const SettingDef &setting)
void add(const std::string &section, const std::string &key, const std::string &default_val, const std::string &desc)
void add(const std::string &id, const std::string &key, const std::string &desc)
void Register(const ShortcutDef &shortcut)
Editors are the view controllers for the application.
Unified dependency container for all editor types.
Definition editor.h:169
std::unordered_map< std::string, Editor * > current_window_editors
std::vector< ContentRegistry::Shortcuts::ShortcutDef > shortcuts
std::vector< ContentRegistry::Panels::PanelFactory > factories
std::vector< ContentRegistry::WorkflowActions::ActionDef > workflow_actions
std::vector< ContentRegistry::Editors::EditorFactory > editor_factories
std::vector< ContentRegistry::Settings::SettingDef > settings
Modern project structure with comprehensive settings consolidation.
Definition project.h:172