improve implementation of scene graph tree

Sun, 21 Jan 2024 13:58:23 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 21 Jan 2024 13:58:23 +0100
changeset 27
4ccf4703999e
parent 26
139dac8ef9ee
child 28
8acde7d27904

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

mercurial