summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-03 08:42:12 +0100
committerskal <pascal.massimino@gmail.com>2026-02-03 08:42:12 +0100
commit59c72c95b5fdd756d4b0134fad32f7a3f4daa2aa (patch)
treec60e6b69f3cfeaa0856e17b26690bea63ea44fc2
parentdd849f36c09d08c4cd7a66348232206032455700 (diff)
fix(assets): Resolve static initialization order fiasco
Replaces the global array with which wraps a local static array. This ensures the asset table is initialized on first use, preventing crashes when other globals (like shader strings) try to access assets during dynamic initialization.
-rw-r--r--src/util/asset_manager.cc16
-rw-r--r--tools/asset_packer.cc20
2 files changed, 20 insertions, 16 deletions
diff --git a/src/util/asset_manager.cc b/src/util/asset_manager.cc
index 65b3200..d9ecfe1 100644
--- a/src/util/asset_manager.cc
+++ b/src/util/asset_manager.cc
@@ -24,14 +24,6 @@ static const std::map<std::string, ProcGenFunc> kAssetManagerProcGenFuncMap = {
{"make_periodic", procedural::make_periodic},
};
-// These are defined in the generated assets_data.cc
-#if defined(USE_TEST_ASSETS)
-extern const AssetRecord g_assets[];
-extern const size_t g_assets_count;
-#else
-extern const AssetRecord g_assets[];
-extern const size_t g_assets_count;
-#endif
// Array-based cache for assets.
// Initialized to all zeros (nullptr data, 0 size, false is_procedural)
// The size is derived from the generated ASSET_LAST_ID enum value.
@@ -59,15 +51,19 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) {
return g_asset_cache[index].data;
}
+ const AssetRecord* assets = GetAssetRecordTable();
+ size_t count = GetAssetCount();
+
// Not in cache, retrieve from static data (packed in binary) or generate
// procedurally
- if (index >= g_assets_count) {
+ if (index >= count) {
if (out_size)
*out_size = 0;
return nullptr; // Invalid asset_id or asset not in static packed data.
}
- AssetRecord source_record = g_assets[index];
+ AssetRecord source_record = assets[index];
+
AssetRecord cached_record = source_record;
if (source_record.is_procedural) {
diff --git a/tools/asset_packer.cc b/tools/asset_packer.cc
index d86e29b..2de57d0 100644
--- a/tools/asset_packer.cc
+++ b/tools/asset_packer.cc
@@ -86,7 +86,7 @@ int main(int argc, char* argv[]) {
assets_data_cc_file,
"// This file is auto-generated by asset_packer.cc. Do not edit.\n\n");
fprintf(assets_data_cc_file, "#include \"util/asset_manager.h\"\n");
- fprintf(assets_data_cc_file, "#include \"%s\"\n\n",
+ fprintf(assets_data_cc_file, "#include \"%s\"\n",
generated_header_name.c_str());
// Forward declare procedural functions for AssetRecord initialization
@@ -196,6 +196,10 @@ int main(int argc, char* argv[]) {
fprintf(assets_h_file,
"#include \"util/asset_manager.h\"\n"); // Include here AFTER enum
// definition
+ fprintf(assets_h_file, "\n// Accessors to avoid static initialization order issues\n");
+ fprintf(assets_h_file, "const struct AssetRecord* GetAssetRecordTable();\n");
+ fprintf(assets_h_file, "size_t GetAssetCount();\n");
+
std::fclose(assets_h_file);
for (const auto& info : asset_build_infos) {
@@ -238,7 +242,8 @@ int main(int argc, char* argv[]) {
}
}
- fprintf(assets_data_cc_file, "extern const AssetRecord g_assets[] = {\n");
+ fprintf(assets_data_cc_file, "const AssetRecord* GetAssetRecordTable() {\n");
+ fprintf(assets_data_cc_file, " static const AssetRecord assets[] = {\n");
for (const auto& info : asset_build_infos) {
fprintf(assets_data_cc_file, " { ");
if (info.is_procedural) {
@@ -251,10 +256,13 @@ int main(int argc, char* argv[]) {
}
fprintf(assets_data_cc_file, " },\n");
}
- fprintf(assets_data_cc_file, "};\n");
- fprintf(assets_data_cc_file,
- "extern const size_t g_assets_count = sizeof(g_assets) / "
- "sizeof(g_assets[0]);\n");
+ fprintf(assets_data_cc_file, " };\n");
+ fprintf(assets_data_cc_file, " return assets;\n");
+ fprintf(assets_data_cc_file, "}\n\n");
+
+ fprintf(assets_data_cc_file, "size_t GetAssetCount() {\n");
+ fprintf(assets_data_cc_file, " return %zu;\n", asset_build_infos.size());
+ fprintf(assets_data_cc_file, "}\n\n");
std::fclose(assets_data_cc_file);