From f107689be915d96363ea75889631939c62f07980 Mon Sep 17 00:00:00 2001 From: quou Date: Sun, 29 Dec 2024 13:54:35 +1100 Subject: cache assets to avoid loading them more than once --- asset.cpp | 46 ++++++++++++++++++++++++++++++++++------------ asset.hpp | 15 ++++++++++----- c2.cpp | 2 +- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/asset.cpp b/asset.cpp index fc8abde..10ddd04 100644 --- a/asset.cpp +++ b/asset.cpp @@ -66,7 +66,12 @@ void register_asset_loader( manager.set_loader(magic, loader); } -void Asset_Arena::init(Arena* arena, const char* pack_name) { +void Asset_Arena::init( + Arena* arena, + const char* pack_name, + int max +) { + int i; p = pack_open(pack_name, arena); assert(p != 0); a = arena; @@ -76,27 +81,43 @@ void Asset_Arena::init(Arena* arena, const char* pack_name) { arena_alloc(a, asset_scratch_size), asset_scratch_size ); - assets = 0; + max_assets = max; + assets = (Bucket*)arena_alloc(arena, max * sizeof(Bucket)); + for (i = 0; i < max; i++) + assets[i].name = 0; } void Asset_Arena::destroy() { - Asset* a; - for (a = assets; a; a = a->next) { - a->loader->unload(a); + int i, c = max_assets; + for (i = 0; i < c; i++) { + Bucket& b = assets[i]; + if (b.name) + b.asset->loader->unload(b.asset); } pack_close(p); } -void Asset_Arena::claim(Asset* a) { - if (assets) { - a->next = assets; - assets = a; - } else assets = a; +int Asset_Arena::bucket(const char* name) { + uint32_t hash = hash_string(name); + int bucket = (int)(hash % max_assets); + int i; + for (i = 0; i < max_assets; i++) { + Bucket& b = assets[bucket]; + if (!b.name || string_equal(name, b.name)) + return bucket; + bucket = (bucket + 1) % max_assets; + } + return -1; } Asset* Asset_Arena::load(const char* name) { char magic[4]; - Pack_File* f = pack_open_file(p, name); + Pack_File* f; + int b = bucket(name); + assert(b >= 0); + if (assets[b].name) + return assets[b].asset; + f = pack_open_file(p, name); if (!f) return 0; pack_read(f, magic, 4); pack_seek(f, 0, seek_rel_start); @@ -105,7 +126,8 @@ Asset* Asset_Arena::load(const char* name) { Asset* asset = loader.load(a, s, f); if (asset) { asset->loader = &loader; - claim(asset); + assets[b].name = dup_string(a, name); + assets[b].asset = asset; } pack_close_file(f); return asset; diff --git a/asset.hpp b/asset.hpp index db53414..c149e0a 100644 --- a/asset.hpp +++ b/asset.hpp @@ -7,7 +7,6 @@ struct Pack_File; struct Pack; struct Asset { - Asset* next; Asset_Loader* loader; }; @@ -19,13 +18,19 @@ struct Asset_Loader { struct Asset_Arena { Pack* p; Arena* a, * s; - Asset* assets; - - void init(Arena* arena, const char* pack_name); + struct Bucket { + char* name; + Asset* asset; + }; + Bucket* assets; + int max_assets; + + void init(Arena* arena, const char* pack_name, int max); void destroy(); Asset* load(const char* name); - void claim(Asset* a); + + int bucket(const char* name); }; void register_asset_loader( diff --git a/c2.cpp b/c2.cpp index 29f3955..d3b414b 100644 --- a/c2.cpp +++ b/c2.cpp @@ -102,7 +102,7 @@ extern "C" int entrypoint() { arena_alloc(app->arena, ui_arena_size), ui_arena_size ); - assets.init(&asset_arena, "pack"); + assets.init(&asset_arena, "pack", 128); dev = Device::create(&video_arena, app); model_loader.init(dev, &assets); register_asset_loader("MODL", &model_loader); -- cgit v1.2.3-54-g00ecf