--- a/src/scene_node.c Mon Apr 06 20:27:11 2026 +0200 +++ b/src/scene_node.c Mon Apr 06 21:04:10 2026 +0200 @@ -31,10 +31,33 @@ #include <cx/tree.h> #include <cx/linked_list.h> +#include <cx/hash_map.h> #include <cx/printf.h> #include <assert.h> +AscSceneNodeDict *asc_scene_node_dict_create(void) { + return cxHashMapCreate(cxDefaultAllocator, sizeof(AscSceneNodeDictEntry), 0); +} + +void asc_scene_node_dict_free(AscSceneNodeDict *dict) { + cxMapFree(dict); +} + +static void asc_scene_node_dict_add(AscSceneNodeDict *dict, AscSceneNode *node) { + if (dict == NULL || !asc_test_flag(node->flags, ASC_SCENE_NODE_HAS_NAME)) { + return; + } + // TODO: add a new dict entry or add the node the the list if it's not already present +} + +static void asc_scene_node_dict_remove(AscSceneNodeDict *dict, AscSceneNode *node) { + if (dict == NULL || !asc_test_flag(node->flags, ASC_SCENE_NODE_HAS_NAME)) { + return; + } + // TODO: find entries for node's name and remove it from the list - erase the entry when it was the last +} + static CxTreeIterator asc_scene_node_iterator( AscSceneNode *node, bool visit_on_exit @@ -143,9 +166,14 @@ } void asc_scene_node_name(AscSceneNode *node, const char *name) { + asc_scene_node_dict_remove(node->dict, node); cx_strfree(&node->name); - if (name != NULL) { + if (name == NULL) { + asc_clear_flag(node->flags, ASC_SCENE_NODE_HAS_NAME); + } else { + asc_set_flag(node->flags, ASC_SCENE_NODE_HAS_NAME); node->name = cx_strdup(name); + asc_scene_node_dict_add(node->dict, node); } } @@ -168,6 +196,7 @@ } void asc_scene_node_add(AscSceneNode * restrict parent, AscSceneNode * restrict node) { + asc_scene_node_dict_add(parent->dict, node); cx_tree_add( parent, node, offsetof(AscSceneNode, parent), @@ -180,6 +209,7 @@ } void asc_scene_node_remove(AscSceneNode *node) { + asc_scene_node_dict_remove(node->dict, node); cx_tree_remove( node, offsetof(AscSceneNode, parent),