diff --git a/src/app/core/controller.cc b/src/app/core/controller.cc index 6d91be00..71173394 100644 --- a/src/app/core/controller.cc +++ b/src/app/core/controller.cc @@ -7,7 +7,7 @@ #include "app/editor/editor_manager.h" #include "app/gui/background_renderer.h" #include "app/gui/theme_manager.h" -#include "app/gui/widget_id_registry.h" +#include "app/gui/widgets/widget_id_registry.h" #include "imgui/backends/imgui_impl_sdl2.h" #include "imgui/backends/imgui_impl_sdlrenderer2.h" #include "imgui/imgui.h" diff --git a/src/app/core/core_library.cmake b/src/app/core/core_library.cmake index ef73bdf6..3598809a 100644 --- a/src/app/core/core_library.cmake +++ b/src/app/core/core_library.cmake @@ -10,13 +10,11 @@ set( if (WIN32 OR MINGW OR (UNIX AND NOT APPLE)) list(APPEND YAZE_APP_CORE_SRC app/core/platform/font_loader.cc - app/core/platform/file_dialog.cc ) endif() if(APPLE) list(APPEND YAZE_APP_CORE_SRC - app/core/platform/file_dialog.cc app/core/platform/file_dialog.mm app/core/platform/app_delegate.mm app/core/platform/font_loader.cc diff --git a/src/app/core/platform/app_delegate.mm b/src/app/core/platform/app_delegate.mm index 68868ee7..4a2940b6 100644 --- a/src/app/core/platform/app_delegate.mm +++ b/src/app/core/platform/app_delegate.mm @@ -208,7 +208,7 @@ - (void)openFileAction:(id)sender { // TODO: Re-implmenent this without the SharedRom singleton // if (!yaze::SharedRom::shared_rom_ - // ->LoadFromFile(yaze::core::FileDialogWrapper::ShowOpenFileDialog()) + // ->LoadFromFile(yaze::util::FileDialogWrapper::ShowOpenFileDialog()) // .ok()) { // NSAlert *alert = [[NSAlert alloc] init]; // [alert setMessageText:@"Error"]; diff --git a/src/app/core/platform/file_dialog.mm b/src/app/core/platform/file_dialog.mm index 8dc27b58..781469ad 100644 --- a/src/app/core/platform/file_dialog.mm +++ b/src/app/core/platform/file_dialog.mm @@ -1,4 +1,4 @@ -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include #include @@ -46,21 +46,21 @@ std::string ShowOpenFileDialogSync() { } } // namespace -std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() { return ShowOpenFileDialogSync(); } +std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() { return ShowOpenFileDialogSync(); } -std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() { return ""; } +std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() { return ""; } -std::vector yaze::core::FileDialogWrapper::GetFilesInFolder( +std::vector yaze::util::FileDialogWrapper::GetFilesInFolder( const std::string &folder) { return {}; } -std::vector yaze::core::FileDialogWrapper::GetSubdirectoriesInFolder( +std::vector yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder( const std::string &folder) { return {}; } -std::string yaze::core::GetBundleResourcePath() { +std::string yaze::util::GetBundleResourcePath() { NSBundle* bundle = [NSBundle mainBundle]; NSString* resourceDirectoryPath = [bundle bundlePath]; NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"]; @@ -73,7 +73,7 @@ std::string yaze::core::GetBundleResourcePath() { #import #import -std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogBespoke() { +std::string yaze::util::FileDialogWrapper::ShowOpenFileDialogBespoke() { NSOpenPanel* openPanel = [NSOpenPanel openPanel]; [openPanel setCanChooseFiles:YES]; [openPanel setCanChooseDirectories:NO]; @@ -88,7 +88,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogBespoke() { return ""; } -std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name, +std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name, const std::string& default_extension) { NSSavePanel* savePanel = [NSSavePanel savePanel]; @@ -111,7 +111,7 @@ std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogBespoke(const std:: } // Global feature flag-based dispatch methods -std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() { +std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() { if (FeatureFlags::get().kUseNativeFileDialog) { return ShowOpenFileDialogNFD(); } else { @@ -119,7 +119,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialog() { } } -std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() { +std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() { if (FeatureFlags::get().kUseNativeFileDialog) { return ShowOpenFolderDialogNFD(); } else { @@ -127,7 +127,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialog() { } } -std::string yaze::core::FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name, +std::string yaze::util::FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name, const std::string& default_extension) { if (FeatureFlags::get().kUseNativeFileDialog) { return ShowSaveFileDialogNFD(default_name, default_extension); @@ -137,7 +137,7 @@ std::string yaze::core::FileDialogWrapper::ShowSaveFileDialog(const std::string& } // NFD implementation for macOS (fallback to bespoke if NFD not available) -std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogNFD() { +std::string yaze::util::FileDialogWrapper::ShowOpenFileDialogNFD() { #if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD NFD_Init(); nfdu8char_t *out_path = NULL; @@ -164,7 +164,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFileDialogNFD() { #endif } -std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogNFD() { +std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialogNFD() { #if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD NFD_Init(); nfdu8char_t *out_path = NULL; @@ -187,7 +187,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogNFD() { #endif } -std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name, +std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name, const std::string& default_extension) { #if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD NFD_Init(); @@ -236,7 +236,7 @@ std::string yaze::core::FileDialogWrapper::ShowSaveFileDialogNFD(const std::stri #endif } -std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogBespoke() { +std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialogBespoke() { NSOpenPanel* openPanel = [NSOpenPanel openPanel]; [openPanel setCanChooseFiles:NO]; [openPanel setCanChooseDirectories:YES]; @@ -251,7 +251,7 @@ std::string yaze::core::FileDialogWrapper::ShowOpenFolderDialogBespoke() { return ""; } -std::vector yaze::core::FileDialogWrapper::GetFilesInFolder( +std::vector yaze::util::FileDialogWrapper::GetFilesInFolder( const std::string& folder) { std::vector filenames; NSFileManager* fileManager = [NSFileManager defaultManager]; @@ -267,7 +267,7 @@ std::vector yaze::core::FileDialogWrapper::GetFilesInFolder( return filenames; } -std::vector yaze::core::FileDialogWrapper::GetSubdirectoriesInFolder( +std::vector yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder( const std::string& folder) { std::vector subdirectories; NSFileManager* fileManager = [NSFileManager defaultManager]; @@ -289,7 +289,7 @@ std::vector yaze::core::FileDialogWrapper::GetSubdirectoriesInFolde return subdirectories; } -std::string yaze::core::GetBundleResourcePath() { +std::string yaze::util::GetBundleResourcePath() { NSBundle* bundle = [NSBundle mainBundle]; NSString* resourceDirectoryPath = [bundle bundlePath]; NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"]; diff --git a/src/app/core/platform/font_loader.cc b/src/app/core/platform/font_loader.cc index d85e7c84..4f0fc7f6 100644 --- a/src/app/core/platform/font_loader.cc +++ b/src/app/core/platform/font_loader.cc @@ -9,7 +9,7 @@ #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gui/icons.h" #include "imgui/imgui.h" #include "util/macro.h" @@ -33,10 +33,10 @@ namespace { std::string SetFontPath(const std::string& font_path) { #ifdef __APPLE__ #if TARGET_OS_IOS == 1 - const std::string kBundlePath = GetBundleResourcePath(); + const std::string kBundlePath = util::GetBundleResourcePath(); return kBundlePath + font_path; #else - return absl::StrCat(GetBundleResourcePath(), "Contents/Resources/font/", + return absl::StrCat(util::GetBundleResourcePath(), "Contents/Resources/font/", font_path); #endif #else diff --git a/src/app/core/project.cc b/src/app/core/project.cc index c611fe7e..d7d3ee54 100644 --- a/src/app/core/project.cc +++ b/src/app/core/project.cc @@ -9,7 +9,7 @@ #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" #include "absl/strings/str_split.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gui/icons.h" #include "app/zelda3/zelda3_labels.h" #include "imgui/imgui.h" diff --git a/src/app/core/service/widget_discovery_service.h b/src/app/core/service/widget_discovery_service.h index 0b5dc0e6..289b3937 100644 --- a/src/app/core/service/widget_discovery_service.h +++ b/src/app/core/service/widget_discovery_service.h @@ -6,7 +6,7 @@ #include "absl/strings/string_view.h" #include "app/core/proto/imgui_test_harness.pb.h" -#include "app/gui/widget_id_registry.h" +#include "app/gui/widgets/widget_id_registry.h" #if defined(YAZE_ENABLE_IMGUI_TEST_ENGINE) && YAZE_ENABLE_IMGUI_TEST_ENGINE #include "imgui_test_engine/imgui_te_context.h" diff --git a/src/app/core/window.cc b/src/app/core/window.cc index ab6546c2..5be3cd12 100644 --- a/src/app/core/window.cc +++ b/src/app/core/window.cc @@ -3,7 +3,7 @@ #include "absl/status/status.h" #include "absl/strings/str_format.h" #include "app/core/platform/font_loader.h" -#include "app/core/platform/sdl_deleter.h" +#include "util/sdl_deleter.h" #include "app/gfx/arena.h" #include "app/gui/style.h" #include "app/gui/theme_manager.h" diff --git a/src/app/core/window.h b/src/app/core/window.h index 53d2d6b1..7093bf72 100644 --- a/src/app/core/window.h +++ b/src/app/core/window.h @@ -7,7 +7,7 @@ #include "absl/status/status.h" #include "absl/strings/str_format.h" -#include "app/core/platform/sdl_deleter.h" +#include "util/sdl_deleter.h" #include "app/gfx/bitmap.h" namespace yaze { diff --git a/src/app/editor/agent/agent_chat_widget.cc b/src/app/editor/agent/agent_chat_widget.cc index 325b02f3..71375cc6 100644 --- a/src/app/editor/agent/agent_chat_widget.cc +++ b/src/app/editor/agent/agent_chat_widget.cc @@ -14,7 +14,7 @@ #include "absl/strings/str_format.h" #include "absl/time/clock.h" #include "absl/time/time.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/editor/agent/agent_chat_history_codec.h" #include "app/editor/system/proposal_drawer.h" #include "app/editor/system/toast_manager.h" @@ -48,7 +48,7 @@ std::filesystem::path ExpandUserPath(std::string path) { } std::filesystem::path ResolveHistoryPath(const std::string& session_id = "") { - std::filesystem::path base = ExpandUserPath(yaze::core::GetConfigDirectory()); + std::filesystem::path base = ExpandUserPath(yaze::util::GetConfigDirectory()); if (base.empty()) { base = ExpandUserPath(".yaze"); } @@ -1723,7 +1723,7 @@ void AgentChatWidget::RenderSystemPromptEditor() { // Save the current system prompt to project directory for (auto& tab : open_files_) { if (tab.is_system_prompt) { - auto save_path = core::FileDialogWrapper::ShowSaveFileDialog( + auto save_path = util::FileDialogWrapper::ShowSaveFileDialog( "custom_system_prompt", "txt"); if (!save_path.empty()) { std::ofstream file(save_path); @@ -1760,7 +1760,7 @@ void AgentChatWidget::RenderSystemPromptEditor() { ImGui::SameLine(); if (ImGui::Button(ICON_MD_FOLDER_OPEN " Load Custom")) { - auto filepath = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filepath = util::FileDialogWrapper::ShowOpenFileDialog(); if (!filepath.empty()) { std::ifstream file(filepath); if (file.is_open()) { @@ -1832,7 +1832,7 @@ void AgentChatWidget::RenderFileEditorTabs() { } ImGui::SameLine(); if (ImGui::Button(ICON_MD_FOLDER_OPEN " Open File")) { - auto filepath = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filepath = util::FileDialogWrapper::ShowOpenFileDialog(); if (!filepath.empty()) { OpenFileInEditor(filepath); } @@ -1890,7 +1890,7 @@ void AgentChatWidget::RenderFileEditorTabs() { toast_manager_->Show("Failed to save file", ToastType::kError); } } else { - auto save_path = core::FileDialogWrapper::ShowSaveFileDialog( + auto save_path = util::FileDialogWrapper::ShowSaveFileDialog( open_files_[i].filename, ""); if (!save_path.empty()) { std::ofstream file(save_path); diff --git a/src/app/editor/agent/agent_collaboration_coordinator.cc b/src/app/editor/agent/agent_collaboration_coordinator.cc index 0b3c636d..dba75fd6 100644 --- a/src/app/editor/agent/agent_collaboration_coordinator.cc +++ b/src/app/editor/agent/agent_collaboration_coordinator.cc @@ -17,7 +17,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/strip.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "util/macro.h" namespace yaze { diff --git a/src/app/editor/code/assembly_editor.cc b/src/app/editor/code/assembly_editor.cc index 44b1fd7f..6f1e3888 100644 --- a/src/app/editor/code/assembly_editor.cc +++ b/src/app/editor/code/assembly_editor.cc @@ -6,13 +6,13 @@ #include "absl/strings/str_cat.h" #include "absl/strings/match.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gui/icons.h" #include "app/gui/modules/text_editor.h" namespace yaze::editor { -using core::FileDialogWrapper; +using util::FileDialogWrapper; namespace { @@ -283,7 +283,7 @@ void AssemblyEditor::DrawFileTabView() { void AssemblyEditor::DrawFileMenu() { if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("Open", "Ctrl+O")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); ChangeActiveFile(filename); } if (ImGui::MenuItem("Save", "Ctrl+S")) { diff --git a/src/app/editor/code/memory_editor.h b/src/app/editor/code/memory_editor.h index 04dc1657..b5c33c30 100644 --- a/src/app/editor/code/memory_editor.h +++ b/src/app/editor/code/memory_editor.h @@ -1,7 +1,7 @@ #ifndef YAZE_APP_EDITOR_CODE_MEMORY_EDITOR_H #define YAZE_APP_EDITOR_CODE_MEMORY_EDITOR_H -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gui/input.h" #include "app/rom.h" #include "app/snes.h" @@ -25,7 +25,7 @@ struct MemoryEditorWithDiffChecker { static Rom comparison_rom; ImGui::Begin("Hex Editor", &show_memory_editor); if (ImGui::Button("Compare Rom")) { - auto file_name = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file_name = util::FileDialogWrapper::ShowOpenFileDialog(); PRINT_IF_ERROR(comparison_rom.LoadFromFile(file_name)); show_compare_rom = true; } diff --git a/src/app/editor/code/project_file_editor.cc b/src/app/editor/code/project_file_editor.cc index 286c43cb..10618294 100644 --- a/src/app/editor/code/project_file_editor.cc +++ b/src/app/editor/code/project_file_editor.cc @@ -6,7 +6,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_format.h" #include "absl/strings/str_split.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/editor/system/toast_manager.h" #include "app/gui/icons.h" #include "imgui/imgui.h" @@ -40,7 +40,7 @@ void ProjectFileEditor::Draw() { ImGui::TableNextColumn(); if (ImGui::Button(absl::StrFormat("%s Open", ICON_MD_FOLDER_OPEN).c_str())) { - auto file = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file = util::FileDialogWrapper::ShowOpenFileDialog(); if (!file.empty()) { auto status = LoadFile(file); if (!status.ok() && toast_manager_) { @@ -65,7 +65,7 @@ void ProjectFileEditor::Draw() { ImGui::TableNextColumn(); if (ImGui::Button(absl::StrFormat("%s Save As", ICON_MD_SAVE_AS).c_str())) { - auto file = core::FileDialogWrapper::ShowSaveFileDialog( + auto file = util::FileDialogWrapper::ShowSaveFileDialog( filepath_.empty() ? "project" : filepath_, "yaze"); if (!file.empty()) { auto status = SaveFileAs(file); diff --git a/src/app/editor/editor_manager.cc b/src/app/editor/editor_manager.cc index 7e3ce6d1..cfacc27a 100644 --- a/src/app/editor/editor_manager.cc +++ b/src/app/editor/editor_manager.cc @@ -11,7 +11,7 @@ #include "absl/strings/match.h" #include "absl/strings/str_cat.h" #include "app/core/features.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/project.h" #include "app/editor/code/assembly_editor.h" #include "app/editor/dungeon/dungeon_editor.h" @@ -62,7 +62,7 @@ namespace yaze { namespace editor { using namespace ImGui; -using core::FileDialogWrapper; +using util::FileDialogWrapper; namespace { @@ -1620,7 +1620,7 @@ void EditorManager::DrawMenuBar() { gui::kDefaultModalSize)) { // Use save file dialog for ROM files auto file_path = - core::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "sfc"); + util::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "sfc"); if (!file_path.empty()) { save_as_filename = file_path; } @@ -1698,7 +1698,7 @@ void EditorManager::DrawMenuBar() { .c_str(), gui::kDefaultModalSize)) { auto project_file_path = - core::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "yaze"); + util::FileDialogWrapper::ShowSaveFileDialog(save_as_filename, "yaze"); if (!project_file_path.empty()) { // Ensure .yaze extension if (project_file_path.find(".yaze") == std::string::npos) { @@ -1975,7 +1975,7 @@ absl::Status EditorManager::OpenRomOrProject(const std::string& filename) { } absl::Status EditorManager::CreateNewProject(const std::string& template_name) { - auto dialog_path = core::FileDialogWrapper::ShowOpenFolderDialog(); + auto dialog_path = util::FileDialogWrapper::ShowOpenFolderDialog(); if (dialog_path.empty()) { return absl::OkStatus(); // User cancelled } @@ -1986,7 +1986,7 @@ absl::Status EditorManager::CreateNewProject(const std::string& template_name) { } absl::Status EditorManager::OpenProject() { - auto file_path = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file_path = util::FileDialogWrapper::ShowOpenFileDialog(); if (file_path.empty()) { return absl::OkStatus(); } @@ -2101,7 +2101,7 @@ absl::Status EditorManager::SaveProjectAs() { : "untitled_project"; auto file_path = - core::FileDialogWrapper::ShowSaveFileDialog(default_name, "yaze"); + util::FileDialogWrapper::ShowSaveFileDialog(default_name, "yaze"); if (file_path.empty()) { return absl::OkStatus(); } @@ -3195,7 +3195,7 @@ void EditorManager::DrawWelcomeScreen() { } ImGui::SameLine(); if (ImGui::Button(ICON_MD_FOLDER_OPEN " Open Project", ImVec2(200, 40))) { - auto file_name = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file_name = util::FileDialogWrapper::ShowOpenFileDialog(); if (!file_name.empty()) { status_ = OpenRomOrProject(file_name); if (!status_.ok()) { diff --git a/src/app/editor/graphics/graphics_editor.cc b/src/app/editor/graphics/graphics_editor.cc index 61b47810..aa3fb998 100644 --- a/src/app/editor/graphics/graphics_editor.cc +++ b/src/app/editor/graphics/graphics_editor.cc @@ -5,7 +5,7 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/window.h" #include "app/gfx/arena.h" #include "app/gfx/bitmap.h" @@ -549,7 +549,7 @@ absl::Status GraphicsEditor::DrawCgxImport() { SameLine(); if (ImGui::Button("Open CGX")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); cgx_file_name_ = filename; cgx_file_path_ = std::filesystem::absolute(filename).string(); is_open_ = true; @@ -578,7 +578,7 @@ absl::Status GraphicsEditor::DrawScrImport() { InputText("##ScrFile", &scr_file_name_); if (ImGui::Button("Open SCR")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); scr_file_name_ = filename; scr_file_path_ = std::filesystem::absolute(filename).string(); is_open_ = true; @@ -610,7 +610,7 @@ absl::Status GraphicsEditor::DrawPaletteControls() { SameLine(); if (ImGui::Button("Open COL")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); col_file_name_ = filename; col_file_path_ = std::filesystem::absolute(filename).string(); status_ = temp_rom_.LoadFromFile(col_file_path_, @@ -659,7 +659,7 @@ absl::Status GraphicsEditor::DrawObjImport() { SameLine(); if (ImGui::Button("Open OBJ")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); obj_file_path_ = std::filesystem::absolute(filename).string(); status_ = temp_rom_.LoadFromFile(obj_file_path_); is_open_ = true; @@ -677,7 +677,7 @@ absl::Status GraphicsEditor::DrawTilemapImport() { SameLine(); if (ImGui::Button("Open Tilemap")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); tilemap_file_path_ = std::filesystem::absolute(filename).string(); status_ = tilemap_rom_.LoadFromFile(tilemap_file_path_); status_ = tilemap_rom_.LoadFromFile(tilemap_file_path_); @@ -700,7 +700,7 @@ absl::Status GraphicsEditor::DrawFileImport() { SameLine(); if (ImGui::Button("Open BIN")) { - auto filename = core::FileDialogWrapper::ShowOpenFileDialog(); + auto filename = util::FileDialogWrapper::ShowOpenFileDialog(); file_path_ = filename; status_ = temp_rom_.LoadFromFile(file_path_); is_open_ = true; diff --git a/src/app/editor/graphics/screen_editor.cc b/src/app/editor/graphics/screen_editor.cc index a737e964..5399599d 100644 --- a/src/app/editor/graphics/screen_editor.cc +++ b/src/app/editor/graphics/screen_editor.cc @@ -7,7 +7,7 @@ #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "app/gfx/performance_profiler.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/window.h" #include "app/gfx/arena.h" #include "app/gfx/atlas_renderer.h" @@ -474,7 +474,7 @@ void ScreenEditor::DrawDungeonMapsEditor() { } void ScreenEditor::LoadBinaryGfx() { - std::string bin_file = core::FileDialogWrapper::ShowOpenFileDialog(); + std::string bin_file = util::FileDialogWrapper::ShowOpenFileDialog(); if (!bin_file.empty()) { std::ifstream file(bin_file, std::ios::binary); if (file.is_open()) { diff --git a/src/app/editor/message/message_editor.cc b/src/app/editor/message/message_editor.cc index f1744e81..725fa358 100644 --- a/src/app/editor/message/message_editor.cc +++ b/src/app/editor/message/message_editor.cc @@ -7,7 +7,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "app/gfx/performance_profiler.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/window.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_palette.h" @@ -243,7 +243,7 @@ void MessageEditor::DrawExpandedMessageSettings() { ImGui::Text("Expanded Messages"); static std::string expanded_message_path = ""; if (ImGui::Button("Load Expanded Message")) { - expanded_message_path = core::FileDialogWrapper::ShowOpenFileDialog(); + expanded_message_path = util::FileDialogWrapper::ShowOpenFileDialog(); if (!expanded_message_path.empty()) { if (!LoadExpandedMessages(expanded_message_path, parsed_messages_, expanded_messages_, diff --git a/src/app/editor/sprite/sprite_editor.cc b/src/app/editor/sprite/sprite_editor.cc index 47dee667..de7f0195 100644 --- a/src/app/editor/sprite/sprite_editor.cc +++ b/src/app/editor/sprite/sprite_editor.cc @@ -1,7 +1,7 @@ #include "sprite_editor.h" #include "app/gfx/performance_profiler.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/editor/sprite/zsprite.h" #include "app/gfx/arena.h" #include "app/gui/icons.h" @@ -254,7 +254,7 @@ void SpriteEditor::DrawCustomSpritesMetadata() { // ZSprite Maker format open file dialog if (ImGui::Button("Open ZSprite")) { // Open ZSprite file - std::string file_path = core::FileDialogWrapper::ShowOpenFileDialog(); + std::string file_path = util::FileDialogWrapper::ShowOpenFileDialog(); if (!file_path.empty()) { zsprite::ZSprite zsprite; status_ = zsprite.Load(file_path); diff --git a/src/app/emu/emu.cc b/src/app/emu/emu.cc index b5a27aa0..b9dc239f 100644 --- a/src/app/emu/emu.cc +++ b/src/app/emu/emu.cc @@ -11,11 +11,11 @@ #include "absl/debugging/failure_signal_handler.h" #include "absl/debugging/symbolize.h" #include "absl/status/status.h" -#include "app/core/platform/sdl_deleter.h" +#include "util/sdl_deleter.h" #include "app/emu/snes.h" #include "app/rom.h" -using yaze::core::SDL_Deleter; +using yaze::util::SDL_Deleter; int main(int argc, char **argv) { absl::InitializeSymbolizer(argv[0]); diff --git a/src/app/emu/emulator.cc b/src/app/emu/emulator.cc index b7177b34..7af89b86 100644 --- a/src/app/emu/emulator.cc +++ b/src/app/emu/emulator.cc @@ -4,7 +4,7 @@ #include #include -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/window.h" #include "app/emu/cpu/internal/opcodes.h" #include "app/gui/icons.h" @@ -316,7 +316,7 @@ void Emulator::RenderNavBar() { } if (open_file) { - auto file_name = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file_name = util::FileDialogWrapper::ShowOpenFileDialog(); if (!file_name.empty()) { std::ifstream file(file_name, std::ios::binary); // Load the data directly into rom_data diff --git a/src/app/gfx/arena.cc b/src/app/gfx/arena.cc index 64e1e6bc..947a47aa 100644 --- a/src/app/gfx/arena.cc +++ b/src/app/gfx/arena.cc @@ -2,7 +2,7 @@ #include -#include "app/core/platform/sdl_deleter.h" +#include "util/sdl_deleter.h" namespace yaze { namespace gfx { @@ -58,7 +58,7 @@ SDL_Texture* Arena::AllocateTexture(SDL_Renderer* renderer, int width, // Store in hash map with automatic cleanup textures_[texture] = - std::unique_ptr(texture); + std::unique_ptr(texture); return texture; } } @@ -146,9 +146,9 @@ void Arena::UpdateTexture(SDL_Texture* texture, SDL_Surface* surface) { // Convert surface to RGBA8888 format for texture compatibility auto converted_surface = - std::unique_ptr( + std::unique_ptr( SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0), - core::SDL_Surface_Deleter()); + util::SDL_Surface_Deleter()); if (!converted_surface) { SDL_Log("SDL_ConvertSurfaceFormat failed: %s", SDL_GetError()); @@ -228,7 +228,7 @@ SDL_Surface* Arena::AllocateSurface(int width, int height, int depth, // Store in hash map with automatic cleanup surfaces_[surface] = - std::unique_ptr(surface); + std::unique_ptr(surface); return surface; } } @@ -278,7 +278,7 @@ SDL_Texture* Arena::CreateNewTexture(SDL_Renderer* renderer, int width, int heig // Store in hash map with automatic cleanup textures_[texture] = - std::unique_ptr(texture); + std::unique_ptr(texture); return texture; } @@ -300,7 +300,7 @@ SDL_Surface* Arena::CreateNewSurface(int width, int height, int depth, int forma // Store in hash map with automatic cleanup surfaces_[surface] = - std::unique_ptr(surface); + std::unique_ptr(surface); return surface; } @@ -327,9 +327,9 @@ void Arena::UpdateTextureRegion(SDL_Texture* texture, SDL_Surface* surface, SDL_ // Convert surface to RGBA8888 format for texture compatibility auto converted_surface = - std::unique_ptr( + std::unique_ptr( SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0), - core::SDL_Surface_Deleter()); + util::SDL_Surface_Deleter()); if (!converted_surface) { return; diff --git a/src/app/gfx/arena.h b/src/app/gfx/arena.h index 9fdc87cc..73313d7b 100644 --- a/src/app/gfx/arena.h +++ b/src/app/gfx/arena.h @@ -8,7 +8,7 @@ #include #include -#include "app/core/platform/sdl_deleter.h" +#include "util/sdl_deleter.h" #include "app/gfx/background_buffer.h" namespace yaze { @@ -177,11 +177,11 @@ class Arena { std::array gfx_sheets_; std::unordered_map> + std::unique_ptr> textures_; std::unordered_map> + std::unique_ptr> surfaces_; // Resource pooling for efficient memory management diff --git a/src/app/gui/style.cc b/src/app/gui/style.cc index 4ee7ab5d..1d2df2c2 100644 --- a/src/app/gui/style.cc +++ b/src/app/gui/style.cc @@ -2,7 +2,7 @@ #include -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gui/theme_manager.h" #include "app/gui/background_renderer.h" #include "app/core/platform/font_loader.h" diff --git a/src/app/gui/theme_manager.cc b/src/app/gui/theme_manager.cc index 84452ddb..27b5a29e 100644 --- a/src/app/gui/theme_manager.cc +++ b/src/app/gui/theme_manager.cc @@ -9,7 +9,7 @@ #include "absl/strings/str_format.h" #include "absl/strings/str_split.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gui/icons.h" #include "app/gui/style.h" // For ColorsYaze function #include "imgui/imgui.h" @@ -466,7 +466,7 @@ void ThemeManager::ShowThemeSelector(bool* p_open) { ImGui::SameLine(); if (ImGui::Button(absl::StrFormat("%s Load Custom Theme", ICON_MD_FOLDER_OPEN).c_str())) { - auto file_path = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file_path = util::FileDialogWrapper::ShowOpenFileDialog(); if (!file_path.empty()) { auto status = LoadThemeFromFile(file_path); if (!status.ok()) { @@ -1007,7 +1007,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) { ApplyClassicYazeTheme(); } if (ImGui::MenuItem(absl::StrFormat("%s Load Theme", ICON_MD_FOLDER_OPEN).c_str())) { - auto file_path = core::FileDialogWrapper::ShowOpenFileDialog(); + auto file_path = util::FileDialogWrapper::ShowOpenFileDialog(); if (!file_path.empty()) { LoadThemeFromFile(file_path); } @@ -1023,7 +1023,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) { } } else { // No existing file, prompt for new location - auto file_path = core::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme"); + auto file_path = util::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme"); if (!file_path.empty()) { auto status = SaveThemeToFile(current_theme_, file_path); if (!status.ok()) { @@ -1034,7 +1034,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) { } if (ImGui::MenuItem(absl::StrFormat("%s Save As...", ICON_MD_SAVE_AS).c_str())) { // Save theme to new file - auto file_path = core::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme"); + auto file_path = util::FileDialogWrapper::ShowSaveFileDialog(current_theme_.name, "theme"); if (!file_path.empty()) { auto status = SaveThemeToFile(current_theme_, file_path); if (!status.ok()) { @@ -1859,7 +1859,7 @@ void ThemeManager::ShowSimpleThemeEditor(bool* p_open) { // Use save file dialog with proper defaults std::string safe_name = edit_theme.name.empty() ? "custom_theme" : edit_theme.name; - auto file_path = core::FileDialogWrapper::ShowSaveFileDialog(safe_name, "theme"); + auto file_path = util::FileDialogWrapper::ShowSaveFileDialog(safe_name, "theme"); if (!file_path.empty()) { // Ensure .theme extension @@ -1957,7 +1957,7 @@ std::vector ThemeManager::DiscoverAvailableThemeFiles() const { try { // Use platform-specific file discovery instead of glob #ifdef __APPLE__ - auto files_in_folder = core::FileDialogWrapper::GetFilesInFolder(search_path); + auto files_in_folder = util::FileDialogWrapper::GetFilesInFolder(search_path); for (const auto& file : files_in_folder) { if (file.length() > 6 && file.substr(file.length() - 6) == ".theme") { std::string full_path = search_path + file; diff --git a/src/app/gui/widget_auto_register.cc b/src/app/gui/widgets/widget_auto_register.cc similarity index 97% rename from src/app/gui/widget_auto_register.cc rename to src/app/gui/widgets/widget_auto_register.cc index 63c0dd8b..d4026bdc 100644 --- a/src/app/gui/widget_auto_register.cc +++ b/src/app/gui/widgets/widget_auto_register.cc @@ -1,4 +1,4 @@ -#include "app/gui/widget_auto_register.h" +#include "app/gui/widgets/widget_auto_register.h" #include diff --git a/src/app/gui/widget_auto_register.h b/src/app/gui/widgets/widget_auto_register.h similarity index 97% rename from src/app/gui/widget_auto_register.h rename to src/app/gui/widgets/widget_auto_register.h index 737401d5..ff632cc4 100644 --- a/src/app/gui/widget_auto_register.h +++ b/src/app/gui/widgets/widget_auto_register.h @@ -1,10 +1,10 @@ -#ifndef YAZE_APP_GUI_WIDGET_AUTO_REGISTER_H_ -#define YAZE_APP_GUI_WIDGET_AUTO_REGISTER_H_ +#ifndef YAZE_APP_GUI_WIDGETS_WIDGET_AUTO_REGISTER_H_ +#define YAZE_APP_GUI_WIDGETS_WIDGET_AUTO_REGISTER_H_ #include #include "imgui/imgui.h" -#include "app/gui/widget_id_registry.h" +#include "app/gui/widgets/widget_id_registry.h" #include "absl/strings/str_cat.h" /** @@ -260,5 +260,5 @@ inline void RegisterTable(const char* table_name, const std::string& description } // namespace gui } // namespace yaze -#endif // YAZE_APP_GUI_WIDGET_AUTO_REGISTER_H_ +#endif // YAZE_APP_GUI_WIDGETS_WIDGET_AUTO_REGISTER_H_ diff --git a/src/app/gui/widget_id_registry.cc b/src/app/gui/widgets/widget_id_registry.cc similarity index 99% rename from src/app/gui/widget_id_registry.cc rename to src/app/gui/widgets/widget_id_registry.cc index dfd6325f..17845ab4 100644 --- a/src/app/gui/widget_id_registry.cc +++ b/src/app/gui/widgets/widget_id_registry.cc @@ -1,4 +1,4 @@ -#include "widget_id_registry.h" +#include "app/gui/widgets/widget_id_registry.h" #include #include diff --git a/src/app/gui/widget_id_registry.h b/src/app/gui/widgets/widget_id_registry.h similarity index 97% rename from src/app/gui/widget_id_registry.h rename to src/app/gui/widgets/widget_id_registry.h index a0db68ad..50924a9a 100644 --- a/src/app/gui/widget_id_registry.h +++ b/src/app/gui/widgets/widget_id_registry.h @@ -1,5 +1,5 @@ -#ifndef YAZE_APP_GUI_WIDGET_ID_REGISTRY_H_ -#define YAZE_APP_GUI_WIDGET_ID_REGISTRY_H_ +#ifndef YAZE_APP_GUI_WIDGETS_WIDGET_ID_REGISTRY_H_ +#define YAZE_APP_GUI_WIDGETS_WIDGET_ID_REGISTRY_H_ #include #include @@ -173,4 +173,4 @@ class WidgetIdRegistry { } // namespace gui } // namespace yaze -#endif // YAZE_APP_GUI_WIDGET_ID_REGISTRY_H_ +#endif // YAZE_APP_GUI_WIDGETS_WIDGET_ID_REGISTRY_H_ diff --git a/src/app/test/test_manager.cc b/src/app/test/test_manager.cc index 4ba4650c..c859301e 100644 --- a/src/app/test/test_manager.cc +++ b/src/app/test/test_manager.cc @@ -14,7 +14,7 @@ #include "app/core/service/screenshot_utils.h" #include "app/gui/widgets/widget_state_capture.h" #include "app/core/features.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/gfx/arena.h" #include "app/gui/icons.h" #if defined(YAZE_ENABLE_IMGUI_TEST_ENGINE) && YAZE_ENABLE_IMGUI_TEST_ENGINE @@ -1011,7 +1011,7 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) { : "Bespoke"); // Actually test the file dialog - auto result = core::FileDialogWrapper::ShowOpenFileDialog(); + auto result = util::FileDialogWrapper::ShowOpenFileDialog(); if (!result.empty()) { LOG_INFO("TestManager", "File dialog test successful: %s", result.c_str()); @@ -1023,7 +1023,7 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) { ImGui::SameLine(); if (ImGui::Button("Test NFD Directly")) { - auto result = core::FileDialogWrapper::ShowOpenFileDialogNFD(); + auto result = util::FileDialogWrapper::ShowOpenFileDialogNFD(); if (!result.empty()) { LOG_INFO("TestManager", "NFD test successful: %s", result.c_str()); } else { @@ -1035,7 +1035,7 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) { ImGui::SameLine(); if (ImGui::Button("Test Bespoke Directly")) { - auto result = core::FileDialogWrapper::ShowOpenFileDialogBespoke(); + auto result = util::FileDialogWrapper::ShowOpenFileDialogBespoke(); if (!result.empty()) { LOG_INFO("TestManager", "Bespoke test successful: %s", result.c_str()); @@ -1187,13 +1187,13 @@ void TestManager::DrawTestDashboard(bool* show_dashboard) { ImGui::Text("Test Both Implementations:"); if (ImGui::Button("Quick Test NFD")) { - auto result = core::FileDialogWrapper::ShowOpenFileDialogNFD(); + auto result = util::FileDialogWrapper::ShowOpenFileDialogNFD(); LOG_INFO("TestManager", "NFD test result: %s", result.empty() ? "Failed/Canceled" : result.c_str()); } ImGui::SameLine(); if (ImGui::Button("Quick Test Bespoke")) { - auto result = core::FileDialogWrapper::ShowOpenFileDialogBespoke(); + auto result = util::FileDialogWrapper::ShowOpenFileDialogBespoke(); LOG_INFO("TestManager", "Bespoke test result: %s", result.empty() ? "Failed/Not Implemented" : result.c_str()); } diff --git a/src/app/zelda3/screen/dungeon_map.cc b/src/app/zelda3/screen/dungeon_map.cc index 04b91f2c..7b94b3d4 100644 --- a/src/app/zelda3/screen/dungeon_map.cc +++ b/src/app/zelda3/screen/dungeon_map.cc @@ -3,7 +3,7 @@ #include #include -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/window.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_tile.h" @@ -165,7 +165,7 @@ absl::Status LoadDungeonMapGfxFromBinary(Rom &rom, gfx::Tilemap &tile16_blockset, std::array &sheets, std::vector &gfx_bin_data) { - std::string bin_file = core::FileDialogWrapper::ShowOpenFileDialog(); + std::string bin_file = util::FileDialogWrapper::ShowOpenFileDialog(); if (bin_file.empty()) { return absl::InternalError("No file selected"); } diff --git a/src/cli/service/agent/learned_knowledge_service.cc b/src/cli/service/agent/learned_knowledge_service.cc index 247e5039..21a50e08 100644 --- a/src/cli/service/agent/learned_knowledge_service.cc +++ b/src/cli/service/agent/learned_knowledge_service.cc @@ -10,14 +10,7 @@ #include "absl/strings/str_format.h" #include "absl/time/clock.h" #include "absl/time/time.h" - -#ifdef _WIN32 -#include -#define mkdir(path, mode) _mkdir(path) -#else -#include -#include -#endif +#include "util/platform_paths.h" namespace yaze { namespace cli { @@ -36,25 +29,26 @@ std::string GenerateRandomID() { } bool FileExists(const std::filesystem::path& path) { - return std::filesystem::exists(path); -} - -absl::Status EnsureDirectoryExists(const std::filesystem::path& path) { - if (!std::filesystem::exists(path)) { - std::error_code ec; - if (!std::filesystem::create_directories(path, ec)) { - return absl::InternalError( - absl::StrCat("Failed to create directory: ", path.string(), - " - ", ec.message())); - } - } - return absl::OkStatus(); + return util::PlatformPaths::Exists(path); } } // namespace -LearnedKnowledgeService::LearnedKnowledgeService() - : LearnedKnowledgeService(std::filesystem::path(getenv("HOME") ? getenv("HOME") : ".") / ".yaze" / "agent") {} +LearnedKnowledgeService::LearnedKnowledgeService() { + // Get app data directory in a cross-platform way + auto app_data_result = util::PlatformPaths::GetAppDataSubdirectory("agent"); + if (app_data_result.ok()) { + data_dir_ = *app_data_result; + } else { + // Fallback to current directory + data_dir_ = std::filesystem::current_path() / ".yaze" / "agent"; + } + + prefs_file_ = data_dir_ / "preferences.json"; + patterns_file_ = data_dir_ / "patterns.json"; + projects_file_ = data_dir_ / "projects.json"; + memories_file_ = data_dir_ / "memories.json"; +} LearnedKnowledgeService::LearnedKnowledgeService( const std::filesystem::path& data_dir) @@ -70,7 +64,7 @@ absl::Status LearnedKnowledgeService::Initialize() { } // Ensure data directory exists - auto status = EnsureDirectoryExists(data_dir_); + auto status = util::PlatformPaths::EnsureDirectoryExists(data_dir_); if (!status.ok()) { return status; } diff --git a/src/cli/tui.cc b/src/cli/tui.cc index 1efd60b4..f8a7cf65 100644 --- a/src/cli/tui.cc +++ b/src/cli/tui.cc @@ -10,7 +10,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "util/bps.h" -#include "app/core/platform/file_dialog.h" +#include "util/file_util.h" #include "app/core/asar_wrapper.h" #include "app/zelda3/overworld/overworld.h" #include "cli/modern_cli.h" diff --git a/src/app/core/platform/file_dialog.cc b/src/util/file_util.cc similarity index 99% rename from src/app/core/platform/file_dialog.cc rename to src/util/file_util.cc index 7d2c968d..5ac92028 100644 --- a/src/app/core/platform/file_dialog.cc +++ b/src/util/file_util.cc @@ -1,4 +1,4 @@ -#include "file_dialog.h" +#include "util/file_util.h" #ifdef _WIN32 // Include Windows-specific headers @@ -18,7 +18,7 @@ #include "app/core/features.h" namespace yaze { -namespace core { +namespace util { std::string GetFileExtension(const std::string &filename) { size_t dot = filename.find_last_of('.'); @@ -723,5 +723,5 @@ std::vector FileDialogWrapper::GetFilesInFolder( #endif -} // namespace core +} // namespace util } // namespace yaze \ No newline at end of file diff --git a/src/app/core/platform/file_dialog.h b/src/util/file_util.h similarity index 92% rename from src/app/core/platform/file_dialog.h rename to src/util/file_util.h index 09d5d720..9cc2dd6c 100644 --- a/src/app/core/platform/file_dialog.h +++ b/src/util/file_util.h @@ -1,11 +1,11 @@ -#ifndef YAZE_APP_CORE_PLATFORM_FILE_DIALOG_H -#define YAZE_APP_CORE_PLATFORM_FILE_DIALOG_H +#ifndef YAZE_UTIL_FILE_UTIL_H_ +#define YAZE_UTIL_FILE_UTIL_H_ #include #include namespace yaze { -namespace core { +namespace util { class FileDialogWrapper { public: @@ -61,7 +61,7 @@ std::string ExpandHomePath(const std::string& path); std::string GetResourcePath(const std::string &resource_path); void SaveFile(const std::string &filename, const std::string &data); -} // namespace core +} // namespace util } // namespace yaze -#endif // YAZE_APP_CORE_PLATFORM_FILE_DIALOG_H +#endif // YAZE_UTIL_FILE_UTIL_H_ diff --git a/src/util/platform_paths.cc b/src/util/platform_paths.cc new file mode 100644 index 00000000..f07b72cf --- /dev/null +++ b/src/util/platform_paths.cc @@ -0,0 +1,140 @@ +#include "util/platform_paths.h" + +#include + +#include "absl/strings/str_cat.h" +#include "absl/strings/str_replace.h" + +#ifdef _WIN32 +#include +#include +#else +#include +#include +#endif + +namespace yaze { +namespace util { + +std::filesystem::path PlatformPaths::GetHomeDirectory() { +#ifdef _WIN32 + // Windows: Use USERPROFILE environment variable + const char* userprofile = std::getenv("USERPROFILE"); + if (userprofile && *userprofile) { + return std::filesystem::path(userprofile); + } + + // Fallback to HOMEDRIVE + HOMEPATH + const char* homedrive = std::getenv("HOMEDRIVE"); + const char* homepath = std::getenv("HOMEPATH"); + if (homedrive && homepath) { + return std::filesystem::path(std::string(homedrive) + std::string(homepath)); + } + + // Last resort: use temp directory + return std::filesystem::temp_directory_path(); +#else + // Unix/macOS: Use HOME environment variable + const char* home = std::getenv("HOME"); + if (home && *home) { + return std::filesystem::path(home); + } + + // Fallback: try getpwuid + struct passwd* pw = getpwuid(getuid()); + if (pw && pw->pw_dir) { + return std::filesystem::path(pw->pw_dir); + } + + // Last resort: current directory + return std::filesystem::current_path(); +#endif +} + +absl::StatusOr PlatformPaths::GetAppDataDirectory() { + std::filesystem::path home = GetHomeDirectory(); + std::filesystem::path app_data = home / ".yaze"; + + auto status = EnsureDirectoryExists(app_data); + if (!status.ok()) { + return status; + } + + return app_data; +} + +absl::StatusOr PlatformPaths::GetAppDataSubdirectory( + const std::string& subdir) { + auto app_data_result = GetAppDataDirectory(); + if (!app_data_result.ok()) { + return app_data_result.status(); + } + + std::filesystem::path subdir_path = *app_data_result / subdir; + + auto status = EnsureDirectoryExists(subdir_path); + if (!status.ok()) { + return status; + } + + return subdir_path; +} + +absl::Status PlatformPaths::EnsureDirectoryExists( + const std::filesystem::path& path) { + if (Exists(path)) { + return absl::OkStatus(); + } + + std::error_code ec; + if (!std::filesystem::create_directories(path, ec)) { + if (ec) { + return absl::InternalError( + absl::StrCat("Failed to create directory: ", path.string(), + " - Error: ", ec.message())); + } + } + + return absl::OkStatus(); +} + +bool PlatformPaths::Exists(const std::filesystem::path& path) { + std::error_code ec; + bool exists = std::filesystem::exists(path, ec); + return exists && !ec; +} + +absl::StatusOr PlatformPaths::GetTempDirectory() { + std::error_code ec; + std::filesystem::path temp_base = std::filesystem::temp_directory_path(ec); + + if (ec) { + return absl::InternalError( + absl::StrCat("Failed to get temp directory: ", ec.message())); + } + + std::filesystem::path yaze_temp = temp_base / "yaze"; + + auto status = EnsureDirectoryExists(yaze_temp); + if (!status.ok()) { + return status; + } + + return yaze_temp; +} + +std::string PlatformPaths::NormalizePathForDisplay( + const std::filesystem::path& path) { + // Convert to string and replace backslashes with forward slashes + // Forward slashes work on all platforms for display purposes + std::string path_str = path.string(); + return absl::StrReplaceAll(path_str, {{"\\", "/"}}); +} + +std::string PlatformPaths::ToNativePath(const std::filesystem::path& path) { + // std::filesystem::path::string() already returns the native format + return path.string(); +} + +} // namespace util +} // namespace yaze diff --git a/src/util/platform_paths.h b/src/util/platform_paths.h new file mode 100644 index 00000000..da23b471 --- /dev/null +++ b/src/util/platform_paths.h @@ -0,0 +1,107 @@ +#ifndef YAZE_UTIL_PLATFORM_PATHS_H_ +#define YAZE_UTIL_PLATFORM_PATHS_H_ + +#include +#include + +#include "absl/status/statusor.h" + +namespace yaze { +namespace util { + +/** + * @brief Cross-platform utilities for file system paths + * + * Provides consistent, platform-independent file and directory operations + * that work correctly on Windows (MSVC), macOS, and Linux. + */ +class PlatformPaths { + public: + /** + * @brief Get the user's home directory in a cross-platform way + * + * - Windows: Uses USERPROFILE environment variable + * - Unix/macOS: Uses HOME environment variable + * - Fallback: Returns current directory + * + * @return Path to user's home directory, or "." if not available + */ + static std::filesystem::path GetHomeDirectory(); + + /** + * @brief Get application data directory for YAZE + * + * Creates the directory if it doesn't exist. + * + * - Windows: %USERPROFILE%\.yaze + * - Unix/macOS: $HOME/.yaze + * + * @return StatusOr with path to data directory + */ + static absl::StatusOr GetAppDataDirectory(); + + /** + * @brief Get a subdirectory within the app data folder + * + * Creates the directory if it doesn't exist. + * + * @param subdir Subdirectory name (e.g., "agent", "cache", "logs") + * @return StatusOr with path to subdirectory + */ + static absl::StatusOr GetAppDataSubdirectory( + const std::string& subdir); + + /** + * @brief Ensure a directory exists, creating it if necessary + * + * Uses std::filesystem::create_directories which works cross-platform. + * + * @param path Directory path to create + * @return OK if directory exists or was created successfully + */ + static absl::Status EnsureDirectoryExists(const std::filesystem::path& path); + + /** + * @brief Check if a file or directory exists + * + * @param path Path to check + * @return true if exists, false otherwise + */ + static bool Exists(const std::filesystem::path& path); + + /** + * @brief Get a temporary directory for the application + * + * - Windows: %TEMP%\yaze + * - Unix: /tmp/yaze or $TMPDIR/yaze + * + * @return StatusOr with path to temp directory + */ + static absl::StatusOr GetTempDirectory(); + + /** + * @brief Normalize path separators for display + * + * Converts all path separators to forward slashes for consistent + * output in logs and UI (forward slashes work on all platforms). + * + * @param path Path to normalize + * @return Normalized path string + */ + static std::string NormalizePathForDisplay(const std::filesystem::path& path); + + /** + * @brief Convert path to native format + * + * Ensures path uses the correct separator for the current platform. + * + * @param path Path to convert + * @return Native path string + */ + static std::string ToNativePath(const std::filesystem::path& path); +}; + +} // namespace util +} // namespace yaze + +#endif // YAZE_UTIL_PLATFORM_PATHS_H_ diff --git a/src/app/core/platform/sdl_deleter.h b/src/util/sdl_deleter.h similarity index 77% rename from src/app/core/platform/sdl_deleter.h rename to src/util/sdl_deleter.h index 2552d1ba..00f0e329 100644 --- a/src/app/core/platform/sdl_deleter.h +++ b/src/util/sdl_deleter.h @@ -1,10 +1,10 @@ -#ifndef YAZE_APP_CORE_UTILS_SDL_DELETER_H_ -#define YAZE_APP_CORE_UTILS_SDL_DELETER_H_ +#ifndef YAZE_UTIL_SDL_DELETER_H_ +#define YAZE_UTIL_SDL_DELETER_H_ #include namespace yaze { -namespace core { +namespace util { /** * @brief Deleter for SDL_Window and SDL_Renderer. @@ -32,7 +32,7 @@ struct SDL_Texture_Deleter { } }; -} // namespace core +} // namespace util } // namespace yaze -#endif // YAZE_APP_CORE_UTILS_SDL_DELETER_H_ +#endif // YAZE_UTIL_SDL_DELETER_H_ diff --git a/src/util/util.cmake b/src/util/util.cmake index 2fdabb7d..d9aef788 100644 --- a/src/util/util.cmake +++ b/src/util/util.cmake @@ -15,6 +15,8 @@ set(YAZE_UTIL_SRC util/flag.cc util/hex.cc util/log.cc + util/platform_paths.cc + util/file_util.cc ) add_library(yaze_util STATIC ${YAZE_UTIL_SRC})