Sun, 21 Jan 2024 13:58:23 +0100
improve implementation of scene graph tree
src/ascension/scene.h | file | annotate | diff | comparison | revisions | |
src/scene.c | file | annotate | diff | comparison | revisions |
1.1 --- a/src/ascension/scene.h Sun Jan 21 13:34:49 2024 +0100 1.2 +++ b/src/ascension/scene.h Sun Jan 21 13:58:23 2024 +0100 1.3 @@ -28,11 +28,11 @@ 1.4 #ifndef ASCENSION_SCENE_H 1.5 #define ASCENSION_SCENE_H 1.6 1.7 -#include <cx/list.h> 1.8 - 1.9 typedef struct AscSceneNode { 1.10 struct AscSceneNode *parent; 1.11 - CxList *children; 1.12 + struct AscSceneNode *prev; 1.13 + struct AscSceneNode *next; 1.14 + struct AscSceneNode *children; 1.15 // TODO: add node contents 1.16 } AscSceneNode; 1.17
2.1 --- a/src/scene.c Sun Jan 21 13:34:49 2024 +0100 2.2 +++ b/src/scene.c Sun Jan 21 13:58:23 2024 +0100 2.3 @@ -28,7 +28,6 @@ 2.4 #include "ascension/scene.h" 2.5 #include "ascension/error.h" 2.6 2.7 -#include <cx/linked_list.h> 2.8 #include <assert.h> 2.9 2.10 void asc_scene_init(AscScene *scene) { 2.11 @@ -44,24 +43,25 @@ 2.12 } 2.13 2.14 AscSceneNode *asc_scene_node_create(AscSceneNode *parent) { 2.15 - AscSceneNode *node = malloc(sizeof(AscSceneNode)); 2.16 + // TODO: check if this can remain a calloc or if it's too expensive 2.17 + AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); 2.18 assert(node != NULL); 2.19 - node->children = cxLinkedListCreateSimple(CX_STORE_POINTERS); 2.20 - assert(node->children != NULL); 2.21 - node->parent = NULL; 2.22 asc_scene_node_link(node, parent); 2.23 return node; 2.24 } 2.25 2.26 void asc_scene_node_free(AscSceneNode *node) { 2.27 if (node == NULL) return; 2.28 - while (cxListSize(node->children) > 0) { 2.29 - AscSceneNode *child = cxListAt(node->children, 0); 2.30 - asc_scene_node_free(child); 2.31 + 2.32 + // free the children recursively 2.33 + while (node->children != NULL) { 2.34 + asc_scene_node_free(node->children); 2.35 } 2.36 - if (node->parent != NULL) { 2.37 - cxListFindRemove(node->parent->children, node); 2.38 - } 2.39 + 2.40 + // remove this node from its parent 2.41 + asc_scene_node_unlink(node); 2.42 + 2.43 + // free the node 2.44 free(node); 2.45 } 2.46 2.47 @@ -72,13 +72,26 @@ 2.48 if (node->parent == parent) return; 2.49 if (node->parent != NULL || parent == NULL) asc_scene_node_unlink(node); 2.50 if (parent != NULL) { 2.51 - cxListAdd(parent->children, node); 2.52 + if (parent->children == NULL) { 2.53 + parent->children = node; 2.54 + } else { 2.55 + parent->children->prev = node; 2.56 + node->next = parent->children; 2.57 + } 2.58 node->parent = parent; 2.59 } 2.60 } 2.61 2.62 void asc_scene_node_unlink(AscSceneNode *node) { 2.63 if (node->parent == NULL) return; 2.64 - cxListFindRemove(node->parent->children, node); 2.65 - node->parent = NULL; 2.66 + AscSceneNode *left = node->prev; 2.67 + AscSceneNode *right = node->next; 2.68 + assert(left == NULL || node->parent->children != node); 2.69 + if (left != NULL) { 2.70 + left->next = right; 2.71 + } else { 2.72 + node->parent->children = right; 2.73 + } 2.74 + if (right != NULL) right->prev = left; 2.75 + node->parent = node->prev = node->next = NULL; 2.76 } 2.77 \ No newline at end of file