28 #include "ascension/scene_node.h" |
28 #include "ascension/scene_node.h" |
29 #include "ascension/context.h" |
29 #include "ascension/context.h" |
30 |
30 |
31 #include <cx/tree.h> |
31 #include <cx/tree.h> |
32 #include <cx/linked_list.h> |
32 #include <cx/linked_list.h> |
|
33 #include <cx/printf.h> |
|
34 |
|
35 #include "ascension/error.h" |
33 |
36 |
34 static CxTreeIterator asc_scene_node_iterator( |
37 static CxTreeIterator asc_scene_node_iterator( |
35 AscSceneNode *node, |
38 AscSceneNode *node, |
36 bool visit_on_exit |
39 bool visit_on_exit |
37 ) { |
40 ) { |
54 static void asc_scene_node_destroy(AscSceneNode *node) { |
57 static void asc_scene_node_destroy(AscSceneNode *node) { |
55 cxListFree(node->behaviors); |
58 cxListFree(node->behaviors); |
56 if (node->destroy_func != NULL) { |
59 if (node->destroy_func != NULL) { |
57 node->destroy_func(node); |
60 node->destroy_func(node); |
58 } |
61 } |
59 free(node->name); |
62 if (node->name.ptr != NULL) { |
|
63 asc_dprintf("Destroy node: %"CX_PRIstr, CX_SFMT(node->name)); |
|
64 cx_strfree(&node->name); |
|
65 } |
60 } |
66 } |
61 |
67 |
62 void asc_scene_node_free(AscSceneNode *node) { |
68 void asc_scene_node_free(AscSceneNode *node) { |
63 if (node == NULL) return; |
69 if (node == NULL) return; |
64 |
70 |
70 cx_foreach(AscSceneNode*, child, iter) { |
76 cx_foreach(AscSceneNode*, child, iter) { |
71 if (!iter.exiting) continue; |
77 if (!iter.exiting) continue; |
72 asc_scene_node_destroy(child); |
78 asc_scene_node_destroy(child); |
73 free(child); |
79 free(child); |
74 } |
80 } |
|
81 } |
|
82 |
|
83 void asc_scene_node_name(AscSceneNode *node, const char *name) { |
|
84 free(node->name.ptr); |
|
85 if (name == NULL) { |
|
86 node->name.ptr = NULL; |
|
87 node->name.length = 0; |
|
88 } else { |
|
89 node->name.ptr = strdup(name); |
|
90 node->name.length = strlen(name); |
|
91 } |
|
92 } |
|
93 |
|
94 cxstring asc_scene_node_get_name(AscSceneNode *node) { |
|
95 if (node->name.ptr != NULL) return cx_strcast(node->name); |
|
96 |
|
97 AscSceneNode *parent = node->parent; |
|
98 while (parent != NULL && parent->name.ptr == NULL) { |
|
99 parent = parent->parent; |
|
100 } |
|
101 if (parent == NULL) { |
|
102 cx_sprintf(&node->name.ptr, &node->name.length, |
|
103 "%"PRIuPTR " - w/o named parent", (uintptr_t)node); |
|
104 } else { |
|
105 cx_sprintf(&node->name.ptr, &node->name.length, |
|
106 "%"PRIuPTR " - child of %"CX_PRIstr, (uintptr_t)node, CX_SFMT(parent->name)); |
|
107 } |
|
108 |
|
109 return cx_strcast(node->name); |
75 } |
110 } |
76 |
111 |
77 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
112 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
78 cx_tree_link( |
113 cx_tree_link( |
79 parent, node, |
114 parent, node, |