refactor: Restructure file dialog handling and introduce utility classes

- Updated file dialog references across the application to utilize a new `util::FileDialogWrapper` for consistent file handling.
- Refactored existing code to replace direct calls to `core::FileDialogWrapper` with the new utility class, enhancing modularity and maintainability.
- Introduced `util::PlatformPaths` for cross-platform directory management, ensuring consistent access to user directories and application data paths.
- Added new utility functions for file operations, improving the overall file handling capabilities within the application.
- Updated CMake configurations to include new utility source files, streamlining the build process.
This commit is contained in:
scawful
2025-10-04 23:26:42 -04:00
parent 429506e503
commit bcc8f8e8f9
39 changed files with 385 additions and 144 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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"];

View File

@@ -1,4 +1,4 @@
#include "app/core/platform/file_dialog.h"
#include "util/file_util.h"
#include <iostream>
#include <string>
@@ -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<std::string> yaze::core::FileDialogWrapper::GetFilesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetFilesInFolder(
const std::string &folder) {
return {};
}
std::vector<std::string> yaze::core::FileDialogWrapper::GetSubdirectoriesInFolder(
std::vector<std::string> 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 <Cocoa/Cocoa.h>
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
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<std::string> yaze::core::FileDialogWrapper::GetFilesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetFilesInFolder(
const std::string& folder) {
std::vector<std::string> filenames;
NSFileManager* fileManager = [NSFileManager defaultManager];
@@ -267,7 +267,7 @@ std::vector<std::string> yaze::core::FileDialogWrapper::GetFilesInFolder(
return filenames;
}
std::vector<std::string> yaze::core::FileDialogWrapper::GetSubdirectoriesInFolder(
std::vector<std::string> yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder(
const std::string& folder) {
std::vector<std::string> subdirectories;
NSFileManager* fileManager = [NSFileManager defaultManager];
@@ -289,7 +289,7 @@ std::vector<std::string> 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:@"/"];

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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")) {

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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()) {

View File

@@ -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;

View File

@@ -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()) {

View File

@@ -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_,

View File

@@ -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);

View File

@@ -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]);

View File

@@ -4,7 +4,7 @@
#include <fstream>
#include <vector>
#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

View File

@@ -2,7 +2,7 @@
#include <SDL.h>
#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<SDL_Texture, core::SDL_Texture_Deleter>(texture);
std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>(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<SDL_Surface, core::SDL_Surface_Deleter>(
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(
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<SDL_Surface, core::SDL_Surface_Deleter>(surface);
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(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<SDL_Texture, core::SDL_Texture_Deleter>(texture);
std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>(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<SDL_Surface, core::SDL_Surface_Deleter>(surface);
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(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<SDL_Surface, core::SDL_Surface_Deleter>(
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>(
SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0),
core::SDL_Surface_Deleter());
util::SDL_Surface_Deleter());
if (!converted_surface) {
return;

View File

@@ -8,7 +8,7 @@
#include <unordered_map>
#include <vector>
#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::Bitmap, 223> gfx_sheets_;
std::unordered_map<SDL_Texture*,
std::unique_ptr<SDL_Texture, core::SDL_Texture_Deleter>>
std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>>
textures_;
std::unordered_map<SDL_Surface*,
std::unique_ptr<SDL_Surface, core::SDL_Surface_Deleter>>
std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>>
surfaces_;
// Resource pooling for efficient memory management

View File

@@ -2,7 +2,7 @@
#include <algorithm>
#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"

View File

@@ -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<std::string> 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;

View File

@@ -1,4 +1,4 @@
#include "app/gui/widget_auto_register.h"
#include "app/gui/widgets/widget_auto_register.h"
#include <vector>

View File

@@ -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 <string>
#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_

View File

@@ -1,4 +1,4 @@
#include "widget_id_registry.h"
#include "app/gui/widgets/widget_id_registry.h"
#include <algorithm>
#include <chrono>

View File

@@ -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 <cstdint>
#include <optional>
@@ -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_

View File

@@ -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());
}

View File

@@ -3,7 +3,7 @@
#include <fstream>
#include <vector>
#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<gfx::Bitmap, 4> &sheets,
std::vector<uint8_t> &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");
}

View File

@@ -10,14 +10,7 @@
#include "absl/strings/str_format.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#ifdef _WIN32
#include <direct.h>
#define mkdir(path, mode) _mkdir(path)
#else
#include <sys/stat.h>
#include <sys/types.h>
#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;
}

View File

@@ -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"

View File

@@ -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<std::string> FileDialogWrapper::GetFilesInFolder(
#endif
} // namespace core
} // namespace util
} // namespace yaze

View File

@@ -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 <string>
#include <vector>
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_

140
src/util/platform_paths.cc Normal file
View File

@@ -0,0 +1,140 @@
#include "util/platform_paths.h"
#include <cstdlib>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#ifdef _WIN32
#include <windows.h>
#include <shlobj.h>
#else
#include <unistd.h>
#include <pwd.h>
#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<std::filesystem::path> 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<std::filesystem::path> 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<std::filesystem::path> 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

107
src/util/platform_paths.h Normal file
View File

@@ -0,0 +1,107 @@
#ifndef YAZE_UTIL_PLATFORM_PATHS_H_
#define YAZE_UTIL_PLATFORM_PATHS_H_
#include <filesystem>
#include <string>
#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<std::filesystem::path> 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<std::filesystem::path> 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<std::filesystem::path> 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_

View File

@@ -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 <SDL.h>
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_

View File

@@ -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})