73 } |
73 } |
74 |
74 |
75 void asc_scene_node_free(AscSceneNode *node) { |
75 void asc_scene_node_free(AscSceneNode *node) { |
76 if (node == NULL) return; |
76 if (node == NULL) return; |
77 |
77 |
78 // TODO: replace with UCX tree visitor |
|
79 // TODO: avoid recursion |
|
80 |
|
81 // free the children recursively |
|
82 while (node->children != NULL) { |
|
83 asc_scene_node_free(node->children); |
|
84 } |
|
85 |
|
86 // remove this node from its parent |
78 // remove this node from its parent |
87 asc_scene_node_unlink(node); |
79 asc_scene_node_unlink(node); |
88 |
80 |
89 // free the node |
81 // free the entire subtree |
90 if (node->free_func != NULL) { |
82 CxTreeIterator iter = cx_tree_iterator(node, true, child_list_off_); |
91 node->free_func(node); |
83 cx_foreach(AscSceneNode*, child, iter) { |
|
84 if (!iter.exiting) continue; |
|
85 if (child->free_func != NULL) { |
|
86 child->free_func(child); |
|
87 } else { |
|
88 free(child); |
|
89 } |
92 } |
90 } |
93 } |
91 } |
94 |
92 |
95 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
93 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
96 cx_tree_link(parent, node, node_layout_); |
94 cx_tree_link(parent, node, node_layout_); |