refactor: Integrate PlatformPaths for configuration directory management

- Replaced direct calls to GetConfigDirectory with PlatformPaths::GetConfigDirectory across multiple files to standardize configuration directory access.
- Updated RecentFilesManager, EditorManager, and various agent components to handle potential errors when retrieving the configuration directory.
- Enhanced file loading functions to utilize the new LoadFileFromConfigDir method for improved clarity and error handling.
- Introduced new methods in file_util.h for better file management practices, leveraging std::filesystem for cross-platform consistency.
This commit is contained in:
scawful
2025-10-08 20:50:49 -04:00
parent 9bc31bc8fc
commit 7f4a0f546c
14 changed files with 281 additions and 717 deletions

View File

@@ -10,6 +10,7 @@
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "util/file_util.h"
#include "util/platform_paths.h"
#include "app/gui/icons.h"
#include "util/log.h"
#include "app/zelda3/zelda3_labels.h"
@@ -1059,13 +1060,19 @@ absl::Status YazeProject::SaveToJsonFormat() {
// RecentFilesManager implementation
std::string RecentFilesManager::GetFilePath() const {
return util::GetConfigDirectory() + "/" + kRecentFilesFilename;
auto config_dir = util::PlatformPaths::GetConfigDirectory();
if (!config_dir.ok()) {
return ""; // Or handle error appropriately
}
return (*config_dir / kRecentFilesFilename).string();
}
void RecentFilesManager::Save() {
// Ensure config directory exists
if (!util::EnsureConfigDirectoryExists()) {
LOG_WARN("RecentFilesManager", "Could not create config directory for recent files");
auto config_dir_status = util::PlatformPaths::GetConfigDirectory();
if (!config_dir_status.ok()) {
LOG_ERROR("Project", "Failed to get or create config directory: %s",
config_dir_status.status().ToString().c_str());
return;
}

View File

@@ -28,8 +28,10 @@
#include "app/rom.h"
#include "imgui/imgui.h"
#include "util/file_util.h"
#include "util/platform_paths.h"
#include <SDL.h>
#include <filesystem>
#if defined(YAZE_WITH_GRPC)
#include "app/test/test_manager.h"
@@ -37,6 +39,7 @@
namespace {
namespace fs = std::filesystem;
using yaze::cli::agent::ChatMessage;
std::filesystem::path ExpandUserPath(std::string path) {
@@ -55,7 +58,13 @@ std::filesystem::path ExpandUserPath(std::string path) {
}
std::filesystem::path ResolveHistoryPath(const std::string& session_id = "") {
std::filesystem::path base = ExpandUserPath(yaze::util::GetConfigDirectory());
auto config_dir = yaze::util::PlatformPaths::GetConfigDirectory();
if (!config_dir.ok()) {
// Fallback to a local directory if config can't be determined.
return fs::current_path() / ".yaze" / "agent" / "history" / (session_id.empty() ? "default.json" : session_id + ".json");
}
fs::path base = *config_dir;
if (base.empty()) {
base = ExpandUserPath(".yaze");
}

View File

@@ -18,8 +18,12 @@
#include "absl/strings/str_format.h"
#include "absl/strings/strip.h"
#include "util/file_util.h"
#include "util/platform_paths.h"
#include "util/macro.h"
#include <filesystem>
namespace fs = std::filesystem;
namespace yaze {
namespace editor {
@@ -259,11 +263,12 @@ std::string AgentCollaborationCoordinator::GenerateSessionCode() const {
}
std::filesystem::path AgentCollaborationCoordinator::SessionsDirectory() const {
std::filesystem::path base = ExpandUserPath(util::GetConfigDirectory());
if (base.empty()) {
base = ExpandUserPath(".yaze");
auto config_dir = util::PlatformPaths::GetConfigDirectory();
if (!config_dir.ok()) {
// Fallback to a local directory if config can't be determined.
return fs::current_path() / ".yaze" / "agent" / "sessions";
}
return base / "agent" / "sessions";
return *config_dir / "agent" / "sessions";
}
std::filesystem::path AgentCollaborationCoordinator::SessionFilePath(

View File

@@ -15,6 +15,7 @@
#include "app/gui/icons.h"
#include "app/rom.h"
#include "util/file_util.h"
#include "util/platform_paths.h"
#ifdef YAZE_WITH_GRPC
#include "app/editor/agent/network_collaboration_coordinator.h"
@@ -1238,23 +1239,12 @@ absl::Status AgentEditor::ImportProfile(const std::filesystem::path& path) {
}
std::filesystem::path AgentEditor::GetProfilesDirectory() const {
std::filesystem::path config_dir(yaze::util::GetConfigDirectory());
if (config_dir.empty()) {
#ifdef _WIN32
const char* appdata = std::getenv("APPDATA");
if (appdata) {
config_dir = std::filesystem::path(appdata) / "yaze";
}
#else
const char* home_env = std::getenv("HOME");
if (home_env) {
config_dir = std::filesystem::path(home_env) / ".yaze";
}
#endif
auto config_dir = yaze::util::PlatformPaths::GetConfigDirectory();
if (!config_dir.ok()) {
// Fallback to a local directory if config can't be determined.
return std::filesystem::current_path() / ".yaze" / "agent" / "profiles";
}
return config_dir / std::filesystem::path("agent") /
std::filesystem::path("profiles");
return *config_dir / "agent" / "profiles";
}
absl::Status AgentEditor::EnsureProfilesDirectory() {

View File

@@ -13,6 +13,7 @@
#include "app/core/features.h"
#include "app/core/timing.h"
#include "util/file_util.h"
#include "util/platform_paths.h"
#include "app/core/project.h"
#include "app/editor/code/assembly_editor.h"
#include "app/editor/dungeon/dungeon_editor.h"
@@ -82,8 +83,16 @@ std::string GetEditorName(EditorType type) {
// Settings + preset helpers
void EditorManager::LoadUserSettings() {
auto config_dir = util::PlatformPaths::GetConfigDirectory();
if (!config_dir.ok()) {
LOG_WARN("EditorManager", "Could not determine config directory for settings.");
return;
}
std::string settings_path = (*config_dir / settings_filename_).string();
try {
auto data = util::LoadConfigFile(settings_filename_);
auto data = util::LoadFile(settings_path);
if (!data.empty()) {
std::istringstream ss(data);
std::string line;
@@ -102,7 +111,9 @@ void EditorManager::LoadUserSettings() {
}
ImGui::GetIO().FontGlobalScale = font_global_scale_;
}
} catch (...) {}
} catch (...) {
// Could not load file, just use defaults.
}
}
void EditorManager::SaveUserSettings() {
@@ -121,17 +132,21 @@ void EditorManager::RefreshWorkspacePresets() {
// Try to read a simple index file of presets
try {
auto data = util::LoadConfigFile("workspace_presets.txt");
if (!data.empty()) {
std::istringstream ss(data);
std::string name;
while (std::getline(ss, name)) {
// Trim whitespace and validate
name.erase(0, name.find_first_not_of(" \t\r\n"));
name.erase(name.find_last_not_of(" \t\r\n") + 1);
if (!name.empty() &&
name.length() < 256) { // Reasonable length limit
new_presets.emplace_back(std::move(name));
auto config_dir = util::PlatformPaths::GetConfigDirectory();
if (config_dir.ok()) {
std::string presets_path = (*config_dir / "workspace_presets.txt").string();
auto data = util::LoadFile(presets_path);
if (!data.empty()) {
std::istringstream ss(data);
std::string name;
while (std::getline(ss, name)) {
// Trim whitespace and validate
name.erase(0, name.find_first_not_of(" \t\r\n"));
name.erase(name.find_last_not_of(" \t\r\n") + 1);
if (!name.empty() &&
name.length() < 256) { // Reasonable length limit
new_presets.emplace_back(std::move(name));
}
}
}
}

View File

@@ -3,9 +3,11 @@
#include "absl/strings/str_format.h"
#include "app/gfx/performance_profiler.h"
#include "app/editor/code/assembly_editor.h"
#include "app/emu/emulator.h"
#include "app/gui/icons.h"
#include "app/gui/input.h"
#include "imgui/imgui.h"
#include "util/log.h"
namespace yaze {
namespace editor {
@@ -210,5 +212,75 @@ void MusicEditor::DrawToolset() {
ImGui::ProgressBar((float)current_time / SONG_DURATION);
}
// ============================================================================
// Audio Control Methods (Emulator Integration)
// ============================================================================
void MusicEditor::PlaySong(int song_id) {
if (!emulator_) {
LOG_WARN("MusicEditor", "No emulator instance - cannot play song");
return;
}
if (!emulator_->snes().running()) {
LOG_WARN("MusicEditor", "Emulator not running - cannot play song");
return;
}
// Write song request to game memory ($7E012C)
// This triggers the NMI handler to send the song to APU
try {
emulator_->snes().Write(0x7E012C, static_cast<uint8_t>(song_id));
LOG_INFO("MusicEditor", "Requested song %d (%s)", song_id,
song_id < 30 ? kGameSongs[song_id] : "Unknown");
// Ensure audio backend is playing
if (auto* audio = emulator_->audio_backend()) {
auto status = audio->GetStatus();
if (!status.is_playing) {
audio->Play();
LOG_INFO("MusicEditor", "Started audio backend playback");
}
}
is_playing_ = true;
} catch (const std::exception& e) {
LOG_ERROR("MusicEditor", "Failed to play song: %s", e.what());
}
}
void MusicEditor::StopSong() {
if (!emulator_) return;
// Write stop command to game memory
try {
emulator_->snes().Write(0x7E012C, 0xFF); // 0xFF = stop music
LOG_INFO("MusicEditor", "Stopped music playback");
// Optional: pause audio backend to save CPU
if (auto* audio = emulator_->audio_backend()) {
audio->Pause();
}
is_playing_ = false;
} catch (const std::exception& e) {
LOG_ERROR("MusicEditor", "Failed to stop song: %s", e.what());
}
}
void MusicEditor::SetVolume(float volume) {
if (!emulator_) return;
// Clamp volume to valid range
volume = std::clamp(volume, 0.0f, 1.0f);
if (auto* audio = emulator_->audio_backend()) {
audio->SetVolume(volume);
LOG_DEBUG("MusicEditor", "Set volume to %.2f", volume);
} else {
LOG_WARN("MusicEditor", "No audio backend available");
}
}
} // namespace editor
} // namespace yaze

View File

@@ -9,6 +9,12 @@
#include "imgui/imgui.h"
namespace yaze {
// Forward declaration
namespace emu {
class Emulator;
}
namespace editor {
static const char* kGameSongs[] = {"Title",
@@ -77,6 +83,15 @@ class MusicEditor : public Editor {
// Get the ROM pointer
Rom* rom() const { return rom_; }
// Emulator integration for live audio playback
void set_emulator(emu::Emulator* emulator) { emulator_ = emulator; }
emu::Emulator* emulator() const { return emulator_; }
// Audio control methods
void PlaySong(int song_id);
void StopSong();
void SetVolume(float volume); // 0.0 to 1.0
private:
// UI Drawing Methods
@@ -112,6 +127,7 @@ class MusicEditor : public Editor {
ImGuiTableFlags_BordersV | ImGuiTableFlags_PadOuterX;
Rom* rom_;
emu::Emulator* emulator_ = nullptr; // For live audio playback
};
} // namespace editor

View File

@@ -344,7 +344,7 @@ void EditorSelectionDialog::MarkRecentlyUsed(EditorType type) {
void EditorSelectionDialog::LoadRecentEditors() {
try {
auto data = util::LoadConfigFile("recent_editors.txt");
auto data = util::LoadFileFromConfigDir("recent_editors.txt");
if (!data.empty()) {
std::istringstream ss(data);
std::string line;

View File

@@ -10,6 +10,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
#include "util/file_util.h"
#include "util/platform_paths.h"
#include "app/gui/icons.h"
#include "app/gui/style.h" // For ColorsYaze function
#include "imgui/imgui.h"
@@ -1917,8 +1918,10 @@ std::vector<std::string> ThemeManager::GetThemeSearchPaths() const {
#endif
// User config directory
std::string config_themes = util::GetConfigDirectory() + "/themes/";
search_paths.push_back(config_themes);
auto config_dir = util::PlatformPaths::GetConfigDirectory();
if (config_dir.ok()) {
search_paths.push_back((*config_dir / "themes/").string());
}
return search_paths;
}