1.1 --- a/src/scene.c Mon Mar 04 21:16:46 2024 +0100 1.2 +++ b/src/scene.c Wed Mar 06 23:08:03 2024 +0100 1.3 @@ -32,9 +32,6 @@ 1.4 1.5 #include <assert.h> 1.6 1.7 -#define node_layout_ \ 1.8 - offsetof(AscSceneNode, parent), offsetof(AscSceneNode, children), \ 1.9 - offsetof(AscSceneNode, prev), offsetof(AscSceneNode, next) 1.10 #define child_list_off_ \ 1.11 offsetof(AscSceneNode, children), offsetof(AscSceneNode, next) 1.12 1.13 @@ -61,13 +58,22 @@ 1.14 // skip the root node deliberately, we know it's just the container 1.15 cxIteratorNext(iter); 1.16 1.17 - // draw the children 1.18 + // update the children 1.19 cx_foreach(AscSceneNode*, node, iter) { 1.20 + // execute behaviors, first 1.21 + AscBehaviorNode *behavior = node->behaviors; 1.22 + while (behavior) { 1.23 + behavior->func(node); 1.24 + behavior = behavior->next; 1.25 + } 1.26 + 1.27 + // check if geometry needs update 1.28 if (node->need_update && node->update_func != NULL) { 1.29 node->need_update = false; 1.30 asc_transform_copy(node->transform, node->parent->transform); 1.31 node->update_func(node); 1.32 } 1.33 + 1.34 // TODO: don't visit the tree for drawing, visit the render groups 1.35 if (node->draw_func != NULL) { 1.36 node->draw_func(node); 1.37 @@ -102,9 +108,45 @@ 1.38 } 1.39 1.40 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) { 1.41 - cx_tree_link(parent, node, node_layout_); 1.42 + cx_tree_link( 1.43 + parent, node, 1.44 + offsetof(AscSceneNode, parent), 1.45 + offsetof(AscSceneNode, children), 1.46 + offsetof(AscSceneNode, prev), 1.47 + offsetof(AscSceneNode, next) 1.48 + ); 1.49 } 1.50 1.51 void asc_scene_node_unlink(AscSceneNode *node) { 1.52 - cx_tree_unlink(node, node_layout_); 1.53 -} 1.54 \ No newline at end of file 1.55 + cx_tree_unlink( 1.56 + node, 1.57 + offsetof(AscSceneNode, parent), 1.58 + offsetof(AscSceneNode, children), 1.59 + offsetof(AscSceneNode, prev), 1.60 + offsetof(AscSceneNode, next) 1.61 + ); 1.62 +} 1.63 + 1.64 +AscBehaviorNode *asc_scene_add_behavior(AscSceneNode *node, asc_scene_update_func behavior) { 1.65 + AscBehaviorNode *behavior_node = calloc(1, sizeof(AscBehaviorNode)); 1.66 + behavior_node->func = behavior; 1.67 + cx_tree_link( 1.68 + node, 1.69 + behavior_node, 1.70 + offsetof(AscBehaviorNode, parent), 1.71 + offsetof(AscSceneNode, behaviors), 1.72 + offsetof(AscBehaviorNode, prev), 1.73 + offsetof(AscBehaviorNode, next) 1.74 + ); 1.75 + return behavior_node; 1.76 +} 1.77 + 1.78 +void asc_scene_remove_behavior(AscBehaviorNode *node) { 1.79 + cx_tree_unlink( 1.80 + node, 1.81 + offsetof(AscBehaviorNode, parent), 1.82 + offsetof(AscSceneNode, behaviors), 1.83 + offsetof(AscBehaviorNode, prev), 1.84 + offsetof(AscBehaviorNode, next) 1.85 + ); 1.86 +}