give them nodes names

Sat, 10 May 2025 15:42:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 10 May 2025 15:42:56 +0200
changeset 114
5b91bbab1ac0
parent 113
71ba88258ea0
child 115
e5f8c99b0987

give them nodes names

src/ascension/2d/sprite.h file | annotate | diff | comparison | revisions
src/ascension/scene_node.h file | annotate | diff | comparison | revisions
src/ascension/ui/text.h file | annotate | diff | comparison | revisions
src/behavior.c file | annotate | diff | comparison | revisions
src/scene_node.c file | annotate | diff | comparison | revisions
src/sprite.c file | annotate | diff | comparison | revisions
src/text.c file | annotate | diff | comparison | revisions
test/snake/snake.c file | annotate | diff | comparison | revisions
--- a/src/ascension/2d/sprite.h	Sat May 10 15:06:47 2025 +0200
+++ b/src/ascension/2d/sprite.h	Sat May 10 15:42:56 2025 +0200
@@ -37,6 +37,7 @@
 } AscSprite;
 
 struct asc_sprite_create_args {
+    const char* name;
     AscTexture *texture;
     int x;
     int y;
--- a/src/ascension/scene_node.h	Sat May 10 15:06:47 2025 +0200
+++ b/src/ascension/scene_node.h	Sat May 10 15:42:56 2025 +0200
@@ -29,6 +29,7 @@
 #define ASCENSION_SCENE_NODE_H
 
 #include <cx/list.h>
+#include <cx/string.h>
 
 #include "datatypes.h"
 #include "transform.h"
@@ -51,7 +52,7 @@
     AscSceneNode *next;
     AscSceneNode *children;
     AscSceneNode *last_child;
-    char *name;
+    cxmutstr name;
     /**
      * List of AscBehavior structs.
      * Not a pointer list!
@@ -112,6 +113,8 @@
  */
 AscSceneNode *asc_scene_node_empty(void);
 
+// TODO: create a common init-function that all "subclasses" use, which also debug-logs the assigned name
+
 /**
  * Unlinks the node from its parent and frees the entire subtree.
  *
@@ -123,6 +126,24 @@
 void asc_scene_node_free(AscSceneNode *node);
 
 /**
+ * Sets the name of a node.
+ *
+ * @param node the node
+ * @param name the new name of the node
+ */
+void asc_scene_node_name(AscSceneNode *node, const char *name);
+
+/**
+ * Returns the name of the node.
+ *
+ * Names are not necessarily unique.
+ *
+ * @param node the node
+ * @return the node's name or a calculated name if it does not have one
+ */
+cxstring asc_scene_node_get_name(AscSceneNode *node);
+
+/**
  * Links a node to a (new) parent.
  *
  * @param parent the (new) parent
--- a/src/ascension/ui/text.h	Sat May 10 15:06:47 2025 +0200
+++ b/src/ascension/ui/text.h	Sat May 10 15:42:56 2025 +0200
@@ -53,6 +53,7 @@
 struct asc_text_create_args {
     int x;
     int y;
+    const char *name;
     char const *text;
     enum asc_text_alignment alignment;
     unsigned short max_width;
--- a/src/behavior.c	Sat May 10 15:06:47 2025 +0200
+++ b/src/behavior.c	Sat May 10 15:42:56 2025 +0200
@@ -52,8 +52,8 @@
     }
     AscBehavior *behavior = cxListEmplace(node->behaviors);
     if (behavior == NULL) {
-        // TODO: output ID of node once we have implemented that
-        asc_error("Failed to add behavior to scene node.");
+        const cxstring node_name = asc_scene_node_get_name(node);
+        asc_error("Failed to add behavior to scene node %"CX_PRIstr, CX_SFMT(node_name));
         return NULL;
     }
     behavior->enabled = true;
--- a/src/scene_node.c	Sat May 10 15:06:47 2025 +0200
+++ b/src/scene_node.c	Sat May 10 15:42:56 2025 +0200
@@ -30,6 +30,9 @@
 
 #include <cx/tree.h>
 #include <cx/linked_list.h>
+#include <cx/printf.h>
+
+#include "ascension/error.h"
 
 static CxTreeIterator asc_scene_node_iterator(
         AscSceneNode *node,
@@ -56,7 +59,10 @@
     if (node->destroy_func != NULL) {
         node->destroy_func(node);
     }
-    free(node->name);
+    if (node->name.ptr != NULL) {
+        asc_dprintf("Destroy node: %"CX_PRIstr, CX_SFMT(node->name));
+        cx_strfree(&node->name);
+    }
 }
 
 void asc_scene_node_free(AscSceneNode *node) {
@@ -74,6 +80,35 @@
     }
 }
 
+void asc_scene_node_name(AscSceneNode *node, const char *name) {
+    free(node->name.ptr);
+    if (name == NULL) {
+        node->name.ptr = NULL;
+        node->name.length = 0;
+    } else {
+        node->name.ptr = strdup(name);
+        node->name.length = strlen(name);
+    }
+}
+
+cxstring asc_scene_node_get_name(AscSceneNode *node) {
+    if (node->name.ptr != NULL) return cx_strcast(node->name);
+
+    AscSceneNode *parent = node->parent;
+    while (parent != NULL && parent->name.ptr == NULL) {
+        parent = parent->parent;
+    }
+    if (parent == NULL) {
+        cx_sprintf(&node->name.ptr, &node->name.length,
+            "%"PRIuPTR " - w/o named parent", (uintptr_t)node);
+    } else {
+        cx_sprintf(&node->name.ptr, &node->name.length,
+            "%"PRIuPTR " - child of %"CX_PRIstr, (uintptr_t)node, CX_SFMT(parent->name));
+    }
+
+    return cx_strcast(node->name);
+}
+
 void asc_scene_node_link(AscSceneNode * restrict parent, AscSceneNode * restrict node) {
     cx_tree_link(
             parent, node,
--- a/src/sprite.c	Sat May 10 15:06:47 2025 +0200
+++ b/src/sprite.c	Sat May 10 15:42:56 2025 +0200
@@ -45,6 +45,7 @@
 
     // basic node parameters
     AscSceneNode *node = (AscSceneNode *) sprite;
+    asc_scene_node_name(node, args.name);
     node->render_group = args.opaque
                              ? ASC_RENDER_GROUP_SPRITE_OPAQUE
                              : ASC_RENDER_GROUP_SPRITE_BLEND;
--- a/src/text.c	Sat May 10 15:06:47 2025 +0200
+++ b/src/text.c	Sat May 10 15:42:56 2025 +0200
@@ -100,6 +100,7 @@
     }
 
     // initialize
+    asc_scene_node_name(node, args.name);
     text->base.texture = malloc(sizeof(AscTexture));
     asc_texture_init_rectangle(text->base.texture, 1);
     asc_text_update(node);
--- a/test/snake/snake.c	Sat May 10 15:06:47 2025 +0200
+++ b/test/snake/snake.c	Sat May 10 15:42:56 2025 +0200
@@ -102,7 +102,7 @@
 static void create_fps_counter(void) {
     asc_font(ASC_FONT_REGULAR, 12);
     asc_ink_rgba(224, 224, 224, 196);
-    AscSceneNode *node = asc_text();
+    AscSceneNode *node = asc_text(.name = "FPS Counter");
     asc_behavior_add(node, .func = update_fps_counter);
     asc_add_ui_node(node);
 }
@@ -111,14 +111,16 @@
     asc_font(ASC_FONT_BOLD, 16);
     asc_ink_rgb(0, 255, 0);
     AscSceneNode* node = asc_text(
-            .x = 10, .y = 10,
-            .text = "Score: 0"
+        .name = "Score Counter",
+        .x = 10, .y = 10,
+        .text = "Score: 0"
     );
     asc_add_ui_node(node);
 }
 
 static void create_spaceship(void) {
     AscSceneNode *sprite = asc_sprite(
+        .name = "Player",
         .texture = TEXTURE_SHIP,
         .x = 250,
         .y = 300,

mercurial