# HG changeset patch # User Mike Becker # Date 1746565494 -7200 # Node ID 3e956c96dd6c2d366c82e298d8c29e035371986a # Parent ee4b58dfcf7f0ca84f5d4b350689de8277e91c71 extract execution of behaviors from draw function fixes #646 diff -r ee4b58dfcf7f -r 3e956c96dd6c src/ascension/behavior.h --- a/src/ascension/behavior.h Tue May 06 22:54:38 2025 +0200 +++ b/src/ascension/behavior.h Tue May 06 23:04:54 2025 +0200 @@ -41,6 +41,7 @@ asc_behavior_destroy_func destroy_func; AscSceneNode *node; void *data; + bool enabled; // TODO: more useful attributes, e.g. timing settings }; diff -r ee4b58dfcf7f -r 3e956c96dd6c src/ascension/scene.h --- a/src/ascension/scene.h Tue May 06 22:54:38 2025 +0200 +++ b/src/ascension/scene.h Tue May 06 23:04:54 2025 +0200 @@ -65,6 +65,8 @@ return &scene->camera; } +void asc_scene_execute_behaviors(AscScene *scene); + /** * Draws the scene with the specified root node. * diff -r ee4b58dfcf7f -r 3e956c96dd6c src/behavior.c --- a/src/behavior.c Tue May 06 22:54:38 2025 +0200 +++ b/src/behavior.c Tue May 06 23:04:54 2025 +0200 @@ -27,8 +27,10 @@ #include "ascension/behavior.h" #include "ascension/error.h" +#include "ascension/scene.h" #include +#include static void asc_behavior_destroy(void *b) { AscBehavior *behavior = b; @@ -54,6 +56,7 @@ asc_error("Failed to add behavior to scene node."); return NULL; } + behavior->enabled = true; behavior->node = node; behavior->func = args.func; behavior->destroy_func = args.destroy_func; diff -r ee4b58dfcf7f -r 3e956c96dd6c src/scene.c --- a/src/scene.c Tue May 06 22:54:38 2025 +0200 +++ b/src/scene.c Tue May 06 23:04:54 2025 +0200 @@ -59,6 +59,21 @@ asc_scene_node_free(scene->root); } +void asc_scene_execute_behaviors(AscScene *scene) { + CxTreeVisitor iter = cx_tree_visitor(scene->root, + offsetof(AscSceneNode, children), + offsetof(AscSceneNode, next) + ); + cx_foreach(AscSceneNode*, node, iter) { + CxIterator behavior_iter = cxListIterator(node->behaviors); + cx_foreach(AscBehavior*, behavior, behavior_iter) { + if (behavior->enabled) { + behavior->func(behavior); + } + } + } +} + void asc_scene_draw(AscScene *scene) { if (scene->root == NULL) return; @@ -93,13 +108,6 @@ cxTreeVisitorContinue(iter); } - // execute behaviors, first - // TODO: move to a separate iteration that is decoupled from drawing - issue #646 - CxIterator behavior_iter = cxListIterator(node->behaviors); - cx_foreach(AscBehavior*, behavior, behavior_iter) { - behavior->func(behavior); - } - // TODO: implement culling // check if geometry needs update diff -r ee4b58dfcf7f -r 3e956c96dd6c src/window.c --- a/src/window.c Tue May 06 22:54:38 2025 +0200 +++ b/src/window.c Tue May 06 23:04:54 2025 +0200 @@ -154,6 +154,13 @@ glViewport(0, 0, window_width, window_height); glClear(GL_COLOR_BUFFER_BIT); + // Execute all behaviors + // TODO: this can eventually be parallelized + for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { + asc_scene_execute_behaviors(&window->scenes[i]); + } + asc_scene_execute_behaviors(&window->ui); + // Draw all scenes for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { asc_scene_draw(&window->scenes[i]);