added asset manager
This commit is contained in:
parent
1f46acf0f7
commit
5e494bac1b
100
src/assets.c
Normal file
100
src/assets.c
Normal 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
28
src/assets.h
Normal 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
|
Loading…
Reference in a new issue