From bd57f345ed9dbed1d81683e48199626de2ea9044 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 27 Jun 2025 10:18:39 -0700 Subject: Restructure project --- src/scene/scene_memory.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/scene/scene_memory.c (limited to 'src/scene/scene_memory.c') 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 @@ +#include "scene_memory.h" + +#include + +#include "animation_impl.h" +#include "camera_impl.h" +#include "light_impl.h" +#include "material_impl.h" +#include "mesh_impl.h" +#include "model_impl.h" +#include "node_impl.h" +#include "object_impl.h" +#include "scene_impl.h" + +#include + +DEF_MEMPOOL(anima_pool, Anima, GFX_MAX_NUM_ANIMAS) +DEF_MEMPOOL(animation_pool, Animation, GFX_MAX_NUM_ANIMATIONS) +DEF_MEMPOOL(camera_pool, SceneCamera, GFX_MAX_NUM_CAMERAS) +DEF_MEMPOOL(light_pool, Light, GFX_MAX_NUM_LIGHTS) +DEF_MEMPOOL(material_pool, Material, GFX_MAX_NUM_MATERIALS) +DEF_MEMPOOL(mesh_pool, Mesh, GFX_MAX_NUM_MESHES) +DEF_MEMPOOL(mesh_link_pool, MeshLink, GFX_MAX_NUM_MESH_LINKS) +DEF_MEMPOOL(model_pool, Model, GFX_MAX_NUM_MODELS) +DEF_MEMPOOL(node_pool, SceneNode, GFX_MAX_NUM_NODES) +DEF_MEMPOOL(object_pool, SceneObject, GFX_MAX_NUM_OBJECTS) +DEF_MEMPOOL(scene_pool, Scene, GFX_MAX_NUM_SCENES) +DEF_MEMPOOL(skeleton_pool, Skeleton, GFX_MAX_NUM_SKELETONS) + +/// Scene memory. +/// +/// Holds memory pools for every type of scene object. +typedef struct SceneMemory { + anima_pool animas; + animation_pool animations; + camera_pool cameras; + light_pool lights; + material_pool materials; + mesh_pool meshs; // Purposeful typo to make the PLURAL() macro work. + mesh_link_pool mesh_links; + model_pool models; + node_pool nodes; + object_pool objects; + scene_pool scenes; + skeleton_pool skeletons; +} SceneMemory; + +static SceneMemory mem; + +#define ALLOC_DUMMY(POOL) \ + { \ + const void* object = mempool_alloc(POOL); \ + assert(mempool_get_block_index(POOL, object) == 0); \ + } + +#define PLURAL(name) name##s +#define MEM_FIELD(name) mem.PLURAL(name) + +void scene_mem_init() { + mempool_make(&mem.animas); + mempool_make(&mem.animations); + mempool_make(&mem.cameras); + mempool_make(&mem.lights); + mempool_make(&mem.materials); + mempool_make(&mem.meshs); + mempool_make(&mem.mesh_links); + mempool_make(&mem.models); + mempool_make(&mem.nodes); + mempool_make(&mem.objects); + mempool_make(&mem.scenes); + mempool_make(&mem.skeletons); + + // Allocate dummy objects at index 0 to guarantee that no objects allocated by + // the caller map to index 0. + ALLOC_DUMMY(&mem.animas); + ALLOC_DUMMY(&mem.animations); + ALLOC_DUMMY(&mem.cameras); + ALLOC_DUMMY(&mem.lights); + ALLOC_DUMMY(&mem.materials); + ALLOC_DUMMY(&mem.meshs); + ALLOC_DUMMY(&mem.mesh_links); + ALLOC_DUMMY(&mem.models); + ALLOC_DUMMY(&mem.nodes); + ALLOC_DUMMY(&mem.objects); + ALLOC_DUMMY(&mem.scenes); + ALLOC_DUMMY(&mem.skeletons); +} + +void scene_mem_destroy() { + // NOTE: the dummy objects are not constructed, so the destruction code below + // always skips index 0. (I don't really like the conditional inside the loop, + // but this gets the job done without having to specialize the loop macro.) +#define DESTROY(name) \ + mempool_foreach(&MEM_FIELD(name), obj, { \ + if (i > 0) { \ + gfx_destroy_##name(&obj); \ + } \ + }) + + // Models contain scene elements. Destruction is handled by the remainder of + // scene destructionb elow. + // + // First destroy the scenes. This will recursively destroy the scene's nodes + // and their objects and avoid a double-free when we then destroy any stray + // scene elements. + DESTROY(scene); + // Then delete stray nodes. This will delete their children nodes and + // resource. + DESTROY(node); + // Destroy remaining scene elements. + DESTROY(anima); + // Animations are owned by animas and do not have a destructor. + DESTROY(camera); + DESTROY(light); + DESTROY(material); + DESTROY(mesh); + // Mesh links don't have a destructor. + DESTROY(object); + // Skeletons are owned by animas and do not have a destructor. +} + +#define DEF_MEMORY(name, type) \ + /* xyz* mem_alloc_xyz(); */ \ + type* mem_alloc_##name() { return mempool_alloc(&MEM_FIELD(name)); } \ + /* void mem_free_xyz(xyz**); */ \ + void mem_free_##name(type** obj) { mempool_free(&MEM_FIELD(name), obj); } \ + /* xyz* mem_get_xyz(xyz_idx); */ \ + type* mem_get_##name(NAMED_INDEX(name) index) { \ + assert(index.val != 0); /* 0 is the dummy allocation. */ \ + return mempool_get_block(&MEM_FIELD(name), index.val); \ + } \ + /* xyz_idx mem_get_xyz_index(const xyz*); */ \ + NAMED_INDEX(name) mem_get_##name##_index(const type* obj) { \ + return (NAMED_INDEX(name)){ \ + .val = mempool_get_block_index(&MEM_FIELD(name), obj)}; \ + } + +DEF_MEMORY(anima, Anima) +DEF_MEMORY(animation, Animation) +DEF_MEMORY(camera, SceneCamera) +DEF_MEMORY(light, Light) +DEF_MEMORY(material, Material) +DEF_MEMORY(mesh, Mesh) +DEF_MEMORY(mesh_link, MeshLink) +DEF_MEMORY(model, Model) +DEF_MEMORY(node, SceneNode) +DEF_MEMORY(object, SceneObject) +DEF_MEMORY(scene, Scene) +DEF_MEMORY(skeleton, Skeleton) -- cgit v1.2.3