yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
asset_loader.cc
Go to the documentation of this file.
2
3#include <fstream>
4#include <sstream>
5
6#ifdef __APPLE__
7#include <TargetConditionals.h>
8#endif
9
10#include "absl/strings/str_format.h"
11#include "util/file_util.h"
12#include "util/platform_paths.h"
13
14namespace yaze {
15
16std::vector<std::filesystem::path> AssetLoader::GetSearchPaths(
17 const std::string& relative_path) {
18 std::vector<std::filesystem::path> search_paths;
19
20#ifdef __APPLE__
21 // macOS bundle resource paths
22 std::string bundle_root = yaze::util::GetBundleResourcePath();
23
24#if TARGET_OS_IOS == 1
25 // iOS app bundle resources live at the root.
26 search_paths.push_back(std::filesystem::path(bundle_root) / "assets" /
27 relative_path);
28 search_paths.push_back(std::filesystem::path(bundle_root) / relative_path);
29#else
30 // Try Contents/Resources first (standard bundle location)
31 search_paths.push_back(std::filesystem::path(bundle_root) / "Contents" /
32 "Resources" / relative_path);
33 search_paths.push_back(std::filesystem::path(bundle_root) / "Contents" /
34 "Resources" / "assets" / relative_path);
35
36 // Try without Contents (if app is at root)
37 search_paths.push_back(std::filesystem::path(bundle_root) / "Resources" /
38 relative_path);
39 search_paths.push_back(std::filesystem::path(bundle_root) / "Resources" /
40 "assets" / relative_path);
41
42 // Assets folder next to the app bundle (nightly installs)
43 search_paths.push_back(std::filesystem::path(bundle_root) / ".." / "assets" /
44 relative_path);
45
46 // Development paths (when running from build dir)
47 search_paths.push_back(std::filesystem::path(bundle_root) / ".." / ".." /
48 ".." / "assets" / relative_path);
49 search_paths.push_back(std::filesystem::path(bundle_root) / ".." / ".." /
50 ".." / ".." / "assets" / relative_path);
51#endif
52#endif
53
54 // Standard relative paths (works for all platforms)
55 search_paths.push_back(std::filesystem::path("assets") / relative_path);
56 search_paths.push_back(std::filesystem::path("../assets") / relative_path);
57 search_paths.push_back(std::filesystem::path("../../assets") / relative_path);
58 search_paths.push_back(std::filesystem::path("../../../assets") /
59 relative_path);
60 search_paths.push_back(std::filesystem::path("../../../../assets") /
61 relative_path);
62
63 // Build directory paths
64 search_paths.push_back(std::filesystem::path("build/assets") / relative_path);
65 search_paths.push_back(std::filesystem::path("../build/assets") /
66 relative_path);
67
68 return search_paths;
69}
70
71absl::StatusOr<std::filesystem::path> AssetLoader::FindAssetFile(
72 const std::string& relative_path) {
73 if (auto path = util::PlatformPaths::FindAsset(relative_path); path.ok()) {
74 return *path;
75 }
76
77 // Retain the historical relative probes for older portable layouts.
78 auto search_paths = GetSearchPaths(relative_path);
79
80 for (const auto& path : search_paths) {
81 if (std::filesystem::exists(path)) {
82 return path;
83 }
84 }
85
86 // Debug: Print searched paths
87 std::string searched_paths;
88 for (const auto& path : search_paths) {
89 searched_paths += "\n - " + path.string();
90 }
91
92 return absl::NotFoundError(
93 absl::StrFormat("Asset file not found: %s\nSearched paths:%s",
94 relative_path, searched_paths));
95}
96
97absl::StatusOr<std::string> AssetLoader::LoadTextFile(
98 const std::string& relative_path) {
99 auto path_result = FindAssetFile(relative_path);
100 if (!path_result.ok()) {
101 return path_result.status();
102 }
103
104 const auto& path = *path_result;
105 std::ifstream file(path);
106 if (!file.is_open()) {
107 return absl::InternalError(
108 absl::StrFormat("Failed to open file: %s", path.string()));
109 }
110
111 std::stringstream buffer;
112 buffer << file.rdbuf();
113 std::string content = buffer.str();
114
115 if (content.empty()) {
116 return absl::InternalError(
117 absl::StrFormat("File is empty: %s", path.string()));
118 }
119
120 return content;
121}
122
123bool AssetLoader::AssetExists(const std::string& relative_path) {
124 return FindAssetFile(relative_path).ok();
125}
126
127} // namespace yaze
static absl::StatusOr< std::string > LoadTextFile(const std::string &relative_path)
static absl::StatusOr< std::filesystem::path > FindAssetFile(const std::string &relative_path)
static std::vector< std::filesystem::path > GetSearchPaths(const std::string &relative_path)
static bool AssetExists(const std::string &relative_path)
static absl::StatusOr< std::filesystem::path > FindAsset(const std::string &relative_path)
Find an asset file in multiple standard locations.
std::string GetBundleResourcePath()
GetBundleResourcePath returns the path to the bundle resource directory. Specific to MacOS.