polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 089461edd69dcef733ef1c09c9c14a339bbff5a2
parent a1efa0bf5f3b85e04c5819a8ec54cc8722a7e659
Author: William Casarin <jb55@jb55.com>
Date:   Fri,  5 Jul 2019 13:24:32 -0700

static resources wip

Diffstat:
Msrc/entity.c | 9++++++++-
Msrc/entity.h | 6+++++-
Msrc/game.c | 6+++---
Msrc/geometry.c | 4+++-
Msrc/geometry.h | 2+-
Msrc/model.c | 34+++++++++++++++++++---------------
Msrc/model.h | 9+--------
Msrc/node.c | 10+++-------
Msrc/node.h | 9++++++++-
Msrc/resource.c | 77+++++++++++++++++++++++++++--------------------------------------------------
Msrc/resource.h | 10++--------
Asrc/static_resources.h | 26++++++++++++++++++++++++++
Msrc/terrain.c | 6++++--
Mtest/test_resource.c | 12++++++------
Mtest/test_scene.c | 2+-
15 files changed, 117 insertions(+), 105 deletions(-)

diff --git a/src/entity.c b/src/entity.c @@ -48,6 +48,7 @@ struct entity *new_entity_(entity_id *id) { } + struct entity *new_entity_with_node(entity_id *id, node_id *node) { entity_id new_id; @@ -108,7 +109,13 @@ void destroy_entity_system() { void init_entity_system() { init_resource_manager(&esys, sizeof(struct entity), DEF_NUM_ENTITIES, - MAX_ENTITIES, "entity"); + MAX_ENTITIES, "entity", RESERVED_ENTITIES); + + for (int i = 0; i < RESERVED_ENTITIES; i++) { + node_id node_id = make_static_id(i); + struct entity *ent = &static_entities()[i]; + init_entity(ent, &node_id); + } } diff --git a/src/entity.h b/src/entity.h @@ -8,7 +8,6 @@ #include "util.h" #include <assert.h> -#define RESERVED_ENTITIES 2 #define MAX_ENTITIES 2048 enum entity_flags { @@ -39,6 +38,11 @@ struct entity *new_entity_(entity_id *); struct entity *new_entity_with_node(entity_id *, node_id *); void destroy_entity_system(); +static inline struct entity *static_entities() +{ + return (struct entity*)_internal_get_entity_system()->resources; +} + static inline struct entity *new_entity(entity_id *id) { if (id) diff --git a/src/game.c b/src/game.c @@ -172,10 +172,10 @@ void game_init(struct game *game, int width, int height) { // player entity init_id(&res->player_id); - player = new_entity(&res->player_id); - struct node *pnode = get_node(&player->node_id); + player = &static_entities()[entity_player]; + struct node *pnode = &static_nodes()[node_player]; assert(pnode); - assert(res->player_id.index == 1); + assert(res->player_id.index == entity_player); /* player->model_id = get_static_model(model_pirate_officer, NULL); */ struct model *pmodel = new_model(&player->model_id); assert(pmodel); diff --git a/src/geometry.c b/src/geometry.c @@ -3,6 +3,7 @@ #include "util.h" #include "resource.h" #include "debug.h" +#include "static_resources.h" #include <assert.h> static struct resource_manager geom_manager; @@ -173,7 +174,8 @@ void geometry_centroid(struct geometry *geom, float *dest) { void init_geometry_manager() { init_resource_manager(&geom_manager, sizeof(struct geometry), - DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry", NULL); + DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry", + NUM_STATIC_MODELS); } struct geometry *get_geometry(geometry_id *geom_id) { diff --git a/src/geometry.h b/src/geometry.h @@ -7,7 +7,7 @@ #include "shader.h" #include "resource.h" -#define DEF_NUM_GEOMETRY 32 +#define DEF_NUM_GEOMETRY 64 #define MAX_GEOMETRY 1024 // -1 is uninitialized diff --git a/src/model.c b/src/model.c @@ -3,11 +3,12 @@ #include "ply.h" #include "resource.h" #include "debug.h" +#include "util.h" #include <assert.h> #define MODELDEF(name) { .id = model_##name, .loaded = 0, .file = #name } -static struct model_def static_models[NUM_STATIC_MODELS] = { +static struct model_def static_model_defs[NUM_STATIC_MODELS] = { MODELDEF(tower), MODELDEF(icosphere), MODELDEF(pirate_officer), @@ -15,8 +16,6 @@ static struct model_def static_models[NUM_STATIC_MODELS] = { static struct resource_manager dyn_modelman; -static int static_models_initialized = 0; - struct model *init_model(struct model *model) { init_id(&model->geom_id); model->shading = SHADING_VERT_COLOR; @@ -24,13 +23,18 @@ struct model *init_model(struct model *model) { return model; } +static inline struct model *static_models() +{ + return (struct model *)dyn_modelman.resources; +} + + static void initialize_static_models() { + struct model *models = static_models(); for (int i = 0; i < NUM_STATIC_MODELS; i++) { - struct model_def *sm = &static_models[i]; - assert(sm->id == i); - init_model(&sm->model); + struct model *sm = &models[i]; + init_model(sm); } - static_models_initialized = 1; } static inline struct model *new_uninitialized_model(struct resource_id *id) { @@ -46,9 +50,13 @@ static struct model *new_model_resource(model_id *model_id) return model; } -void init_model_manager() { +void init_model_manager() +{ init_resource_manager(&dyn_modelman, sizeof(struct model), - DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS, "model"); + DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS, "model", + NUM_STATIC_MODELS); + + initialize_static_models(); } @@ -63,15 +71,11 @@ struct model *get_model(model_id *model_id) return get_resource(&dyn_modelman, model_id); } - static struct model *load_static_model(enum static_model m) { static char path[128] = {0}; - if (!static_models_initialized) - initialize_static_models(); - - struct model *model = &static_models[m].model; + struct model *model = &static_models()[m]; if (is_id_allocated(&model->geom_id) && get_geometry(&model->geom_id)) return model; @@ -79,7 +83,7 @@ static struct model *load_static_model(enum static_model m) int ok = 0; // Load mesh - snprintf(path, 128, "data/models/%s.ply", static_models[m].file); + snprintf(path, 128, "data/models/%s.ply", static_model_defs[m].file); ok = parse_ply(path, &model->geom_id); if (!ok) return 0; diff --git a/src/model.h b/src/model.h @@ -7,6 +7,7 @@ #include "shader.h" #include "geometry.h" #include "common.h" +#include "static_resources.h" #define DEF_DYNAMIC_MODELS 128 #define MAX_STATIC_MODELS 128 @@ -14,13 +15,6 @@ typedef struct resource_id model_id; -enum static_model { - model_tower, - model_icosphere, - model_pirate_officer, - NUM_STATIC_MODELS -}; - enum shading { SHADING_TERRAIN, SHADING_VERT_COLOR, @@ -38,7 +32,6 @@ struct model_def { u16 id; int loaded; char *file; - struct model model; }; diff --git a/src/node.c b/src/node.c @@ -3,12 +3,13 @@ #include "node.h" #include "mat_util.h" #include "debug.h" +#include "static_resources.h" #include <string.h> #include <stdio.h> #include <assert.h> #include <stdint.h> -static struct resource_manager node_manager = {0}; +struct resource_manager node_manager = {0}; static inline struct node *new_uninitialized_node(node_id *id) { @@ -40,13 +41,8 @@ void destroy_node(node_id *id) void init_node_manager() { - struct static_resources nodes = { - .count = 0, - .capacity = N_STATIC_NODES, - }; - init_resource_manager(&node_manager, sizeof(struct node), 128, - 0xFFFF, "node", &nodes); + 0xFFFF, "node", N_STATIC_NODES); } struct node *node_init(struct node *node) { diff --git a/src/node.h b/src/node.h @@ -5,7 +5,6 @@ #include "resource.h" #define MAX_NODE_CHILDREN 4 -#define N_STATIC_NODES 32 enum node_flags { NODE_IGNORE_RECALC = 1 << 0 @@ -50,4 +49,12 @@ struct node *new_node(node_id *); void destroy_node(node_id *); void init_node_manager(); + +extern struct resource_manager node_manager; + +static inline struct node *static_nodes() +{ + return (struct node*)node_manager.resources; +} + #endif /* POLYADVENT_NODE_H */ diff --git a/src/resource.c b/src/resource.c @@ -21,11 +21,6 @@ static inline void *index_resource(struct resource_manager *r, int i) } -static inline void *index_static_resource(struct resource_manager *r, int i) -{ - return index_resource_(r->static_res.resources, r->elem_size, i); -} - void *get_all_resources(struct resource_manager *r, u32 *count, struct resource_id **ids) { if (count != 0) *count = r->resource_count; @@ -49,36 +44,31 @@ void null_id(struct resource_id *id) id->index = -1; } +static void init_static_ids(struct resource_manager *r) +{ + for (u32 i = 0; i < r->static_elems; i++) + r->ids[i] = make_static_id(i); +} + void init_resource_manager(struct resource_manager *r, u32 elem_size, u32 initial_elements, u32 max_elements, const char *name, - struct static_resources *static_res) + int static_elems) { r->generation = 1; - r->resource_count = 0; + r->resource_count = static_elems; r->elem_size = elem_size; r->max_capacity = max_elements; - r->current_capacity = initial_elements; + r->current_capacity = initial_elements + static_elems; r->name = name; - - if (static_res) { - r->static_res = *static_res; - - if (r->static_res.resources == NULL) { - r->static_res.resources = - calloc(r->static_res.capacity, elem_size); - } - } - else { - r->static_res.count = 0; - r->static_res.capacity = 0; - r->static_res.resources = NULL; - } + r->static_elems = static_elems; assert(initial_elements != 0); - r->resources = calloc(initial_elements, elem_size); - r->ids = calloc(initial_elements, sizeof(struct resource_id)); + r->resources = calloc(r->current_capacity, elem_size); + r->ids = calloc(r->current_capacity, sizeof(struct resource_id)); + + init_static_ids(r); } void destroy_resource_manager(struct resource_manager *r) { @@ -95,7 +85,7 @@ static int refresh_id(struct resource_manager *r, struct resource_id *id, /* debug("id %llu gen %d != res gen %d, refreshing\n", */ /* id->uuid, id->generation, r->generation); */ // try to find uuid in new memory layout - for (u32 i = 0; i < r->resource_count; i++) { + for (u32 i = r->static_elems; i < r->resource_count; i++) { struct resource_id *newer_id = &r->ids[i]; if (newer_id->uuid == id->uuid) { /* debug("found %llu, ind %d -> %d\n", new_id->uuid, new_id->index, new->index); */ @@ -125,13 +115,6 @@ static void new_id(struct resource_manager *r, struct resource_id *id) assert(id->generation); } -static void new_static_id(struct resource_manager *r, struct resource_id *id) -{ - id->index = r->static_res.count; - id->uuid = STATIC_UUID; - id->generation = 0xFFFFFFFF; -} - static void resize(struct resource_manager *r) { debug("resizing %s resources, count %d+1 > current capacity %d\n", @@ -167,7 +150,7 @@ void print_id(struct resource_id *id, int nl) int is_static = is_static_resource(id); if (is_static) { - printf("sid(%llu @ %d)%s", id->uuid & ~U64HOB, id->index, nl?"\n":""); + printf("sid(%d)%s", id->index, nl?"\n":""); return; } @@ -175,20 +158,6 @@ void print_id(struct resource_id *id, int nl) id->uuid, id->index, id->generation, nl?"\n":""); } -void *new_static_resource(struct resource_manager *r, - struct resource_id *id) -{ - assert(r->static_res.resources); - assert(id); - assert(id->index == 0xFFFFFFFF && "res_id is uninitialized"); - assert(r->static_res.count + 1 < r->static_res.capacity); - if (r->static_res.count + 1 < r->static_res.capacity) - return NULL; // we're full - - new_static_id(r, id); - - return index_static_resource(r, r->static_res.count++); -} void *new_resource(struct resource_manager *r, struct resource_id *id) { @@ -211,13 +180,13 @@ void *new_resource(struct resource_manager *r, struct resource_id *id) return index_resource(r, r->resource_count++); } + void *get_static_resource(struct resource_manager *r, struct resource_id *id) { - assert(r->static_res.capacity > 0 && "trying to get a static " - "resource on a manager doesn't have static resources"); + assert(id->index < r->static_elems && "oob static index"); - return index_static_resource(r, id->index); + return index_resource(r, id->index); } void *get_resource(struct resource_manager *r, struct resource_id *id) { @@ -243,12 +212,20 @@ void *get_resource(struct resource_manager *r, struct resource_id *id) { void destroy_resource(struct resource_manager *r, struct resource_id *id) { + assert(id->index >= r->static_elems && "cant destroy a static resource"); + + if (id->index < r->static_elems) { + unusual("trying to destroy a static %s resource #%d\n", r->name, id->index); + return; + } + if (is_resource_destroyed(id)) { unusual("trying to destroy resource %llu which was already destroyed\n", id->uuid); return; } enum refresh_status res = refresh_id(r, id, id); + // entity already deleted /* debug("refresh res %d uuid %llu gen %d index %d\n", res, */ /* id->uuid, id->generation, id->index); */ diff --git a/src/resource.h b/src/resource.h @@ -18,16 +18,10 @@ struct resource_id { u32 generation; }; -struct static_resources { - u8 *resources; - u32 count; - u32 capacity; -}; - struct resource_manager { u8 *resources; - struct static_resources static_res; struct resource_id *ids; + u32 static_elems; u32 resource_count; u32 generation; u32 elem_size; @@ -53,7 +47,7 @@ void null_id(struct resource_id *id); void init_resource_manager(struct resource_manager *r, u32 elem_size, u32 initial_elements, u32 max_elements, const char *name, - struct static_resources *static_res + int static_resources ); diff --git a/src/static_resources.h b/src/static_resources.h @@ -0,0 +1,26 @@ + +#ifndef STATIC_RESOURCES_H +#define STATIC_RESOURCES_H + +enum static_model { + model_tower, + model_icosphere, + model_pirate_officer, + NUM_STATIC_MODELS +}; + +enum static_entities { + entity_terrain, + entity_player, + RESERVED_ENTITIES +}; + +// this should align with static entities +enum static_nodes { + node_terrain, + node_player, + N_STATIC_NODES +}; + + +#endif /* STATIC_RESOURCES_H */ diff --git a/src/terrain.c b/src/terrain.c @@ -55,11 +55,13 @@ void reset_terrain(struct terrain *terrain, float size) { void init_terrain(struct terrain *terrain, float size) { init_id(&terrain->entity_id); - struct entity *ent = new_entity(&terrain->entity_id); - struct node *node = get_node(&ent->node_id); assert(node); + struct entity *ent = &static_entities()[entity_terrain]; + struct node *node = &static_nodes()[node_terrain]; struct model *model = new_model(&ent->model_id); assert(model); /* struct model *model = init_model(&ent->model_id); assert(model); */ + terrain->entity_id = make_static_id(entity_terrain); + assert(terrain->entity_id.index == 0); model->shading = SHADING_TERRAIN; diff --git a/test/test_resource.c b/test/test_resource.c @@ -36,7 +36,7 @@ static void test_compact() int *p; u32 i; - init_resource_manager(&r, sizeof(int), 2, 6, "int"); + init_resource_manager(&r, sizeof(int), 2, 6, "int", 0); for (i = 0; i < (int)ARRAY_SIZE(ids); i++) init_id(&ids[i]); @@ -86,7 +86,7 @@ static void test_int_resource_manager() struct resource_id id, first_id; int *p; // 2 item case - init_resource_manager(&r, sizeof(int), 1, 2, "int"); + init_resource_manager(&r, sizeof(int), 1, 2, "int", 0); init_id(&id); init_id(&first_id); @@ -124,16 +124,16 @@ static void test_entity_system() init_id(&ent_id); ents = get_all_entities(&count, &ids); - assert(count == 0); + assert(count == RESERVED_ENTITIES); ent = new_entity(&ent_id); ents = get_all_entities(&count, &ids); assert(ent != NULL); - assert(count == 1); - assert(&ents[0] == ent); + assert(count == 1+RESERVED_ENTITIES); + assert(&ents[RESERVED_ENTITIES] == ent); - assert(ideq(&ids[0], &ent_id)); + assert(ideq(&ids[RESERVED_ENTITIES], &ent_id)); destroy_entity_system(); } diff --git a/test/test_scene.c b/test/test_scene.c @@ -17,7 +17,7 @@ void delete_every_other_entity() u32 count; entity_id *ids; - for (u32 i = RESERVED_ENTITIES; i < 1000; i++) { + for (u32 i = 0; i < 1000; i++) { get_all_entities(&count, &ids); if (i >= count)