Mon, 06 Apr 2026 21:04:10 +0200
prepare node (/ entity) dictionary per scene
| src/ascension/scene.h | file | annotate | diff | comparison | revisions | |
| src/ascension/scene_node.h | file | annotate | diff | comparison | revisions | |
| src/scene.c | file | annotate | diff | comparison | revisions | |
| src/scene_node.c | file | annotate | diff | comparison | revisions |
--- a/src/ascension/scene.h Mon Apr 06 20:27:11 2026 +0200 +++ b/src/ascension/scene.h Mon Apr 06 21:04:10 2026 +0200 @@ -41,6 +41,11 @@ typedef struct asc_scene_s { AscCamera *camera; AscSceneNode *root; + /** + * Maps names to a list of nodes that share the same name. + * Does not contain nodes with auto-generated names. + */ + AscSceneNodeDict *nodes_dict; cxmutstr name; struct { CxList *render_groups[ASC_RENDER_GROUP_COUNT]; @@ -99,5 +104,7 @@ void asc_scene_add_node(AscScene *scene, AscSceneNode *node); +void asc_scene_remove_node(AscSceneNode *node); + #endif // ASCENSION_SCENE_H
--- a/src/ascension/scene_node.h Mon Apr 06 20:27:11 2026 +0200 +++ b/src/ascension/scene_node.h Mon Apr 06 21:04:10 2026 +0200 @@ -38,6 +38,23 @@ typedef struct asc_scene_node_s AscSceneNode; typedef struct asc_camera_s AscCamera; // avoids full include of camera.h + +typedef struct asc_scene_node_dict_entry_s { + AscSceneNode **node; + /** + * Number of nodes with the same name. + */ + unsigned int count; +} AscSceneNodeDictEntry; + +/** + * A dictionary that maps names to lists of nodes. + */ +typedef CxMap AscSceneNodeDict; + +AscSceneNodeDict *asc_scene_node_dict_create(void); +void asc_scene_node_dict_free(AscSceneNodeDict *dict); + typedef void(*asc_scene_node_destroy_func)(AscSceneNode*); typedef void(*asc_scene_node_update_func)(AscSceneNode*); typedef void(*asc_scene_node_draw_func)(const AscCamera*,const AscSceneNode*); @@ -56,6 +73,10 @@ AscSceneNode *next; AscSceneNode *children; AscSceneNode *last_child; + /** + * A reference to the scene's node dictionary when this node is part of a scene. + */ + AscSceneNodeDict *dict; cxmutstr name; /** * List of AscBehavior structs. @@ -106,6 +127,10 @@ */ #define ASC_SCENE_NODE_TRANSFORM_UPDATED 0x08000000 /** + * The node has a name which is not auto-generated. + */ +#define ASC_SCENE_NODE_HAS_NAME 0x40000000 +/** * Set when the node is not supposed to be shown on screen. */ #define ASC_SCENE_NODE_HIDDEN 0x80000000
--- a/src/scene.c Mon Apr 06 20:27:11 2026 +0200 +++ b/src/scene.c Mon Apr 06 21:04:10 2026 +0200 @@ -43,7 +43,9 @@ void asc_scene_init(AscScene *scene, const char *name, AscCamera *camera) { assert(scene->root == NULL); scene->camera = camera; + scene->nodes_dict = asc_scene_node_dict_create(); scene->root = asc_scene_node_empty(); + scene->root->dict = scene->nodes_dict; for (unsigned i = 0 ; i < ASC_RENDER_GROUP_COUNT ; i++) { scene->internal.render_groups[i] = cxArrayListCreate(NULL, CX_STORE_POINTERS, 32); } @@ -61,6 +63,7 @@ cxListFree(scene->internal.render_groups[i]); scene->internal.render_groups[i] = NULL; } + asc_scene_node_dict_free(scene->nodes_dict); asc_scene_node_free(scene->root); scene->root = NULL; asc_dprintf("Destroyed scene %"CX_PRIstr, CX_SFMT(scene->name));
--- 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),