kettek2/wiki/games/newsboy/Newsboy_0x00/engine/Resource.c

209 lines
5.5 KiB
C

#include <stdlib.h>
#include "Resource.h"
#include "report.h"
struct Resources *newResources(int id, int length) {
struct Resources *res = malloc(sizeof(struct Resources));
res->id = id;
res->length = length;
res->data = malloc(sizeof(void*)*length);
int i;
for (i=0;i<res->length;i++) {
res->data[i] = NULL;
}
res->loadResource_func = NULL;
res->freeResource_func = NULL;
initIdIndex(&res->index, HASH_HUGE, length);
return res;
}
int freeResources(struct Resources *resources) {
if (resources == NULL) {
report(ERROR, "freeResources", "passed Resources is NULL");
return 1;
}
int i;
for (i = 0; i < resources->length; i++) {
if (resources->data[i] != NULL) {
freeResourceById(resources, i);
}
}
freeIdIndex(&resources->index);
return 0;
}
int addResource(struct Resources *res, char *name, void *data) {
if (res == NULL) {
report(ERROR, "addResource", "passed Resource is NULL");
return -1;
}
if (data == NULL) {
report(ERROR, "addResource", "passed data is NULL");
return -2;
}
// check if entry exists for Resource
int id;
if ((id = getIdIndex(&res->index, name)) >= 0) {
//report(WARNING, "addResource", "data \"%s\" already exists", name);
return id;
} else {
if ( (id = findOpenIdIndex(&res->index)) == -1) {
resizeIdIndex(&res->index, res->length+4);
res->data = realloc(res->data, sizeof(void*)*res->length+4);
int i = 0;
for (i=res->length;i<res->length+4;i++) {
res->data[i] = NULL;
}
res->length += 4;
}
id = findOpenIdIndex(&res->index);
res->data[id] = data;
return addIdIndex(&res->index, name, id);
}
}
int remResource(struct Resources *res, char *name) {
if (res == NULL) {
report(ERROR, "remResource", "passed Resource is NULL");
return 1;
}
if (name == NULL) {
report(ERROR, "remResource", "passed name is NULL");
return 2;
}
int id;
if ((id = getIdIndex(&res->index, name)) >= 0) {
remIdIndex(&res->index, name); // TODO: replace with ById?
res->data[id] = NULL;
} else {
report(WARNING, "remResource", "data \"%s\" does not exist", name);
}
return 0;
}
int remResourceById(struct Resources *res, int id) {
if (res == NULL) {
report(ERROR, "remResourceById", "passed Resource is NULL");
return 1;
}
if (id < 0 || id > res->length) {
report(ERROR, "remResourceById", "id \"%d\" is out of range", id);
return 2;
}
if (checkIdIndexMemory(&res->index, id)) {
remIdIndexById(&res->index, id);
res->data[id] = NULL;
} else {
report(WARNING, "remResourceById", "data \"%d\" does not exist", id);
}
return 0;
}
int getResourceId(struct Resources *res, char *name) {
// TODO: ret
if (res == NULL) {
}
return getIdIndex(&res->index, name);
}
void *getResource(struct Resources *res, char *name) {
if (res == NULL) {
report(ERROR, "getResource", "passed Resource is NULL");
return NULL;
}
if (name == NULL) {
report(ERROR, "getResource", "passed name is NULL");
return NULL;
}
int id = getIdIndex(&res->index, name);
if (id >= 0) {
return(res->data[id]);
}
return NULL;
}
void *getResourceById(struct Resources *res, int id) {
if (res == NULL) {
report(ERROR, "getResourceById", "passed Resource is NULL");
return NULL;
}
if (id < 0 || id > res->length) {
report(ERROR, "getResourceById", "requested id %d is out of bounds", id);
return NULL;
}
if (checkIdIndexMemory(&res->index, id) == 1) {
return(res->data[id]);
}
return NULL;
}
int loadResource(struct Resources *res, char *filename) {
if (res == NULL) {
report(ERROR, "loadResource", "passed Resource is NULL");
return -1;
}
if (filename == NULL) {
report(ERROR, "loadResource", "passed name is NULL");
return -2;
}
int resource = 0;
if ((resource = getResourceId(res, filename)) >= 0) {
// already exists
return resource;
}
if (res->loadResource_func == NULL) {
report(WARNING, "loadResource", "internal loadResource not specified, loading in %s as binary", filename);
// TODO: add in binary loading
} else {
return addResource(res, filename, res->loadResource_func(filename));
}
return -3; // generic?
}
int freeResource(struct Resources *res, char *name) {
if (res == NULL) {
report(ERROR, "freeResource", "passed Resource is NULL");
return 1;
}
if (name == NULL) {
report(ERROR, "freeResource", "passed name is NULL");
return 2;
}
if (res->freeResource_func == NULL) {
report(WARNING, "freeResource", "internal freeResource not specified, freeing %s with free", name);
free(getResource(res, name));
remResource(res, name);
} else {
// TODO: optimize this
void *data = getResource(res, name);
if (data != NULL) {
res->freeResource_func(getResource(res, name));
remResource(res, name);
}
}
return 4;
}
int freeResourceById(struct Resources *res, int id) {
if (res == NULL) {
report(ERROR, "freeResourceById", "passed Resource is NULL");
return 1;
}
if (checkIdIndexMemory(&res->index, id) == 0) {
report(WARNING, "freeResourceById", "[%d] is already free", id);
return 2;
}
if (res->freeResource_func == NULL) {
report(WARNING, "freeResourceById", "internal freeResourceById not specified, freeing [%d] with free", id);
free(getResourceById(res, id));
remResourceById(res, id);
} else {
// TODO: optimize this
res->freeResource_func(getResourceById(res, id));
remResourceById(res, id);
}
return 3;
}