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 | } |