#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)