commit d46337ec1b2bf722e315d6534df25dfab11d9d02
parent ecca662a2c4afb0c5be1b7befd9c277a42a247e8
Author: William Casarin <jb55@jb55.com>
Date: Tue, 20 Nov 2018 00:34:46 -0800
more progress
Diffstat:
10 files changed, 131 insertions(+), 81 deletions(-)
diff --git a/src/entity.c b/src/entity.c
@@ -9,10 +9,8 @@
static struct resource_manager esys;
-static u64 entity_uuids = 0;
-
struct entity *get_all_entities(u32 *count, entity_id_t **ids) {
- return (struct entity*)get_all_resources(count, ids);
+ return get_all_resources(&esys, count, ids);
}
struct entity *init_entity(struct entity *ent) {
@@ -21,74 +19,35 @@ struct entity *init_entity(struct entity *ent) {
return ent;
}
-struct entity *get_entity_pure(struct entity_id id) {
- struct entity_id pure_id;
- pure_id = id;
-
- return get_entity(&pure_id);
-}
-
-struct entity *get_entity(struct entity_id *ent_id) {
- struct entity_id *new_id;
- struct id *id = &ent_id->id;
-
- // rollover is ok
- /* assert(->generation <= esys.generation); */
- if (id->generation != esys.generation) {
- // try to find uuid in new memory layout
- for (u32 i = 0; i < esys.entity_count; i++) {
- new_id = &esys.ids[i];
- if (new_id->id.uuid == id->uuid) {
- id->index = new_id->id.index;
- id->generation = esys.generation;
- return &esys.entities[id->index];
- }
- }
-
- // entity was deleted
- return NULL;
- }
- return &esys.entities[id->index];
-}
-
-static inline struct entity_id new_id() {
- return (struct entity_id){
- .id = (struct id) {
- .index = esys.resource_count,
- .uuid = entity_uuids++,
- .generation = esys.generation,
- }
- };
+struct entity *get_entity(entity_id_t *ent_id) {
+ return get_resource(&esys, ent_id);
}
-static inline struct entity *new_uninitialized_entity(struct entity_id *id) {
- struct entity_id fresh_id;
- fresh_id = new_id();
-
- if (id)
- *id = fresh_id;
-
- return &esys.entities[esys.entity_count++];
+static inline struct entity *new_uninitialized_entity(entity_id_t *id) {
+ return new_resource(&esys, id);
}
-struct entity *new_entity(struct entity_id *id) {
+struct entity *new_entity(entity_id_t *id) {
return init_entity(new_uninitialized_entity(id));
}
-struct entity *add_entity(struct entity *e, struct entity_id *id) {
+struct entity *add_entity(struct entity *e, entity_id_t *id) {
struct entity *new = new_uninitialized_entity(id);
*new = *e;
return new;
}
void destroy_entities() {
- for (u32 i = RESERVED_ENTITIES; i < esys.entity_count; i++) {
- destroy_entity(&esys.entities[i]);
+ entity_id_t *ids;
+ u32 count;
+ get_all_resources(&esys, &count, &ids);
+ for (u32 i = RESERVED_ENTITIES; i < count; i++) {
+ destroy_entity(&ids[i]);
}
- esys.entity_count = RESERVED_ENTITIES;
};
-void destroy_entity(entity_id_t id) {
+void destroy_entity(entity_id_t *id) {
+ struct entity *ent = get_entity(id);
node_detach_from_parent(&ent->node);
destroy_resource(&esys, id);
}
@@ -98,11 +57,8 @@ void destroy_entity_system() {
}
void init_entity_system() {
- esys.generation = 0;
- esys.entities = calloc(DEF_NUM_ENTITIES, sizeof(*esys.entities));
-
- esys.ids =
- calloc(DEF_NUM_ENTITIES, sizeof(*esys.ids));
+ init_resource_manager(&esys, sizeof(struct entity), DEF_NUM_ENTITIES,
+ MAX_ENTITIES);
}
diff --git a/src/entity.h b/src/entity.h
@@ -7,6 +7,7 @@
#include "id.h"
#define RESERVED_ENTITIES 2
+#define MAX_ENTITIES 2048
enum entity_flags {
ENT_IS_PLAYER = 1 << 0,
@@ -26,7 +27,7 @@ typedef struct resource_id entity_id_t;
struct entity *init_entity(struct entity *);
void destroy_entities();
-void destroy_entity(struct entity *);
+void destroy_entity(entity_id_t *);
void init_entity_system();
struct entity *get_entity(entity_id_t *);
struct entity *get_all_entities(u32 *count, entity_id_t **ids);
diff --git a/src/geometry.c b/src/geometry.c
@@ -189,14 +189,14 @@ void init_geometry_manager() {
geom_manager.num_geometry = 0;
}
-struct geometry *get_geometry(struct geometry_id geom_id) {
- assert(geom_id.index != -1);
- assert(geom_id.index < geom_manager.num_geometry);
- return &geom_manager.geoms[geom_id.index];
+struct geometry *get_geometry(geometry_id_t *geom_id) {
+ assert(geom_id->index != -1);
+ assert(geom_id->index < geom_manager.num_geometry);
+ return &geom_manager.geoms[geom_id->index];
}
-struct geometry *new_geometry(struct geometry_id *geom_id) {
+struct geometry *new_geometry(geometry_id_t *geom_id) {
u32 index = geom_manager.num_geometry++;
struct geometry *g = &geom_manager.geoms[index];
init_geometry(g);
diff --git a/src/node.c b/src/node.c
@@ -120,6 +120,7 @@ int node_detach(struct node *node, struct node *from) {
if (from->children[i] == node) {
memmove(from->children[i], from->children[i+1],
from->n_children - i - 1);
+ assert(!"fixme, this should be times the size of *children");
from->n_children--;
return 1;
}
diff --git a/src/ply.c b/src/ply.c
@@ -226,9 +226,8 @@ int parse_ply(const char *filename, geometry_id_t *geom_id) {
free((void*)data);
if (success) {
- *geom_id = make_buffer_geometry(&mkgeom);
- struct geometry *geom =
- get_geometry(*geom_id);
+ make_buffer_geometry(&mkgeom, geom_id);
+ struct geometry *geom = get_geometry(geom_id);
vec3_copy(min, geom->min);
vec3_copy(max, geom->max);
diff --git a/src/resource.c b/src/resource.c
@@ -1,5 +1,13 @@
#include "resource.h"
+#include <stdlib.h>
+#include <string.h>
+
+static u64 resource_uuids = 0;
+
+static inline void *index_resource(struct resource_manager *r, int i) {
+ return &r->resources[i * r->elem_size];
+}
void *get_all_resources(struct resource_manager *r, u32 *count, struct resource_id **ids) {
if (count != 0)
@@ -9,6 +17,86 @@ void *get_all_resources(struct resource_manager *r, u32 *count, struct resource_
return r->resources;
}
-void destroy_resource(struct resource_manager *r) {
-
+void init_resource_manager(struct resource_manager *r, u32 elem_size,
+ u32 initial_elements, u32 max_elements) {
+ r->generation = 1;
+ r->resource_count = 0;
+ r->elem_size = elem_size;
+ r->max_elements = max_elements;
+
+ r->resources = calloc(initial_elements, elem_size);
+ r->ids = calloc(initial_elements, sizeof(*r->ids));
+}
+
+void destroy_resource_manager(struct resource_manager *r) {
+ free(r->ids);
+ free(r->resources);
+}
+
+static int refresh_id(struct resource_manager *r, struct resource_id *id,
+ struct resource_id *new)
+{
+ // rollover is ok
+ /* assert(->generation <= esys.generation); */
+ if (id->generation != r->generation) {
+ // try to find uuid in new memory layout
+ for (u32 i = 0; i < r->resource_count; i++) {
+ struct resource_id *new_id = &r->ids[i];
+ if (new_id->uuid == id->uuid) {
+ new->index = new_id->index;
+ new->generation = r->generation;
+ return 1;
+ }
+ }
+
+ // entity was deleted
+ return 0;
+ }
+
+ // doesn't need refreshed
+ return 2;
+}
+
+int is_resource_destroyed(struct resource_id *id) {
+ return id->generation == 0;
+}
+
+void destroy_resource(struct resource_manager *r, struct resource_id *id) {
+ if (is_resource_destroyed(id))
+ return;
+
+ int res = refresh_id(r, id, id);
+ // entity already deleted
+ if (res == 0) {
+ id->generation = 0;
+ return;
+ }
+ // generation 0 means destroyed
+ id->generation = 0;
+
+ memmove(index_resource(r, id->index),
+ index_resource(r, id->index+1), r->resource_count -)
+}
+
+struct resource_id new_id(struct resource_manager *r) {
+ return (struct resource_id){
+ .index = r->resource_count,
+ .uuid = resource_uuids++,
+ .generation = r->generation,
+ };
+}
+
+void *new_resource(struct resource_manager *r, struct resource_id *id) {
+ struct resource_id fresh_id = new_id(r);
+
+ if (id)
+ *id = fresh_id;
+
+ return index_resource(r, r->resource_count++);
+}
+
+void *get_resource(struct resource_manager *r, struct resource_id *id) {
+ refresh_id(r, id, id);
+
+ return index_resource(r, id->index);
}
diff --git a/src/resource.h b/src/resource.h
@@ -11,14 +11,22 @@ struct resource_id {
};
struct resource_manager {
- void *resources;
+ u8 *resources;
struct resource_id *ids;
u32 resource_count;
u32 generation;
+ u32 elem_size;
+ u32 max_elements;
};
+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 *);
+void destroy_resource(struct resource_manager *, struct resource_id *id);
void destroy_resource_manager(struct resource_manager *);
+struct resource_id new_id(struct resource_manager *);
+void *new_resource(struct resource_manager *, struct resource_id *id);
+
+void init_resource_manager(struct resource_manager *r, u32 elem_size,
+ u32 initial_elements, u32 max_elements);
#endif /* RESOURCE_H */
diff --git a/src/skybox.c b/src/skybox.c
@@ -54,8 +54,7 @@ void create_skybox(struct skybox *skybox, struct gpu_program *program) {
mkgeom.num_verts = ARRAY_SIZE(skybox_vertices);
mkgeom.num_indices = ARRAY_SIZE(skybox_indices);
- skybox->model.geom_id =
- make_buffer_geometry(&mkgeom);
+ make_buffer_geometry(&mkgeom, &skybox->model.geom_id);
static const char *faces[6] = {
CUBEMAP("hw_sahara/sahara_rt_flip.tga"),
@@ -112,7 +111,7 @@ void render_skybox(struct skybox *skybox, mat4 *camera) {
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->model.texture);
check_gl();
- render_geometry(get_geometry(skybox->model.geom_id), &skybox->attrs, skybox->program);
+ render_geometry(get_geometry(&skybox->model.geom_id), &skybox->attrs, skybox->program);
check_gl();
glDepthMask(GL_TRUE);
diff --git a/src/terrain.c b/src/terrain.c
@@ -230,5 +230,5 @@ void create_terrain(struct terrain *terrain, float scale) {
void destroy_terrain(struct terrain *terrain) {
struct entity *ent = get_entity(&terrain->entity_id);
assert(ent);
- destroy_buffer_geometry(get_geometry(terrain->model.geom_id));
+ destroy_buffer_geometry(&terrain->model.geom_id);
}
diff --git a/src/ui.c b/src/ui.c
@@ -34,7 +34,7 @@ static GLfloat quad_uvs[] =
};
-static geometry_id_t create_quad()
+static void create_quad(geometry_id_t *id)
{
struct make_geometry mkgeom = {
.indices = quad_indices,
@@ -45,10 +45,8 @@ static geometry_id_t create_quad()
.num_verts = ARRAY_SIZE(quad_vertices),
.num_uv_components = 2
};
- geometry_id_t id = make_buffer_geometry(&mkgeom);
+ make_buffer_geometry(&mkgeom, id);
check_gl();
-
- return id;
}
void render_ui(struct ui *ui, float *view) {