aboutsummaryrefslogtreecommitdiff
path: root/src/scene/scene_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scene/scene_memory.c')
-rw-r--r--src/scene/scene_memory.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/src/scene/scene_memory.c b/src/scene/scene_memory.c
new file mode 100644
index 0000000..85c27e7
--- /dev/null
+++ b/src/scene/scene_memory.c
@@ -0,0 +1,149 @@
1#include "scene_memory.h"
2
3#include <gfx/sizes.h>
4
5#include "animation_impl.h"
6#include "camera_impl.h"
7#include "light_impl.h"
8#include "material_impl.h"
9#include "mesh_impl.h"
10#include "model_impl.h"
11#include "node_impl.h"
12#include "object_impl.h"
13#include "scene_impl.h"
14
15#include <mempool.h>
16
17DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS)
18DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS)
19DEF_MEMPOOL(camera_pool, SceneCamera, GFX_MAX_NUM_CAMERAS)
20DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS)
21DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS)
22DEF_MEMPOOL(mesh_pool, Mesh, GFX_MAX_NUM_MESHES)
23DEF_MEMPOOL(mesh_link_pool, MeshLink, GFX_MAX_NUM_MESH_LINKS)
24DEF_MEMPOOL(model_pool, Model, GFX_MAX_NUM_MODELS)
25DEF_MEMPOOL(node_pool, SceneNode, GFX_MAX_NUM_NODES)
26DEF_MEMPOOL(object_pool, SceneObject, GFX_MAX_NUM_OBJECTS)
27DEF_MEMPOOL(scene_pool, Scene, GFX_MAX_NUM_SCENES)
28DEF_MEMPOOL(skeleton_pool, Skeleton, GFX_MAX_NUM_SKELETONS)
29
30/// Scene memory.
31///
32/// Holds memory pools for every type of scene object.
33typedef struct SceneMemory {
34 anima_pool animas;
35 animation_pool animations;
36 camera_pool cameras;
37 light_pool lights;
38 material_pool materials;
39 mesh_pool meshs; // Purposeful typo to make the PLURAL() macro work.
40 mesh_link_pool mesh_links;
41 model_pool models;
42 node_pool nodes;
43 object_pool objects;
44 scene_pool scenes;
45 skeleton_pool skeletons;
46} SceneMemory;
47
48static SceneMemory mem;
49
50#define ALLOC_DUMMY(POOL) \
51 { \
52 const void* object = mempool_alloc(POOL); \
53 assert(mempool_get_block_index(POOL, object) == 0); \
54 }
55
56#define PLURAL(name) name##s
57#define MEM_FIELD(name) mem.PLURAL(name)
58
59void scene_mem_init() {
60 mempool_make(&mem.animas);
61 mempool_make(&mem.animations);
62 mempool_make(&mem.cameras);
63 mempool_make(&mem.lights);
64 mempool_make(&mem.materials);
65 mempool_make(&mem.meshs);
66 mempool_make(&mem.mesh_links);
67 mempool_make(&mem.models);
68 mempool_make(&mem.nodes);
69 mempool_make(&mem.objects);
70 mempool_make(&mem.scenes);
71 mempool_make(&mem.skeletons);
72
73 // Allocate dummy objects at index 0 to guarantee that no objects allocated by
74 // the caller map to index 0.
75 ALLOC_DUMMY(&mem.animas);
76 ALLOC_DUMMY(&mem.animations);
77 ALLOC_DUMMY(&mem.cameras);
78 ALLOC_DUMMY(&mem.lights);
79 ALLOC_DUMMY(&mem.materials);
80 ALLOC_DUMMY(&mem.meshs);
81 ALLOC_DUMMY(&mem.mesh_links);
82 ALLOC_DUMMY(&mem.models);
83 ALLOC_DUMMY(&mem.nodes);
84 ALLOC_DUMMY(&mem.objects);
85 ALLOC_DUMMY(&mem.scenes);
86 ALLOC_DUMMY(&mem.skeletons);
87}
88
89void scene_mem_destroy() {
90 // NOTE: the dummy objects are not constructed, so the destruction code below
91 // always skips index 0. (I don't really like the conditional inside the loop,
92 // but this gets the job done without having to specialize the loop macro.)
93#define DESTROY(name) \
94 mempool_foreach(&MEM_FIELD(name), obj, { \
95 if (i > 0) { \
96 gfx_destroy_##name(&obj); \
97 } \
98 })
99
100 // Models contain scene elements. Destruction is handled by the remainder of
101 // scene destructionb elow.
102 //
103 // First destroy the scenes. This will recursively destroy the scene's nodes
104 // and their objects and avoid a double-free when we then destroy any stray
105 // scene elements.
106 DESTROY(scene);
107 // Then delete stray nodes. This will delete their children nodes and
108 // resource.
109 DESTROY(node);
110 // Destroy remaining scene elements.
111 DESTROY(anima);
112 // Animations are owned by animas and do not have a destructor.
113 DESTROY(camera);
114 DESTROY(light);
115 DESTROY(material);
116 DESTROY(mesh);
117 // Mesh links don't have a destructor.
118 DESTROY(object);
119 // Skeletons are owned by animas and do not have a destructor.
120}
121
122#define DEF_MEMORY(name, type) \
123 /* xyz* mem_alloc_xyz(); */ \
124 type* mem_alloc_##name() { return mempool_alloc(&MEM_FIELD(name)); } \
125 /* void mem_free_xyz(xyz**); */ \
126 void mem_free_##name(type** obj) { mempool_free(&MEM_FIELD(name), obj); } \
127 /* xyz* mem_get_xyz(xyz_idx); */ \
128 type* mem_get_##name(NAMED_INDEX(name) index) { \
129 assert(index.val != 0); /* 0 is the dummy allocation. */ \
130 return mempool_get_block(&MEM_FIELD(name), index.val); \
131 } \
132 /* xyz_idx mem_get_xyz_index(const xyz*); */ \
133 NAMED_INDEX(name) mem_get_##name##_index(const type* obj) { \
134 return (NAMED_INDEX(name)){ \
135 .val = mempool_get_block_index(&MEM_FIELD(name), obj)}; \
136 }
137
138DEF_MEMORY(anima, Anima)
139DEF_MEMORY(animation, Animation)
140DEF_MEMORY(camera, SceneCamera)
141DEF_MEMORY(light, Light)
142DEF_MEMORY(material, Material)
143DEF_MEMORY(mesh, Mesh)
144DEF_MEMORY(mesh_link, MeshLink)
145DEF_MEMORY(model, Model)
146DEF_MEMORY(node, SceneNode)
147DEF_MEMORY(object, SceneObject)
148DEF_MEMORY(scene, Scene)
149DEF_MEMORY(skeleton, Skeleton)