added asset manager

This commit is contained in:
Sara 2023-09-24 23:39:39 +02:00
parent 1f46acf0f7
commit 5e494bac1b
2 changed files with 128 additions and 0 deletions

100
src/assets.c Normal file
View file

@ -0,0 +1,100 @@
#include "assets.h"
#include <stdlib.h>
#include <memory.h>
typedef
struct AssetData {
void* asset;
asset_id id;
AssetDestructor destructor;
} AssetData;
static AssetData* _assets = NULL;
static size_t _assets_len = 0;
static size_t _assets_cap = 0;
static asset_id _next_id = 0;
static
void _resize_if_needed(size_t requested_len) {
if(requested_len < _assets_cap) {
return; // not needed.
}
size_t new_cap = _assets_cap ? _assets_cap : 8;
while(new_cap < requested_len) {
new_cap *= 2;
}
AssetData* new_assets = realloc(_assets, new_cap * sizeof(AssetData));
if(new_assets != NULL) {
_assets = new_assets;
_assets_cap = new_cap;
}
}
void assets_init() {
_assets = malloc(_assets_cap * sizeof(AssetData));
_next_id = 1;
}
asset_id store_asset(void* asset, AssetDestructor destructor) {
_resize_if_needed(_assets_len + 1);
AssetData* data = _assets + _assets_len;
data->asset = asset;
data->destructor = destructor;
data->id = _next_id;
++_next_id;
++_assets_len;
return data->id;
}
static
AssetData* _internal_get_by_id(asset_id id) {
if(id == 0) {
return NULL;
}
for(size_t i = 0; i < _assets_len; ++i) {
if(_assets[i].id == id) {
return _assets + i;
}
}
return NULL;
}
void* get_asset(asset_id id) {
AssetData* found = _internal_get_by_id(id);
if(found != NULL) {
return found->asset;
}
return NULL;
}
asset_id get_asset_id(void* asset) {
for(size_t i = 0; i < _assets_len; ++i) {
if(_assets[i].asset == asset) {
return _assets[i].id;
}
}
return 0;
}
void free_asset(asset_id id) {
AssetData* found = _internal_get_by_id(id);
if(found == NULL) {
return;
}
found->destructor(found->asset);
AssetData* next = found + 1;
size_t dif = next - (_assets + _assets_len);
memmove(found, next, dif);
}

28
src/assets.h Normal file
View file

@ -0,0 +1,28 @@
#ifndef _fencer_assets_h
#define _fencer_assets_h
#include <stdint.h>
typedef void(*AssetDestructor)(void*);
typedef uintptr_t asset_id;
// Prepare asset management.
// Other asset management functions are invalid until assets_init is called.
void assets_init();
// Clean up and shut down assets management.
void assets_clean();
// Clear all assets and reset to initial state.
void assets_reset();
// Submit an object to be managed as an asset. If the destructor is NULL, free will be used.
// Returns zero if asset could not be stored.
asset_id store_asset(void* asset, AssetDestructor destructor);
// Get an asset already submitted to the asset manager.
// Returns 0 if asset does not exist.
void* get_asset(asset_id id);
// Get an asset id, returns 0 if no such asset exists.
asset_id get_asset_id(void* asset);
// Free an asset managed by the asset manager using it's destructor, or free(..) if NULL.
void free_asset(asset_id id);
#endif // !_fencer_assets_h