30 |
30 |
31 #include <cx/tree.h> |
31 #include <cx/tree.h> |
32 |
32 |
33 #include <assert.h> |
33 #include <assert.h> |
34 |
34 |
35 #define asc_scene_node_layout \ |
35 #define node_layout_ \ |
36 offsetof(AscSceneNode, parent), offsetof(AscSceneNode, children), \ |
36 offsetof(AscSceneNode, parent), offsetof(AscSceneNode, children), \ |
37 offsetof(AscSceneNode, prev), offsetof(AscSceneNode, next) |
37 offsetof(AscSceneNode, prev), offsetof(AscSceneNode, next) |
|
38 #define child_list_off_ \ |
|
39 offsetof(AscSceneNode, children), offsetof(AscSceneNode, next) |
38 |
40 |
39 void asc_scene_init(AscScene *scene) { |
41 void asc_scene_init(AscScene *scene) { |
40 if (scene->root != NULL) { |
42 if (scene->root != NULL) { |
41 asc_error("Scene is already initialized."); |
43 asc_error("Scene is already initialized."); |
42 return; |
44 return; |
50 |
52 |
51 void asc_scene_add(AscScene *scene, AscSceneNode *node) { |
53 void asc_scene_add(AscScene *scene, AscSceneNode *node) { |
52 asc_scene_node_link(scene->root, node); |
54 asc_scene_node_link(scene->root, node); |
53 } |
55 } |
54 |
56 |
55 static void asc_scene_draw_node(AscSceneNode *node) { |
57 void asc_scene_draw(AscScene const *scene) { |
56 if (node->draw_func != NULL) { |
58 // TODO: don't visit the tree, visit the render groups |
57 node->draw_func(node); |
59 CxTreeIterator iter = cx_tree_iterator(scene->root, false, child_list_off_); |
|
60 cx_foreach(AscSceneNode*, node, iter) { |
|
61 if (node->draw_func != NULL) { |
|
62 node->draw_func(node); |
|
63 } |
58 } |
64 } |
59 if (node->children != NULL) { |
|
60 asc_scene_draw_node(node->children); |
|
61 } |
|
62 if (node->next != NULL) { |
|
63 asc_scene_draw_node(node->next); |
|
64 } |
|
65 } |
|
66 |
|
67 void asc_scene_draw(AscScene const *scene) { |
|
68 // TODO: replace with UCX tree visitor |
|
69 // TODO: don't visit the tree, visit the render groups |
|
70 // TODO: avoid recursion |
|
71 asc_scene_draw_node(scene->root); |
|
72 } |
65 } |
73 |
66 |
74 AscSceneNode *asc_scene_node_empty(void) { |
67 AscSceneNode *asc_scene_node_empty(void) { |
75 // TODO: check if this can remain a calloc or if it's too expensive |
68 // TODO: check if this can remain a calloc or if it's too expensive |
76 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); |
69 AscSceneNode *node = calloc(1, sizeof(AscSceneNode)); |
98 node->free_func(node); |
91 node->free_func(node); |
99 } |
92 } |
100 } |
93 } |
101 |
94 |
102 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
95 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { |
103 cx_tree_link(parent, node, asc_scene_node_layout); |
96 cx_tree_link(parent, node, node_layout_); |
104 } |
97 } |
105 |
98 |
106 void asc_scene_node_unlink(AscSceneNode *node) { |
99 void asc_scene_node_unlink(AscSceneNode *node) { |
107 cx_tree_unlink(node, asc_scene_node_layout); |
100 cx_tree_unlink(node, node_layout_); |
108 } |
101 } |