Sun, 21 Jan 2024 14:01:27 +0100
remove unused cx/list.h include
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 * Copyright 2023 Mike Becker. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
28 #include "ascension/scene.h"
29 #include "ascension/error.h"
31 #include <assert.h>
33 void asc_scene_init(AscScene *scene) {
34 if (scene->root != NULL) {
35 asc_error("Scene is already initialized.");
36 return;
37 }
38 scene->root = asc_scene_node_create(NULL);
39 }
41 void asc_scene_destroy(AscScene *scene) {
42 asc_scene_node_free(scene->root);
43 }
45 AscSceneNode *asc_scene_node_create(AscSceneNode *parent) {
46 // TODO: check if this can remain a calloc or if it's too expensive
47 AscSceneNode *node = calloc(1, sizeof(AscSceneNode));
48 assert(node != NULL);
49 asc_scene_node_link(node, parent);
50 return node;
51 }
53 void asc_scene_node_free(AscSceneNode *node) {
54 if (node == NULL) return;
56 // free the children recursively
57 while (node->children != NULL) {
58 asc_scene_node_free(node->children);
59 }
61 // remove this node from its parent
62 asc_scene_node_unlink(node);
64 // free the node
65 free(node);
66 }
68 void asc_scene_node_link(
69 AscSceneNode *node,
70 AscSceneNode *parent
71 ) {
72 if (node->parent == parent) return;
73 if (node->parent != NULL || parent == NULL) asc_scene_node_unlink(node);
74 if (parent != NULL) {
75 if (parent->children == NULL) {
76 parent->children = node;
77 } else {
78 parent->children->prev = node;
79 node->next = parent->children;
80 }
81 node->parent = parent;
82 }
83 }
85 void asc_scene_node_unlink(AscSceneNode *node) {
86 if (node->parent == NULL) return;
87 AscSceneNode *left = node->prev;
88 AscSceneNode *right = node->next;
89 assert(left == NULL || node->parent->children != node);
90 if (left != NULL) {
91 left->next = right;
92 } else {
93 node->parent->children = right;
94 }
95 if (right != NULL) right->prev = left;
96 node->parent = node->prev = node->next = NULL;
97 }