From ce13cd4be59c0415877571d92aaea3fd0d5a7e49 Mon Sep 17 00:00:00 2001 From: zlago Date: Wed, 2 Oct 2024 20:39:39 +0200 Subject: entities --- src/loader.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 96 insertions(+), 10 deletions(-) (limited to 'src/loader.c') diff --git a/src/loader.c b/src/loader.c index 6a50341..3b39bca 100644 --- a/src/loader.c +++ b/src/loader.c @@ -39,6 +39,22 @@ struct blob_collection { } items[]; } *textures = NULL, *maps = NULL, *collisions = NULL; +struct newfun_collection { + size_t count; + struct newfun_item { + struct entity *(*fun)(void); + name_T name; + } *items; +} newfuns = {0, NULL}; + +struct setfun_collection { + size_t count; + struct setfun_item { + int (*fun)(struct entity *const restrict self, char const *const restrict key, char const *const restrict value); + name_T name; + } *items; +} setfuns = {0, NULL}; + static int name_compare(name_T a, name_T b) { return strcmp(a, b); // return (a > b) - (a < b); @@ -124,24 +140,40 @@ void res_free_collision(void) { collisions = NULL; } +void res_free_newfun(void) { + for (size_t i = 0; i < newfuns.count; i++) { + free(newfuns.items[i].name); + } + free(newfuns.items); + newfuns.count = 0; +} + +void res_free_setfun(void) { + for (size_t i = 0; i < setfuns.count; i++) { + free(setfuns.items[i].name); + } + free(setfuns.items); + setfuns.count = 0; +} + static int res_compare_blobs(void const *a, void const *b) { struct blob_item const *aa = a, *bb = b; return name_compare(aa->name, bb->name); } +static int res_compare_newfuns(void const *a, void const *b) { + struct newfun_item const *aa = a, *bb = b; + return name_compare(aa->name, bb->name); +} + +static int res_compare_setfuns(void const *a, void const *b) { + struct setfun_item const *aa = a, *bb = b; + return name_compare(aa->name, bb->name); +} + static struct blob res_get_blob(name_T const name, struct blob_collection *collection) { struct blob_item new = {.name = name}; struct blob_item *dst = bsearch(&new, collection->items, collection->count, sizeof (struct blob_item), res_compare_blobs); - #if 0 - fprintf(stderr, "== chunk %zu ==\n", dst - collection->items); - for (int i = 0; i < collection->count; i++) { - fprintf(stderr, "= %s, %p\n", collection->items[i].name, collection->items[i].blob.data); - } - if (dst != NULL) - fprintf(stderr, "== value %p ==\n", dst->blob.data); - else - fprintf(stderr, "== not found ==\n"); - #endif if (dst == NULL) { return (struct blob) {.data = NULL, .size = 0}; } @@ -160,6 +192,24 @@ struct blob res_get_collision(name_T const name) { return res_get_blob(name, collisions); } +struct entity *(*res_get_newfun(name_T const name))(void) { + struct newfun_item new = {.name = name}; + struct newfun_item *dst = bsearch(&new, newfuns.items, newfuns.count, sizeof (struct newfun_item), res_compare_newfuns); + if (dst == NULL) { + return NULL; + } + return dst->fun; +} + +int (*res_get_setfun(name_T const name))(struct entity *const restrict self, char const *const restrict key, char const *const restrict value) { + struct setfun_item new = {.name = name}; + struct setfun_item *dst = bsearch(&new, setfuns.items, setfuns.count, sizeof (struct setfun_item), res_compare_setfuns); + if (dst == NULL) { + return NULL; + } + return dst->fun; +} + static struct blob_collection *res_push_blob(struct blob *blob, name_T name, struct blob_collection *collection, void (*freeFunc)(void *)) { int found; struct blob_item new = {.blob = *blob, .name = name}; @@ -206,6 +256,42 @@ void res_push_collision(struct blob *blob, name_T name) { collisions = res_push_blob(blob, name, collisions, blob_free_func); } +void res_push_newfun(struct entity *(*newfun)(void), name_T name) { + int found; + struct newfun_item new = {.fun = newfun, .name = name}; + struct newfun_item *dst = bsearchinsertposition(&new, newfuns.items, newfuns.count, sizeof (struct newfun_item), res_compare_newfuns, &found); + if (found) { + fprintf(stderr, "warn: name collision: %s\n", new.name); + free(dst->name); + memcpy(dst, &new, sizeof (struct newfun_item)); + } else { + size_t index = dst - newfuns.items; // hack + newfuns.count++; + newfuns.items = realloc(newfuns.items, sizeof (struct newfun_item) * newfuns.count); + dst = newfuns.items + index; // hack for the struct having been reallocated + memmove(dst + 1, dst, sizeof (struct newfun_item) * (newfuns.count - 1 - (dst - newfuns.items))); + memcpy(dst, &new, sizeof (struct newfun_item)); + } +} + +void res_push_setfun(int (*setfun)(struct entity *const restrict self, char const *const restrict key, char const *const restrict value), name_T name) { + int found; + struct setfun_item new = {.fun = setfun, .name = name}; + struct setfun_item *dst = bsearchinsertposition(&new, setfuns.items, setfuns.count, sizeof (struct setfun_item), res_compare_setfuns, &found); + if (found) { + fprintf(stderr, "warn: name collision: %s\n", new.name); + free(dst->name); + memcpy(dst, &new, sizeof (struct setfun_item)); + } else { + size_t index = dst - setfuns.items; // hack + setfuns.count++; + setfuns.items = realloc(setfuns.items, sizeof (struct setfun_item) * setfuns.count); + dst = setfuns.items + index; // hack for the struct having been reallocated + memmove(dst + 1, dst, sizeof (struct setfun_item) * (setfuns.count - 1 - (dst - setfuns.items))); + memcpy(dst, &new, sizeof (struct setfun_item)); + } +} + int loadResources(char *filename) { // open the file FILE *zip = fopen(filename, "rb"); -- cgit 1.4.1-2-gfad0