commit d9e8b3450400c825afa81b631de1a66a79a443ef
parent 89c556a73924eb70abe9537d3b75b0b9792b5fe0
Author: William Casarin <jb55@jb55.com>
Date: Tue, 2 Jul 2019 15:21:50 -0700
resource fixes
Diffstat:
20 files changed, 288 insertions(+), 102 deletions(-)
diff --git a/src/animation.c b/src/animation.c
@@ -116,7 +116,7 @@ static void dae_tagbody(struct xmlparser *x, const char *d, size_t dl)
assert(&joint->node_id == &pose->joints[pose->njoints].node_id);
parse_joint(d, pose->njoints, joint);
- print_id(&joint->node_id);
+ print_id(&joint->node_id, 1);
node_set_label(node, data->current_name);
joint->children_ids[0] = data->node_level;
pose->njoints++;
diff --git a/src/entity.c b/src/entity.c
@@ -108,7 +108,7 @@ void destroy_entity_system() {
void init_entity_system() {
init_resource_manager(&esys, sizeof(struct entity), DEF_NUM_ENTITIES,
- MAX_ENTITIES);
+ MAX_ENTITIES, "entity");
}
diff --git a/src/game.c b/src/game.c
@@ -134,6 +134,8 @@ void game_init(struct game *game, int width, int height) {
init_terrain(terrain, size);
create_terrain(terrain, size);
+ update_terrain(terrain);
+
/* get_entity(&terrain->entity_id)->flags |= ENT_INVISIBLE; */
create_skybox(&res->skybox, &res->programs[SKYBOX_PROGRAM]);
diff --git a/src/geometry.c b/src/geometry.c
@@ -174,7 +174,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);
+ DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry");
}
struct geometry *get_geometry(geometry_id *geom_id) {
@@ -183,9 +183,25 @@ struct geometry *get_geometry(geometry_id *geom_id) {
struct geometry *new_geometry(geometry_id *geom_id) {
- return new_resource(&geom_manager, geom_id);
+ struct geometry *geom = new_resource(&geom_manager, geom_id);
+ /* debug("new geometry %llu\n", geom_id->uuid); */
+ return geom;
}
struct geometry *get_all_geometry(u32 *count, geometry_id **ids) {
return get_all_resources(&geom_manager, count, ids);
}
+
+void destroy_geometry(geometry_id *geom_id)
+{
+ struct geometry *geom = get_geometry(geom_id); assert(geom);
+ struct vbo *vbo;
+
+ for (int i = 0; i < n_vertex_attrs; i++) {
+ vbo = &geom->vbos[i];
+ if (vbo->handle)
+ glDeleteBuffers(1, &vbo->handle);
+ }
+
+ destroy_resource(&geom_manager, geom_id);
+}
diff --git a/src/geometry.h b/src/geometry.h
@@ -58,5 +58,6 @@ void init_geometry_id(geometry_id *);
struct geometry *new_geometry(geometry_id *);
struct geometry *get_geometry(geometry_id *);
struct geometry *get_all_geometry(u32 *count, geometry_id **ids);
+void destroy_geometry(geometry_id *geom_id);
#endif /* GEOMETRY_H */
diff --git a/src/main.c b/src/main.c
@@ -40,7 +40,7 @@ int main(void)
int height = 480;
game_init(&game, width, height);
/* reset_scene(&game); */
- /* pbr_scene(&game); */
+ entity_test_scene(&game);
check_gl();
double last = hires_time_in_seconds();
diff --git a/src/model.c b/src/model.c
@@ -2,6 +2,7 @@
#include "model.h"
#include "ply.h"
#include "resource.h"
+#include "debug.h"
#include <assert.h>
#define MODELDEF(name) { .id = model_##name, .loaded = 0, .file = #name }
@@ -46,6 +47,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);
+ /* debug("new model %llu\n", model_id->dyn_model_id.uuid); */
init_id(&model->geom_id);
new_geometry(&model->geom_id);
return model;
@@ -53,7 +55,7 @@ static struct model *new_model_resource(model_id *model_id)
void init_model_manager() {
init_resource_manager(&dyn_modelman, sizeof(struct model),
- DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS);
+ DEF_DYNAMIC_MODELS, MAX_DYNAMIC_MODELS, "model");
}
@@ -102,6 +104,18 @@ static struct model *load_static_model(enum static_model m)
return model;
}
+void destroy_model(model_id *model_id)
+{
+ if (model_id->type == STATIC_MODEL)
+ 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);
+}
+
model_id get_static_model(enum static_model m, struct model **model)
{
model_id model_id;
diff --git a/src/model.h b/src/model.h
@@ -62,6 +62,7 @@ struct model *get_model(model_id *);
struct model *get_model_geom(model_id *, struct geometry **);
struct model *new_model(model_id *);
struct model *new_static_model(model_id *);
+void destroy_model(model_id *);
model_id get_static_model(enum static_model, struct model**);
diff --git a/src/node.c b/src/node.c
@@ -19,6 +19,7 @@ struct node *new_node(node_id *id)
{
struct node *n = node_init(new_uninitialized_node(id));
assert((int64_t)id->uuid != -1);
+ /* debug("new node %llu\n", id->uuid); */
return n;
}
@@ -39,7 +40,7 @@ void destroy_node(node_id *id)
void init_node_manager()
{
- init_resource_manager(&node_manager, sizeof(struct node), 128, 0xFFFF);
+ init_resource_manager(&node_manager, sizeof(struct node), 128, 0xFFFF, "node");
}
struct node *node_init(struct node *node) {
@@ -107,7 +108,7 @@ int node_needs_recalc(struct node *node)
}
vec3 *node_world(struct node *node) {
- node_recalc(node);
+
return &node->mat[M_X];
}
@@ -175,7 +176,7 @@ int node_detach(struct node *node, struct node *from) {
if (child && child == node) {
destroy_node(child_id);
memmove(&from->children_ids[i], &from->children_ids[i+1],
- sizeof(*from->children_ids) * from->n_children - 1);
+ sizeof(*from->children_ids) * (from->n_children - i - 1));
// TODO: test node_detach
from->n_children--;
return 1;
diff --git a/src/procmesh.c b/src/procmesh.c
@@ -35,7 +35,7 @@ void proc_sphere(struct geometry *geom) {
const int n = 50;
qh_vertex_t *vertices = malloc(n*sizeof(qh_vertex_t));
const float radius = 2.0;
-
+ float *colors;
for (int i = 0; i < n; ++i) {
float a0 = (rand_0to1() * TAU);
@@ -43,13 +43,26 @@ void proc_sphere(struct geometry *geom) {
vertices[i].z = sin(a0) * radius;
vertices[i].x = cos(a1) * cos(a0) * rand_0to1() * radius;
vertices[i].y = sin(a1) * cos(a0) * rand_0to1() * radius;
+
}
qh_mesh_t mesh = qh_quickhull3d(vertices, n);
+
+ assert(mesh.nvertices);
+ colors = malloc(mesh.nvertices * 3 * sizeof(*colors));
+ assert(colors);
+ for (u32 i = 0; i < mesh.nvertices; i++) {
+ for (int j = 0; j < 3; j++)
+ colors[i*3+j] = 0.5;
+ }
+ mkgeom.colors = colors;
+
qh_mesh_to_geom(&mesh, &mkgeom);
+
make_buffer_geometry(&mkgeom, geom);
free(vertices);
+ free(colors);
free(mkgeom.normals);
qh_free_mesh(mesh);
}
diff --git a/src/resource.c b/src/resource.c
@@ -39,17 +39,18 @@ void null_id(struct resource_id *id)
}
void init_resource_manager(struct resource_manager *r, u32 elem_size,
- u32 initial_elements, u32 max_elements) {
+ u32 initial_elements, u32 max_elements, const char *name) {
r->generation = 1;
r->resource_count = 0;
r->elem_size = elem_size;
r->max_capacity = max_elements;
r->current_capacity = initial_elements;
+ r->name = name;
assert(initial_elements != 0);
r->resources = calloc(initial_elements, elem_size);
- r->ids = calloc(initial_elements, sizeof(*r->ids));
+ r->ids = calloc(initial_elements, sizeof(struct resource_id));
}
void destroy_resource_manager(struct resource_manager *r) {
@@ -63,7 +64,8 @@ static int refresh_id(struct resource_manager *r, struct resource_id *id,
// rollover is ok
/* assert(->generation <= esys.generation); */
if (id->generation != r->generation) {
- /* debug("id gen %d != res gen %d, refreshing\n", id->generation, r->generation); */
+ /* 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++) {
struct resource_id *newer_id = &r->ids[i];
@@ -97,6 +99,8 @@ static void new_id(struct resource_manager *r, struct resource_id *id)
static void resize(struct resource_manager *r)
{
+ debug("resizing %s resources, count %d+1 > current capacity %d\n",
+ r->name, r->resource_count, r->current_capacity);
void *new_mem;
u32 new_size = r->resource_count * 1.5;
if (new_size >= r->max_capacity)
@@ -121,14 +125,12 @@ static void resize(struct resource_manager *r)
}
r->current_capacity = new_size;
r->ids = new_mem;
-
- // 2 to avoid issues with compact generation incrementing
- r->generation += 2;
}
-void print_id(struct resource_id *id)
+void print_id(struct resource_id *id, int nl)
{
- printf("res_id(uuid:%llu ind:%d gen:%d)\n", id->uuid, id->index, id->generation);
+ printf("id(u:%llu i:%d g:%d)%s",
+ id->uuid, id->index, id->generation, nl?"\n":"");
}
void *new_resource(struct resource_manager *r, struct resource_id *id)
@@ -158,14 +160,14 @@ void *get_resource(struct resource_manager *r, struct resource_id *id) {
assert((int64_t)id->generation != -1 && "id intialized but not allocated (needs new_ call)");
if (id->generation == 0) {
- //unusual("getting already deleted resource %llu\n", id->uuid);
+ /* unusual("getting already deleted resource %llu\n", id->uuid); */
return NULL;
}
enum refresh_status res = refresh_id(r, id, id);
if (res == RESOURCE_DELETED) {
- unusual("getting deleted resource %llu\n", id->uuid);
+ unusual("getting deleted %s resource %llu\n", r->name, id->uuid);
return NULL;
}
@@ -190,18 +192,27 @@ void destroy_resource(struct resource_manager *r, struct resource_id *id) {
return;
}
- /* debug("destroying resource %llu\n", id->uuid); */
+ debug("destroying %s resource %llu ind %d res_count %d\n",
+ r->name, id->uuid, id->index, r->resource_count);
r->resource_count--;
r->generation++;
+ assert((int)r->resource_count - (int)id->index >= 0);
+
+ // TODO: we're copying OOB here
memmove(index_resource(r, id->index),
index_resource(r, id->index+1),
- r->elem_size * r->resource_count);
+ r->elem_size * (r->resource_count - id->index));
memmove(&r->ids[id->index],
&r->ids[id->index+1],
- sizeof(*r->ids) * r->resource_count);
+ sizeof(struct resource_id) * (r->resource_count - id->index));
+
+
+ for (u32 i = id->index; i < r->resource_count; i++) {
+ r->ids[i].index--;
+ }
}
int is_id_allocated(struct resource_id *id)
diff --git a/src/resource.h b/src/resource.h
@@ -25,6 +25,7 @@ struct resource_manager {
u32 slots_used;
u32 max_capacity;
u32 current_capacity;
+ const char *name;
};
#define ideq(a, b) ((a)->uuid == (b)->uuid)
@@ -36,10 +37,10 @@ void *get_all_resources(struct resource_manager *, u32 *count, struct resource_i
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 print_id(struct resource_id *);
+void print_id(struct resource_id *, int nl);
void null_id(struct resource_id *id);
void init_resource_manager(struct resource_manager *r, u32 elem_size,
- u32 initial_elements, u32 max_elements);
+ u32 initial_elements, u32 max_elements, const char *name);
#endif /* RESOURCE_H */
diff --git a/src/scene.c b/src/scene.c
@@ -1,6 +1,10 @@
+
#include "game.h"
#include "model.h"
+#include "procmesh.h"
+#include "debug.h"
+#include "vec3.h"
#include <assert.h>
void reset_scene(struct game *game) {
@@ -43,12 +47,63 @@ void default_scene(struct game *game) {
}
-void pbr_scene(struct game *game) {
+static void delete_every_other_entity()
+{
+ u32 count;
+ entity_id *ids;
+
+ for (u32 i = RESERVED_ENTITIES; i < 1000; i++) {
+ get_all_entities(&count, &ids);
+
+ if (i >= count)
+ return;
+
+ if (i % 2 == 0) {
+ struct entity *ent = get_entity(&ids[i]); assert(ent);
+ struct model *pmodel = get_model(&ent->model_id); assert(pmodel);
+
+ destroy_model(&ent->model_id);
+ destroy_entity(&ids[i]);
+ }
+ }
+}
+
+
+
+void entity_test_scene(struct game *game)
+{
+ struct entity *player = get_player(&game->test_resources);
+ struct terrain *terrain = &game->terrain;
+ player->model_id = get_static_model(model_pirate_officer, NULL);
+
+ for (int i = 0; i < 500; i++) {
+ struct entity *ent = new_entity(NULL);
+ struct node *node = get_node(&ent->node_id);
+
+ struct model *pmodel = new_model(&ent->model_id); assert(pmodel);
+ struct geometry *geom = get_geometry(&pmodel->geom_id); assert(geom);
+
+ proc_sphere(geom);
+ pmodel->shading = SHADING_VERT_COLOR;
+
+ double x = rand_0to1() * terrain->size;
+ double y = rand_0to1() * terrain->size;
+ double z = terrain->fn(terrain, x, y);
+
+ node_scale(node, 10.0);
+ node_translate(node, V3(x, y, z));
+
+ node_recalc(node);
+ }
+
+}
+
+void pbr_scene(struct game *game)
+{
struct entity *ent = new_entity(NULL);
struct node *node = get_node(&ent->node_id); assert(node);
+ struct entity *player = get_player(&game->test_resources);
ent->model_id = get_static_model(model_icosphere, NULL);
node_set_label(node, "sphere");
- node_attach(&game->test_resources.root_id, &ent->node_id);
-
}
diff --git a/src/scene.h b/src/scene.h
@@ -6,6 +6,7 @@
void default_scene(struct game *);
void reset_scene(struct game *);
+void entity_test_scene(struct game *);
void pbr_scene(struct game *);
#endif /* SCENE_H */
diff --git a/src/terrain.c b/src/terrain.c
@@ -2,6 +2,7 @@
#include "terrain.h"
#include "util.h"
#include "delaunay.h"
+#include "debug.h"
#include "vec3.h"
#include "perlin.h"
#include "poisson.h"
@@ -241,3 +242,53 @@ void destroy_terrain(struct terrain *terrain) {
struct model *model = get_model(&ent->model_id); assert(model);
destroy_buffer_geometry(&model->geom_id);
}
+
+
+void update_terrain(struct terrain *terrain) {
+ static int first = 1;
+ static float last_scale = -1.0;
+
+ struct entity *ent = get_entity(&terrain->entity_id);
+ assert(ent);
+ struct perlin_settings *ts = &terrain->settings;
+ struct node *tnode = get_node(&ent->node_id);
+ assert(tnode);
+
+ debug("updating terrain\n");
+
+ if (first) {
+ reset_terrain(terrain, terrain->size);
+ /* tnode->pos[0] = rand_0to1() * terrain->size; */
+ /* tnode->pos[1] = rand_0to1() * terrain->size; */
+ first = 0;
+ }
+
+ ts->ox = tnode->pos[0];
+ ts->oy = tnode->pos[1];
+
+ double scale = tnode->pos[2] * 0.0015;
+ if (scale == 0) scale = 1.0;
+
+ printf("terrain %f %f %f\n", tnode->pos[0], tnode->pos[1], tnode->pos[2]);
+
+ /* ts.o1s = fabs(sin(1/n) * 0.25); */
+ /* ts.o1 = fabs(cos(n*0.2) * 0.5); */
+ /* ts.o2s = fabs(cos(n+2) * 0.5); */
+ /* ts.o2 = fabs(sin(n*0.02) * 2); */
+ ts->freq = scale * 0.05;
+ ts->amplitude = 50.0;
+
+ /* if (terrain->fn) */
+ /* destroy_terrain(terrain); */
+
+ /* const double pdist = min(5.0, max(1.1, 1.0/scale*1.4)); */
+
+ /* printf("pdist %f\n", pdist); */
+
+ if (last_scale == -1.0 || fabs(scale - last_scale) > 0.00001) {
+ gen_terrain_samples(terrain, scale);
+ }
+
+ last_scale = scale;
+ create_terrain(terrain, scale);
+}
diff --git a/src/terrain.h b/src/terrain.h
@@ -32,6 +32,7 @@ struct terrain {
double old_noisy_boi(struct terrain *, double x, double y);
+void update_terrain(struct terrain *terrain);
void gen_terrain_samples(struct terrain *terrain, float scale);
void init_terrain(struct terrain *terrain, float size);
void reset_terrain(struct terrain *terrain, float size);
diff --git a/src/update.c b/src/update.c
@@ -88,55 +88,6 @@ static void remap_samples(struct point *points, int n_samples,
}
}
-void update_terrain(struct terrain *terrain) {
- static int first = 1;
- static float last_scale = -1.0;
-
- struct entity *ent = get_entity(&terrain->entity_id);
- assert(ent);
- struct perlin_settings *ts = &terrain->settings;
- struct node *tnode = get_node(&ent->node_id);
- assert(tnode);
-
- debug("updating terrain\n");
-
- if (first) {
- reset_terrain(terrain, terrain->size);
- tnode->pos[0] = rand_0to1() * terrain->size;
- tnode->pos[1] = rand_0to1() * terrain->size;
- first = 0;
- }
-
- ts->ox = tnode->pos[0];
- ts->oy = tnode->pos[1];
-
- double scale = tnode->pos[2] * 0.0015;
- if (scale == 0) scale = 1.0;
-
- printf("terrain %f %f %f\n", tnode->pos[0], tnode->pos[1], tnode->pos[2]);
-
- /* ts.o1s = fabs(sin(1/n) * 0.25); */
- /* ts.o1 = fabs(cos(n*0.2) * 0.5); */
- /* ts.o2s = fabs(cos(n+2) * 0.5); */
- /* ts.o2 = fabs(sin(n*0.02) * 2); */
- ts->freq = scale * 0.05;
- ts->amplitude = 50.0;
-
- /* if (terrain->fn) */
- /* destroy_terrain(terrain); */
-
- /* const double pdist = min(5.0, max(1.1, 1.0/scale*1.4)); */
-
- /* printf("pdist %f\n", pdist); */
-
- if (last_scale == -1.0 || fabs(scale - last_scale) > 0.00001) {
- gen_terrain_samples(terrain, scale);
- }
-
- last_scale = scale;
- create_terrain(terrain, scale);
-}
-
static void player_terrain_collision(struct terrain *terrain, struct entity *player) {
// player movement
static vec3 last_pos[3] = {0};
@@ -382,7 +333,7 @@ static void player_update(struct game *game, struct entity *player) {
void update (struct game *game) {
static int toggle_fog = 0;
- static int first = 1;
+ static int needs_terrain_update = 0;
struct resources *res = &game->test_resources;
struct terrain *terrain = &game->terrain;
struct node *root = get_node(&game->test_resources.root_id);
@@ -400,9 +351,9 @@ void update (struct game *game) {
gravity(game);
- if (first) {
+ if (needs_terrain_update) {
update_terrain(terrain);
- first = 0;
+ needs_terrain_update = 0;
}
/* spherical_dir(game->test_resources.camera.coords, camera_dir); */
diff --git a/src/vbo.h b/src/vbo.h
@@ -69,5 +69,6 @@ make_int_vertex_buffer(struct vbo *vbo, const int *data,
void bind_uv_vbo(struct vbo *vbo, gpu_addr slot);
void bind_vbo(struct vbo *vbo, gpu_addr slot, GLenum type);
+void free_vbo(struct vbo *vbo);
#endif /* POLYADVENT_BUFFER_H */
diff --git a/test/test_resource.c b/test/test_resource.c
@@ -6,43 +6,79 @@
#include "debug.h"
#include <assert.h>
-void test_compact()
+static void print_int_resources(struct resource_manager *m)
+{
+ int *ints = (int*)m->resources;
+
+ for (u32 i = 0; i < m->resource_count; i++) {
+ printf("%d ", ints[i]);
+ }
+
+ printf("\n");
+}
+
+
+static void print_ids(struct resource_manager *m)
+{
+ for (u32 i = 0; i < m->resource_count; i++) {
+ print_id(&m->ids[i], 0);
+ printf(" ");
+ }
+ printf("\n");
+}
+
+
+static void test_compact()
{
printf("test_compact\n");
struct resource_manager r;
- struct resource_id ids[3], first_id;
+ struct resource_id ids[20];
int *p;
+ u32 i;
- init_resource_manager(&r, sizeof(int), 2, 4);
+ init_resource_manager(&r, sizeof(int), 2, 6, "int");
- for (int i = 0; i < (int)ARRAY_SIZE(ids); i++)
+ for (i = 0; i < (int)ARRAY_SIZE(ids); i++)
init_id(&ids[i]);
- init_id(&first_id);
+ i = 0;
- p = new_resource(&r, &first_id);
- assert(r.resource_count == 1);
- *p = 11;
+ p = new_resource(&r, &ids[i++]);
+ assert(r.resource_count == 1); *p = 0;
- p = new_resource(&r, &ids[0]);
- *p = 22;
+ p = new_resource(&r, &ids[i++]); *p = 1;
assert(r.resource_count == 2);
- destroy_resource(&r, &first_id);
- assert(r.resource_count == 1);
- assert(get_resource(&r, &first_id) == NULL);
- assert(*(int*)get_resource(&r, &ids[0]) == 22);
+ p = new_resource(&r, &ids[i++]); *p = 2;
+ p = new_resource(&r, &ids[i++]);
+ *p = 3;
- new_resource(&r, &ids[1]);
- assert(r.resource_count == 2);
- assert(r.current_capacity == 2);
- new_resource(&r, &ids[2]);
+ print_int_resources(&r);
+ print_ids(&r);
+
+ assert(r.resource_count == 4);
+ destroy_resource(&r, &ids[1]);
assert(r.resource_count == 3);
- assert(r.current_capacity >= 3);
+ print_int_resources(&r);
+ print_ids(&r);
+
+ assert(*(int*)get_resource(&r, &ids[0]) == 0);
+ assert( get_resource(&r, &ids[1]) == NULL);
+ print_id(&ids[1], 1);
+ debug("%d\n",*(int*)get_resource(&r, &ids[2]) );
+ assert(*(int*)get_resource(&r, &ids[2]) == 2);
+
+ new_resource(&r, &ids[i++]);
+ assert(r.resource_count == 4);
+ assert(r.current_capacity >= 4);
+
+ new_resource(&r, &ids[i++]);
+ assert(r.resource_count == 5);
+ assert(r.current_capacity >= 5);
}
-void test_int_resource_manager()
+static void test_int_resource_manager()
{
printf("test_int_resource_manager\n");
struct resource_manager r
@@ -50,7 +86,7 @@ void test_int_resource_manager()
struct resource_id id, first_id;
int *p;
// 2 item case
- init_resource_manager(&r, sizeof(int), 1, 2);
+ init_resource_manager(&r, sizeof(int), 1, 2, "int");
init_id(&id);
init_id(&first_id);
@@ -74,7 +110,7 @@ void test_int_resource_manager()
destroy_resource_manager(&r);
}
-void test_entity_system()
+static void test_entity_system()
{
printf("test_entity_system\n");
u32 count;
diff --git a/test/test_scene.c b/test/test_scene.c
@@ -12,6 +12,28 @@
#define t_assert(cond, msg) assert(cond && msg);
+void delete_every_other_entity()
+{
+ u32 count;
+ entity_id *ids;
+
+ for (u32 i = RESERVED_ENTITIES; i < 1000; i++) {
+ get_all_entities(&count, &ids);
+
+ if (i >= count)
+ return;
+
+ if (i % 2 == 0) {
+ struct entity *ent = get_entity(&ids[i]); assert(ent);
+ struct model *pmodel = get_model(&ent->model_id); assert(pmodel);
+
+ destroy_model(&ent->model_id);
+ destroy_entity(&ids[i]);
+ }
+ }
+}
+
+
int scene_tests(struct game *game) {
struct node *root = get_node(&game->test_resources.root_id);
assert(root);
@@ -41,6 +63,14 @@ int scene_tests(struct game *game) {
t_assert(node_count(root) == initial_node_count,
"scene: node count doesn't match initial after reset_scene");
+ entity_test_scene(game);
+
+ get_all_entities(&ent_count, NULL);
+ /* assert(ent_count == 102); */
+
+ delete_every_other_entity();
+ assert(ent_count == 502);
+
return 1;
}