commit a1efa0bf5f3b85e04c5819a8ec54cc8722a7e659
parent 640f12d0e6bc5ed7944d999ce5c1c131d22eb63a
Author: William Casarin <jb55@jb55.com>
Date: Fri, 5 Jul 2019 10:40:00 -0700
wip: static resources
Diffstat:
12 files changed, 143 insertions(+), 68 deletions(-)
diff --git a/src/common.h b/src/common.h
@@ -8,6 +8,7 @@ typedef int bool;
#define MAT3_ELEMS 9
#define MAT4_ELEMS 16
+#define U64HOB 0x8000000000000000
#define SLAB(f) "etc/slab/" f
#define RESOURCE(f) "etc/shaders/" f
diff --git a/src/entity.c b/src/entity.c
@@ -21,7 +21,7 @@ struct entity *get_all_entities(u32 *count, entity_id **ids) {
struct entity *init_entity(struct entity *ent, node_id *id) {
node_id new_id;
- init_model_id(&ent->model_id);
+ init_id(&ent->model_id);
if (id == NULL) {
init_id(&new_id);
new_node(&new_id);
diff --git a/src/geometry.c b/src/geometry.c
@@ -5,7 +5,6 @@
#include "debug.h"
#include <assert.h>
-
static struct resource_manager geom_manager;
void
@@ -174,7 +173,7 @@ 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");
+ DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry", NULL);
}
struct geometry *get_geometry(geometry_id *geom_id) {
diff --git a/src/model.c b/src/model.c
@@ -17,13 +17,6 @@ static struct resource_manager dyn_modelman;
static int static_models_initialized = 0;
-void init_model_id(model_id *id)
-{
- /* assert((int)id->dyn_model_id.index != -1); */
- id->type = DYNAMIC_MODEL;
- init_id(&id->dyn_model_id);
-}
-
struct model *init_model(struct model *model) {
init_id(&model->geom_id);
model->shading = SHADING_VERT_COLOR;
@@ -46,7 +39,7 @@ static inline struct model *new_uninitialized_model(struct resource_id *id) {
static struct model *new_model_resource(model_id *model_id)
{
- struct model *model = new_uninitialized_model(&model_id->dyn_model_id);
+ struct model *model = new_uninitialized_model(model_id);
/* debug("new model %llu\n", model_id->dyn_model_id.uuid); */
init_id(&model->geom_id);
new_geometry(&model->geom_id);
@@ -61,23 +54,13 @@ void init_model_manager() {
struct model *new_model(model_id *id)
{
- id->type = DYNAMIC_MODEL;
return new_model_resource(id);
}
+
struct model *get_model(model_id *model_id)
{
-
- switch(model_id->type) {
- case DYNAMIC_MODEL:
- return get_resource(&dyn_modelman, &model_id->dyn_model_id);
- case STATIC_MODEL: {
- struct model *model;
- get_static_model(model_id->static_model_id, &model);
- return model;
- }
- }
- assert(!"unhandled case in get_model");
+ return get_resource(&dyn_modelman, model_id);
}
@@ -106,26 +89,22 @@ static struct model *load_static_model(enum static_model m)
void destroy_model(model_id *model_id)
{
- if (model_id->type == STATIC_MODEL)
+ if (is_static_resource(model_id))
return;
- struct resource_id *id = &model_id->dyn_model_id;
struct model *model = get_model(model_id);
destroy_geometry(&model->geom_id);
- destroy_resource(&dyn_modelman, id);
+ destroy_resource(&dyn_modelman, model_id);
}
+
model_id get_static_model(enum static_model m, struct model **model)
{
- model_id model_id;
- model_id.type = STATIC_MODEL;
- model_id.static_model_id = m;
-
if (model)
*model = load_static_model(m);
- return model_id;
+ return make_static_id(m);
}
diff --git a/src/model.h b/src/model.h
@@ -12,6 +12,8 @@
#define MAX_STATIC_MODELS 128
#define MAX_DYNAMIC_MODELS 2048
+typedef struct resource_id model_id;
+
enum static_model {
model_tower,
model_icosphere,
@@ -19,21 +21,6 @@ enum static_model {
NUM_STATIC_MODELS
};
-enum model_type {
- STATIC_MODEL,
- DYNAMIC_MODEL
-};
-
-typedef struct model_id_t
-{
- enum model_type type;
- union {
- struct resource_id dyn_model_id;
- enum static_model static_model_id;
- };
-} model_id;
-
-
enum shading {
SHADING_TERRAIN,
SHADING_VERT_COLOR,
diff --git a/src/node.c b/src/node.c
@@ -40,7 +40,13 @@ void destroy_node(node_id *id)
void init_node_manager()
{
- init_resource_manager(&node_manager, sizeof(struct node), 128, 0xFFFF, "node");
+ struct static_resources nodes = {
+ .count = 0,
+ .capacity = N_STATIC_NODES,
+ };
+
+ init_resource_manager(&node_manager, sizeof(struct node), 128,
+ 0xFFFF, "node", &nodes);
}
struct node *node_init(struct node *node) {
diff --git a/src/node.h b/src/node.h
@@ -5,6 +5,7 @@
#include "resource.h"
#define MAX_NODE_CHILDREN 4
+#define N_STATIC_NODES 32
enum node_flags {
NODE_IGNORE_RECALC = 1 << 0
diff --git a/src/resource.c b/src/resource.c
@@ -9,10 +9,21 @@
static u64 resource_uuids = 0;
-static inline void *index_resource(struct resource_manager *r, int i) {
- unsigned char *p = r->resources;
- assert(p);
- return p + (i * r->elem_size);
+static inline void *index_resource_(u8 *res, u32 elem_size, int i)
+{
+ assert(res);
+ return res + (i * elem_size);
+}
+
+static inline void *index_resource(struct resource_manager *r, int i)
+{
+ return index_resource_(r->resources, r->elem_size, 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) {
@@ -39,7 +50,10 @@ 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) {
+ u32 initial_elements, u32 max_elements,
+ const char *name,
+ struct static_resources *static_res)
+{
r->generation = 1;
r->resource_count = 0;
r->elem_size = elem_size;
@@ -47,6 +61,20 @@ void init_resource_manager(struct resource_manager *r, u32 elem_size,
r->current_capacity = initial_elements;
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;
+ }
+
assert(initial_elements != 0);
r->resources = calloc(initial_elements, elem_size);
@@ -97,6 +125,13 @@ 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",
@@ -129,14 +164,37 @@ static void resize(struct resource_manager *r)
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":"");
+ return;
+ }
+
printf("id(u:%llu i:%d g:%d)%s",
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)
{
assert(id);
- assert((int)id->index == -1 && "res_id is uninitialized");
+ assert(id->uuid != STATIC_UUID && "called new_resource with a static id");
+ assert(id->index == 0xFFFFFFFF && "res_id is uninitialized");
struct resource_id *fresh_id;
@@ -147,16 +205,25 @@ void *new_resource(struct resource_manager *r, struct resource_id *id)
resize(r);
fresh_id = &r->ids[r->resource_count];
-
new_id(r, fresh_id);
-
- if (id)
- *id = *fresh_id;
+ *id = *fresh_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");
+
+ return index_static_resource(r, id->index);
+}
+
void *get_resource(struct resource_manager *r, struct resource_id *id) {
+ if (id->uuid == STATIC_UUID)
+ return get_static_resource(r, id);
+
assert((int64_t)id->generation != -1 && "id intialized but not allocated (needs new_ call)");
if (id->generation == 0) {
@@ -214,8 +281,3 @@ void destroy_resource(struct resource_manager *r, struct resource_id *id) {
r->ids[i].index--;
}
}
-
-int is_id_allocated(struct resource_id *id)
-{
- return (int)id->index != -1;
-}
diff --git a/src/resource.h b/src/resource.h
@@ -4,6 +4,8 @@
#include "common.h"
+#define STATIC_UUID 0x5A51C00000000000
+
enum refresh_status {
RESOURCE_DELETED,
REFRESH_NOT_NEEDED,
@@ -16,8 +18,15 @@ 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 resource_count;
u32 generation;
@@ -25,22 +34,47 @@ struct resource_manager {
u32 slots_used;
u32 max_capacity;
u32 current_capacity;
+
const char *name;
};
#define ideq(a, b) ((a)->uuid == (b)->uuid)
-int is_id_allocated(struct resource_id *id);
void init_id(struct resource_id *id);
void *get_resource(struct resource_manager *r, struct resource_id *id);
void *get_all_resources(struct resource_manager *, u32 *count, struct resource_id **ids);
void destroy_resource(struct resource_manager *, struct resource_id *id);
void destroy_resource_manager(struct resource_manager *);
void *new_resource(struct resource_manager *, struct resource_id *id);
+void *new_static_resource(struct resource_manager *, struct resource_id *id);
void print_id(struct resource_id *, int nl);
void null_id(struct resource_id *id);
+/* int is_static_resource(struct resource_id *id); */
void init_resource_manager(struct resource_manager *r, u32 elem_size,
- u32 initial_elements, u32 max_elements, const char *name);
+ u32 initial_elements, u32 max_elements, const char *name,
+ struct static_resources *static_res
+ );
+
+
+static inline struct resource_id make_static_id(u32 index)
+{
+ return (struct resource_id){
+ .uuid = STATIC_UUID,
+ .index = index,
+ .generation = -1
+ };
+}
+
+static inline int is_static_resource(struct resource_id *id)
+{
+ return id->uuid == STATIC_UUID;
+}
+
+
+static inline int is_id_allocated(struct resource_id *id)
+{
+ return (int)id->index != -1;
+}
#endif /* RESOURCE_H */
diff --git a/src/scene.c b/src/scene.c
@@ -55,7 +55,7 @@ void entity_test_scene(struct game *game)
player->model_id = get_static_model(model_pirate_officer, NULL);
model_id rock_model;
- init_model_id(&rock_model);
+ init_id(&rock_model);
/* model_id rock_model = get_static_model(model_tower, NULL); */
struct model *pmodel = new_model(&rock_model); assert(pmodel);
diff --git a/src/skybox.c b/src/skybox.c
@@ -39,7 +39,7 @@ void create_skybox(struct skybox *skybox, struct gpu_program *program) {
int ok;
node_init(&skybox->node);
- init_model_id(&skybox->model_id);
+ init_id(&skybox->model_id);
skybox->program = program;
diff --git a/todo.org b/todo.org
@@ -3,11 +3,17 @@
* TODO Proc Trees :procgen:
* TODO [#A] Instance rendering for ground debris :perf:rendering:
* TODO [#B] Load bone weights :anim:
+:LOGBOOK:
+CLOCK: [2019-07-05 Fri 09:28]
+:END:
* TODO Simple pthreads job system :jobs:threads:
-* TODO Run pose :anim:
-* TODO Simple animation test :anim:
+* Run pose :anim:
+:LOGBOOK:
+CLOCK: [2019-07-05 Fri 09:28]--[2019-07-05 Fri 09:28] => 0:00
+:END:
+
* TODO Initial physics system :physics:
* TODO Entity loading stress test :perf: