diff options
author | quou <quou@disroot.org> | 2024-12-29 13:54:35 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-12-29 13:55:35 +1100 |
commit | f107689be915d96363ea75889631939c62f07980 (patch) | |
tree | a4b54d5145f12ee946dd24c18e6f6d5225a4d997 | |
parent | 928eba3845d6017d133048cf04c1f816d87941b0 (diff) |
cache assets to avoid loading them more than once
-rw-r--r-- | asset.cpp | 46 | ||||
-rw-r--r-- | asset.hpp | 15 | ||||
-rw-r--r-- | c2.cpp | 2 |
3 files changed, 45 insertions, 18 deletions
@@ -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; @@ -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( @@ -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); |