131 lines
3.3 KiB
C
131 lines
3.3 KiB
C
#include "assets.h"
|
|
#include "debug.h"
|
|
#include "list.h"
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
#include <stdio.h>
|
|
|
|
static List _assets;
|
|
static asset_id _next_id = 0;
|
|
|
|
static
|
|
size_t file_length(FILE* fp) {
|
|
long start = ftell(fp);
|
|
fseek(fp, 0, SEEK_END);
|
|
long r = ftell(fp);
|
|
fseek(fp, start, SEEK_SET);
|
|
return (size_t)r;
|
|
}
|
|
|
|
static
|
|
void read_file(FILE* fp, char* out_buffer, size_t out_size) {
|
|
long start = ftell(fp);
|
|
fread(out_buffer, 1, out_size, fp);
|
|
fseek(fp, start, SEEK_SET);
|
|
}
|
|
|
|
void assets_init() {
|
|
LOG_INFO("assets_init");
|
|
_assets = list_from_type(Asset);
|
|
_next_id = 1;
|
|
}
|
|
|
|
// clear all assets without shrinking the assets array.
|
|
static
|
|
void _empty_assets() {
|
|
list_foreach(Asset*, asset, &_assets) {
|
|
asset->drop->drop(asset->data);
|
|
}
|
|
list_empty(&_assets);
|
|
}
|
|
|
|
void assets_clean() {
|
|
_empty_assets();
|
|
}
|
|
|
|
void assets_reset() {
|
|
_empty_assets();
|
|
}
|
|
|
|
asset_id store_asset(Asset asset) {
|
|
list_reserve(&_assets, _assets.len + 1);
|
|
size_t index = list_add(&_assets, &asset);
|
|
Asset* new_asset = list_at_as(Asset, &_assets, index);
|
|
asset_id id = _next_id++;
|
|
new_asset->tc->set_id(new_asset->data, id);
|
|
asset_id actual_id = new_asset->tc->get_id(new_asset->data);
|
|
ASSERT_RETURN(actual_id == id,actual_id, "ID stored in asset not the same as the expected id");
|
|
return actual_id;
|
|
}
|
|
|
|
static
|
|
Asset* _internal_get_by_id(asset_id id) {
|
|
ASSERT_RETURN_WARN(id != 0, NULL, "Cannot get element with id 0");
|
|
|
|
list_foreach(Asset*, asset, &_assets) {
|
|
if(asset->tc->get_id(asset->data) == id) {
|
|
return asset;
|
|
}
|
|
}
|
|
|
|
RETURN_WARNING(NULL, "Failed to find requested asset with id %zu", id);
|
|
}
|
|
|
|
void* get_asset(asset_id id) {
|
|
Asset* found = _internal_get_by_id(id);
|
|
ASSERT_RETURN(found != NULL, NULL, "Failed to find asset with id %zu.", id);
|
|
return found->data;
|
|
}
|
|
|
|
asset_id get_asset_id(void* asset) {
|
|
list_foreach(Asset*, asset, &_assets) {
|
|
if(asset->data == asset) {
|
|
return asset->tc->get_id(asset->data);
|
|
}
|
|
}
|
|
|
|
RETURN_WARNING(0, "Failed to find asset referencing %p", asset);
|
|
}
|
|
|
|
void free_asset(asset_id id) {
|
|
Asset* found = NULL;
|
|
size_t found_index = _assets.len;
|
|
for(size_t i = 0; i < _assets.len; ++i) {
|
|
found = list_at_as(Asset, &_assets, i);
|
|
if(found->tc->get_id(found->data) == id) {
|
|
found_index = i;
|
|
break;
|
|
}
|
|
}
|
|
ASSERT_RETURN(found != NULL,, "Attempt to free nonexistent asset.");
|
|
found->drop->drop(found->data);
|
|
list_erase(&_assets, found_index);
|
|
}
|
|
|
|
cJSON* load_json_from_file(const char* filename) {
|
|
FILE* fp = fopen(filename, "r");
|
|
ASSERT_RETURN(fp != NULL, NULL, "Failed to open file %s.", filename);
|
|
|
|
size_t len = file_length(fp);
|
|
char* buffer = malloc(len + 1);
|
|
ASSERT_RETURN(buffer != NULL, NULL, "Failed to allocate buffer for json string.");
|
|
|
|
read_file(fp, buffer, len);
|
|
cJSON* out = cJSON_Parse(buffer);
|
|
free(buffer);
|
|
|
|
ASSERT_RETURN(out != NULL, NULL, "Failed to parse json from file %s.", filename);
|
|
|
|
return out;
|
|
}
|
|
|
|
size_t json_array_len(cJSON* json) {
|
|
ASSERT_RETURN(cJSON_IsArray(json), 0, "Tried to get the length of a non-array json element.");
|
|
size_t len = 0;
|
|
cJSON* itr;
|
|
cJSON_ArrayForEach(itr, json) {
|
|
++len;
|
|
}
|
|
return len;
|
|
}
|