diff options
| author | 3gg <3gg@shellblade.net> | 2023-01-07 18:42:48 -0800 | 
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2023-01-07 18:42:48 -0800 | 
| commit | c84f528325a7edf0f808d081106d3ff6a196cb8a (patch) | |
| tree | ef9b5cf52908c730970c08d9e2c384a7680ab9f0 | |
| parent | 5102cd7ffba18b87050b8ecbaed3ee64ab60c462 (diff) | |
Destroy all scene and scene elements upon termination.
| -rw-r--r-- | gfx/src/gfx.c | 10 | ||||
| -rw-r--r-- | gfx/src/scene/scene_memory.c | 47 | ||||
| -rw-r--r-- | gfx/src/scene/scene_memory.h | 4 | ||||
| -rw-r--r-- | gltfview/src/game.c | 3 | 
4 files changed, 50 insertions, 14 deletions
| diff --git a/gfx/src/gfx.c b/gfx/src/gfx.c index 8321f86..4640a52 100644 --- a/gfx/src/gfx.c +++ b/gfx/src/gfx.c | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | 14 | ||
| 15 | typedef struct Gfx { | 15 | typedef struct Gfx { | 
| 16 | RenderBackend render_backend; | 16 | RenderBackend render_backend; | 
| 17 | Renderer renderer; | 17 | Renderer renderer; | 
| 18 | scene_idx scene; // First child scene. | 18 | scene_idx scene; // First child scene. | 
| 19 | } Gfx; | 19 | } Gfx; | 
| 20 | 20 | ||
| 21 | Gfx* gfx_init() { | 21 | Gfx* gfx_init() { | 
| @@ -42,12 +42,6 @@ void gfx_destroy(Gfx** gfx) { | |||
| 42 | if (!gfx) { | 42 | if (!gfx) { | 
| 43 | return; | 43 | return; | 
| 44 | } | 44 | } | 
| 45 | // Destroy scenes for convenience. | ||
| 46 | for (scene_idx scene_index = (*gfx)->scene; scene_index.val;) { | ||
| 47 | Scene* scene = mem_get_scene(scene_index); | ||
| 48 | scene_index = scene->next; | ||
| 49 | gfx_destroy_scene(*gfx, &scene); | ||
| 50 | } | ||
| 51 | scene_mem_destroy(); | 45 | scene_mem_destroy(); | 
| 52 | renderer_destroy(&(*gfx)->renderer, &(*gfx)->render_backend); | 46 | renderer_destroy(&(*gfx)->renderer, &(*gfx)->render_backend); | 
| 53 | gfx_del_render_backend(&(*gfx)->render_backend); | 47 | gfx_del_render_backend(&(*gfx)->render_backend); | 
| diff --git a/gfx/src/scene/scene_memory.c b/gfx/src/scene/scene_memory.c index 7355ad2..83ecd57 100644 --- a/gfx/src/scene/scene_memory.c +++ b/gfx/src/scene/scene_memory.c | |||
| @@ -63,7 +63,52 @@ void scene_mem_init() { | |||
| 63 | ALLOC_DUMMY(&mem.scenes); | 63 | ALLOC_DUMMY(&mem.scenes); | 
| 64 | } | 64 | } | 
| 65 | 65 | ||
| 66 | void scene_mem_destroy() {} | 66 | void scene_mem_destroy() { | 
| 67 | // NOTE: the dummy objects are not constructed, so the destruction code below | ||
| 68 | // always skips index 0. (I don't really like the conditional inside the loop, | ||
| 69 | // but this gets the job done without having to specialize the loop macro.) | ||
| 70 | // | ||
| 71 | // First destroy the scenes. This will recursively destroy the scene's nodes | ||
| 72 | // and their objects and avoid a double-free when we then destroy any stray | ||
| 73 | // scene elements. | ||
| 74 | mempool_foreach(&mem.scenes, scene, { | ||
| 75 | if (i > 0) { | ||
| 76 | scene_destroy(scene); | ||
| 77 | } | ||
| 78 | }); | ||
| 79 | // Destroy remaining scene elements. | ||
| 80 | mempool_foreach(&mem.cameras, camera, { | ||
| 81 | if (i > 0) { | ||
| 82 | gfx_destroy_camera(&camera); | ||
| 83 | } | ||
| 84 | }); | ||
| 85 | mempool_foreach(&mem.lights, light, { | ||
| 86 | if (i > 0) { | ||
| 87 | gfx_destroy_light(&light); | ||
| 88 | } | ||
| 89 | }); | ||
| 90 | mempool_foreach(&mem.materials, material, { | ||
| 91 | if (i > 0) { | ||
| 92 | gfx_destroy_material(&material); | ||
| 93 | } | ||
| 94 | }); | ||
| 95 | mempool_foreach(&mem.meshes, mesh, { | ||
| 96 | if (i > 0) { | ||
| 97 | gfx_destroy_mesh(&mesh); | ||
| 98 | } | ||
| 99 | }); | ||
| 100 | // Mesh links don't have a destructor. | ||
| 101 | mempool_foreach(&mem.nodes, node, { | ||
| 102 | if (i > 0) { | ||
| 103 | gfx_destroy_node(&node); | ||
| 104 | } | ||
| 105 | }); | ||
| 106 | mempool_foreach(&mem.objects, object, { | ||
| 107 | if (i > 0) { | ||
| 108 | gfx_destroy_object(&object); | ||
| 109 | } | ||
| 110 | }); | ||
| 111 | } | ||
| 67 | 112 | ||
| 68 | // Memory allocation. | 113 | // Memory allocation. | 
| 69 | SceneCamera* mem_alloc_camera() { return mempool_alloc(&mem.cameras); } | 114 | SceneCamera* mem_alloc_camera() { return mempool_alloc(&mem.cameras); } | 
| diff --git a/gfx/src/scene/scene_memory.h b/gfx/src/scene/scene_memory.h index b0fa73c..bd2c691 100644 --- a/gfx/src/scene/scene_memory.h +++ b/gfx/src/scene/scene_memory.h | |||
| @@ -15,10 +15,10 @@ typedef struct Scene Scene; | |||
| 15 | /// Initialize scene memory. | 15 | /// Initialize scene memory. | 
| 16 | /// | 16 | /// | 
| 17 | /// The scene memory guarantees that every object maps to an index different | 17 | /// The scene memory guarantees that every object maps to an index different | 
| 18 | /// than 0. In this way, 0 can be used as a special index to denote "no value". | 18 | /// than 0. This way, 0 can be used as a special index to denote "no value". | 
| 19 | void scene_mem_init(); | 19 | void scene_mem_init(); | 
| 20 | 20 | ||
| 21 | /// Destroy the scene memory. | 21 | /// Destroy the scene memory and all allocated objects. | 
| 22 | void scene_mem_destroy(); | 22 | void scene_mem_destroy(); | 
| 23 | 23 | ||
| 24 | /// ---------------------------------------------------------------------------- | 24 | /// ---------------------------------------------------------------------------- | 
| diff --git a/gltfview/src/game.c b/gltfview/src/game.c index 93755e7..612ec67 100644 --- a/gltfview/src/game.c +++ b/gltfview/src/game.c | |||
| @@ -218,9 +218,6 @@ bool game_new(Game* game, int argc, const char** argv) { | |||
| 218 | 218 | ||
| 219 | cleanup: | 219 | cleanup: | 
| 220 | LOGE("Gfx error: %s", gfx_get_error()); | 220 | LOGE("Gfx error: %s", gfx_get_error()); | 
| 221 | if (game->scene) { | ||
| 222 | gfx_destroy_scene(game->gfx, &game->scene); | ||
| 223 | } | ||
| 224 | if (game->gfx) { | 221 | if (game->gfx) { | 
| 225 | gfx_destroy(&game->gfx); | 222 | gfx_destroy(&game->gfx); | 
| 226 | } | 223 | } | 
