From fbcfadbd11fc5e7f87f53310df7530c1c6dfafd0 Mon Sep 17 00:00:00 2001 From: scawful Date: Sun, 5 Oct 2025 05:50:58 -0400 Subject: [PATCH] feat: Add AssetLoader for Cross-Platform Asset Management - Introduced the AssetLoader class to facilitate loading assets across different platforms, including macOS and standard relative paths for Windows and Linux. - Implemented methods for searching asset paths, finding asset files, and loading text files, enhancing the flexibility and usability of asset management. - Updated CMake configuration to include the new asset_loader source files, ensuring proper integration into the build system. --- src/app/core/core_library.cmake | 2 + src/app/core/platform/asset_loader.cc | 79 +++++++++++++++++++++++++++ src/app/core/platform/asset_loader.h | 57 +++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 src/app/core/platform/asset_loader.cc create mode 100644 src/app/core/platform/asset_loader.h diff --git a/src/app/core/core_library.cmake b/src/app/core/core_library.cmake index 5c8b3926..08ddd8c2 100644 --- a/src/app/core/core_library.cmake +++ b/src/app/core/core_library.cmake @@ -10,6 +10,7 @@ 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/asset_loader.cc ) endif() @@ -19,6 +20,7 @@ if(APPLE) app/core/platform/app_delegate.mm app/core/platform/font_loader.cc app/core/platform/font_loader.mm + app/core/platform/asset_loader.cc ) find_library(COCOA_LIBRARY Cocoa) diff --git a/src/app/core/platform/asset_loader.cc b/src/app/core/platform/asset_loader.cc new file mode 100644 index 00000000..a6f395ad --- /dev/null +++ b/src/app/core/platform/asset_loader.cc @@ -0,0 +1,79 @@ +#include "app/core/platform/asset_loader.h" + +#include +#include + +#include "absl/strings/str_format.h" +#include "util/file_util.h" + +namespace yaze { +namespace core { + +std::vector AssetLoader::GetSearchPaths(const std::string& relative_path) { + std::vector search_paths; + +#ifdef __APPLE__ + // macOS bundle resource paths + std::string bundle_root = yaze::util::GetBundleResourcePath(); + search_paths.push_back(std::filesystem::path(bundle_root) / "Contents" / "Resources" / relative_path); + search_paths.push_back(std::filesystem::path(bundle_root) / "assets" / relative_path); +#endif + + // Standard relative paths (works for all platforms) + search_paths.push_back(std::filesystem::path("assets") / relative_path); + search_paths.push_back(std::filesystem::path("../assets") / relative_path); + search_paths.push_back(std::filesystem::path("../../assets") / relative_path); + search_paths.push_back(std::filesystem::path("../../../assets") / relative_path); + + // Build directory paths + search_paths.push_back(std::filesystem::path("build/assets") / relative_path); + search_paths.push_back(std::filesystem::path("../build/assets") / relative_path); + + return search_paths; +} + +absl::StatusOr AssetLoader::FindAssetFile(const std::string& relative_path) { + auto search_paths = GetSearchPaths(relative_path); + + for (const auto& path : search_paths) { + if (std::filesystem::exists(path)) { + return path; + } + } + + return absl::NotFoundError( + absl::StrFormat("Asset file not found: %s (searched %d paths)", + relative_path, search_paths.size())); +} + +absl::StatusOr AssetLoader::LoadTextFile(const std::string& relative_path) { + auto path_result = FindAssetFile(relative_path); + if (!path_result.ok()) { + return path_result.status(); + } + + const auto& path = *path_result; + std::ifstream file(path); + if (!file.is_open()) { + return absl::InternalError( + absl::StrFormat("Failed to open file: %s", path.string())); + } + + std::stringstream buffer; + buffer << file.rdbuf(); + std::string content = buffer.str(); + + if (content.empty()) { + return absl::InternalError( + absl::StrFormat("File is empty: %s", path.string())); + } + + return content; +} + +bool AssetLoader::AssetExists(const std::string& relative_path) { + return FindAssetFile(relative_path).ok(); +} + +} // namespace core +} // namespace yaze diff --git a/src/app/core/platform/asset_loader.h b/src/app/core/platform/asset_loader.h new file mode 100644 index 00000000..4d52b722 --- /dev/null +++ b/src/app/core/platform/asset_loader.h @@ -0,0 +1,57 @@ +#ifndef YAZE_APP_CORE_PLATFORM_ASSET_LOADER_H_ +#define YAZE_APP_CORE_PLATFORM_ASSET_LOADER_H_ + +#include +#include +#include + +#include "absl/status/statusor.h" + +namespace yaze { +namespace core { + +/** + * @class AssetLoader + * @brief Cross-platform asset file loading utility + * + * Handles platform-specific paths for loading assets from: + * - macOS bundle resources + * - Windows relative paths + * - Linux relative paths + * - Development build directories + */ +class AssetLoader { + public: + /** + * Load a text file from the assets directory + * @param relative_path Path relative to assets/ (e.g., "agent/system_prompt.txt") + * @return File contents or error + */ + static absl::StatusOr LoadTextFile(const std::string& relative_path); + + /** + * Find an asset file by trying multiple platform-specific paths + * @param relative_path Path relative to assets/ + * @return Full path to file or error + */ + static absl::StatusOr FindAssetFile(const std::string& relative_path); + + /** + * Get list of search paths for a given asset + * @param relative_path Path relative to assets/ + * @return Vector of paths to try in order + */ + static std::vector GetSearchPaths(const std::string& relative_path); + + /** + * Check if an asset file exists + * @param relative_path Path relative to assets/ + * @return true if file exists in any search path + */ + static bool AssetExists(const std::string& relative_path); +}; + +} // namespace core +} // namespace yaze + +#endif // YAZE_APP_CORE_PLATFORM_ASSET_LOADER_H_