43 } |
43 } |
44 |
44 |
45 AscSceneNode *asc_scene_node_empty(void) { |
45 AscSceneNode *asc_scene_node_empty(void) { |
46 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); |
46 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); |
47 node->render_group = ASC_RENDER_GROUP_NONE; |
47 node->render_group = ASC_RENDER_GROUP_NONE; |
48 node->free_func = (asc_scene_free_func) free; |
|
49 node->scale.x = node->scale.y = node->scale.z = 1; |
48 node->scale.x = node->scale.y = node->scale.z = 1; |
50 asc_transform_identity(node->transform); |
49 asc_transform_identity(node->transform); |
51 asc_transform_identity(node->world_transform); |
50 asc_transform_identity(node->world_transform); |
52 return node; |
51 return node; |
|
52 } |
|
53 |
|
54 static void asc_scene_node_destroy(AscSceneNode *node) { |
|
55 cxListFree(node->behaviors); |
|
56 if (node->destroy_func != NULL) { |
|
57 node->destroy_func(node); |
|
58 } |
|
59 free(node->name); |
53 } |
60 } |
54 |
61 |
55 void asc_scene_node_free(AscSceneNode *node) { |
62 void asc_scene_node_free(AscSceneNode *node) { |
56 if (node == NULL) return; |
63 if (node == NULL) return; |
57 |
64 |
60 |
67 |
61 // free the entire subtree |
68 // free the entire subtree |
62 CxTreeIterator iter = asc_scene_node_iterator(node, true); |
69 CxTreeIterator iter = asc_scene_node_iterator(node, true); |
63 cx_foreach(AscSceneNode*, child, iter) { |
70 cx_foreach(AscSceneNode*, child, iter) { |
64 if (!iter.exiting) continue; |
71 if (!iter.exiting) continue; |
65 cxListFree(child->behaviors); |
72 asc_scene_node_destroy(child); |
66 if (child->free_func != NULL) { |
73 free(child); |
67 child->free_func(child); |
|
68 } else { |
|
69 free(child); |
|
70 } |
|
71 } |
74 } |
72 } |
75 } |
73 |
76 |
74 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
77 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
75 cx_tree_link( |
78 cx_tree_link( |
96 } |
99 } |
97 |
100 |
98 // TODO: rename in asc_node_add_behavior or just asc_add_behavior() |
101 // TODO: rename in asc_node_add_behavior or just asc_add_behavior() |
99 void asc_scene_add_behavior( |
102 void asc_scene_add_behavior( |
100 AscSceneNode *node, |
103 AscSceneNode *node, |
101 asc_scene_update_func behavior |
104 asc_scene_node_update_func behavior |
102 ) { |
105 ) { |
103 if (node->behaviors == NULL) { |
106 if (node->behaviors == NULL) { |
104 node->behaviors = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
107 node->behaviors = cxLinkedListCreateSimple(CX_STORE_POINTERS); |
105 } |
108 } |
106 // TODO: create AscBehavior struct with more stuff than just a fptr |
109 // TODO: create AscBehavior struct with more stuff than just a fptr |
107 cxListAdd(node->behaviors, behavior); |
110 cxListAdd(node->behaviors, behavior); |
108 } |
111 } |
109 |
112 |
110 void asc_scene_remove_behavior( |
113 void asc_scene_remove_behavior( |
111 AscSceneNode *node, |
114 AscSceneNode *node, |
112 asc_scene_update_func behavior |
115 asc_scene_node_update_func behavior |
113 ) { |
116 ) { |
114 if (node->behaviors != NULL) { |
117 if (node->behaviors != NULL) { |
115 cxListFindRemove(node->behaviors, behavior); |
118 cxListFindRemove(node->behaviors, behavior); |
116 } |
119 } |
117 } |
120 } |