209 lines
5.5 KiB
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;
|
|
}
|