53 return node; |
53 return node; |
54 } |
54 } |
55 |
55 |
56 static void asc_scene_node_destroy(AscSceneNode *node) { |
56 static void asc_scene_node_destroy(AscSceneNode *node) { |
57 cxListFree(node->behaviors); |
57 cxListFree(node->behaviors); |
|
58 if (node->user_data_free_func != NULL) { |
|
59 node->user_data_free_func((void*)node->user_data_allocator, node->user_data); |
|
60 } |
58 if (node->destroy_func != NULL) { |
61 if (node->destroy_func != NULL) { |
59 node->destroy_func(node); |
62 node->destroy_func(node); |
60 } |
63 } |
61 if (node->name.ptr != NULL) { |
64 if (node->name.ptr != NULL) { |
62 asc_dprintf("Destroy node: %"CX_PRIstr, CX_SFMT(node->name)); |
65 asc_dprintf("Destroy node: %"CX_PRIstr, CX_SFMT(node->name)); |
133 offsetof(AscSceneNode, children), |
136 offsetof(AscSceneNode, children), |
134 offsetof(AscSceneNode, last_child), |
137 offsetof(AscSceneNode, last_child), |
135 offsetof(AscSceneNode, prev), |
138 offsetof(AscSceneNode, prev), |
136 offsetof(AscSceneNode, next) |
139 offsetof(AscSceneNode, next) |
137 ); |
140 ); |
138 asc_node_update_transform(node); |
141 asc_scene_node_update_transform(node); |
139 } |
142 } |
140 |
143 |
141 void asc_scene_node_unlink(AscSceneNode *node) { |
144 void asc_scene_node_unlink(AscSceneNode *node) { |
142 cx_tree_unlink( |
145 cx_tree_unlink( |
143 node, |
146 node, |
145 offsetof(AscSceneNode, children), |
148 offsetof(AscSceneNode, children), |
146 offsetof(AscSceneNode, last_child), |
149 offsetof(AscSceneNode, last_child), |
147 offsetof(AscSceneNode, prev), |
150 offsetof(AscSceneNode, prev), |
148 offsetof(AscSceneNode, next) |
151 offsetof(AscSceneNode, next) |
149 ); |
152 ); |
150 asc_node_update_transform(node); |
153 asc_scene_node_update_transform(node); |
151 } |
154 } |
152 |
155 |
153 void asc_node_update(AscSceneNode *node) { |
156 void asc_scene_node_update(AscSceneNode *node) { |
154 asc_set_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS); |
157 asc_set_flag(node->flags, ASC_SCENE_NODE_UPDATE_GRAPHICS); |
155 } |
158 } |
156 |
159 |
157 void asc_node_update_transform(AscSceneNode *node) { |
160 void asc_scene_node_update_transform(AscSceneNode *node) { |
158 // fast skip if node is already marked |
161 // fast skip if node is already marked |
159 if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM)) { |
162 if (asc_test_flag(node->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM)) { |
160 return; |
163 return; |
161 } |
164 } |
162 |
165 |
166 cxTreeIteratorContinue(iter); |
169 cxTreeIteratorContinue(iter); |
167 } |
170 } |
168 asc_set_flag(n->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM); |
171 asc_set_flag(n->flags, ASC_SCENE_NODE_UPDATE_TRANSFORM); |
169 } |
172 } |
170 } |
173 } |
|
174 |
|
175 void asc_scene_node_allocate_data(AscSceneNode *node, size_t n) { |
|
176 if (node->user_data != NULL) { |
|
177 asc_dprintf("WARNING: Node %"CX_PRIstr" already has user data!", CX_SFMT(node->name)); |
|
178 if (node->user_data_free_func != NULL) { |
|
179 node->user_data_free_func((void*)node->user_data_allocator, node->user_data); |
|
180 } |
|
181 } |
|
182 node->user_data = cxZallocDefault(n); |
|
183 node->user_data_allocator = cxDefaultAllocator; |
|
184 node->user_data_free_func = (cx_destructor_func2) cxFree; |
|
185 } |