diff options
Diffstat (limited to 'asset.cpp')
-rw-r--r-- | asset.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/asset.cpp b/asset.cpp new file mode 100644 index 0000000..09260e0 --- /dev/null +++ b/asset.cpp @@ -0,0 +1,101 @@ +#include "asset.hpp" + +extern "C" { +#include "memory.h" +#include "pack.h" +#include "plat.h" +#include "str.h" +} + +#define max_asset_types 32 + +struct RLoader { + char magic[4]; + Asset_Loader* loader; +}; + +struct Manager { + RLoader loaders[max_asset_types]; + + Manager() { + int i; + for (i = 0; i < max_asset_types; i++) { + loaders[i].loader = 0; + } + } + + RLoader* find_loader(const char* magic) { + uint32_t hash = hash_string(magic); + int bucket = (int)(hash % max_asset_types); + int i; + for (i = 0; i < max_asset_types; i++) { + RLoader& e = loaders[bucket]; + if (!e.loader || ( + e.magic[0] == magic[0] && + e.magic[1] == magic[1] && + e.magic[2] == magic[2] && + e.magic[3] == magic[3] + )) return &e; + bucket = (bucket + 1) % max_asset_types; + } + return 0; + } + + Asset_Loader& get_loader(const char* magic) { + RLoader* r = find_loader(magic); + assert(r != 0 && r->loader != 0); + return *r->loader; + } + + void set_loader(const char* magic, Asset_Loader* l) { + RLoader* r = find_loader(magic); + assert(r != 0 && r->loader == 0); + r->magic[0] = magic[0]; + r->magic[1] = magic[1]; + r->magic[2] = magic[2]; + r->magic[3] = magic[3]; + r->loader = l; + } +} manager; + +void register_asset_loader( + const char* magic, + Asset_Loader* loader +) { + manager.set_loader(magic, loader); +} + +void Asset_Arena::init(Arena* arena, const char* pack_name) { + p = pack_open(pack_name, arena); + a = arena; + assets = 0; +} + +void Asset_Arena::destroy() { + Asset* a; + for (a = assets; a; a = a->next) { + a->unload(a->loader); + } + pack_close(p); +} + +void Asset_Arena::claim(Asset* a) { + if (assets) { + a->next = assets; + assets = a; + } else assets = a; +} + +Asset* Asset_Arena::load(const char* name) { + char magic[4]; + Pack_File* f = pack_open_file(p, name); + if (!f) return 0; + pack_read(f, magic, 4); + pack_seek(f, 0, seek_rel_start); + Asset_Loader& loader = manager.get_loader(magic); + Asset* asset = loader.load(a, f); + asset->loader = &loader; + pack_close_file(f); + claim(asset); + return asset; +} |