From b0f446a514aa003a95863a8412b4c4f39f1e2d08 Mon Sep 17 00:00:00 2001 From: Akos Horvath Date: Wed, 9 Aug 2023 19:59:05 +0200 Subject: [PATCH] make TreeNode struct heap-allocated --- src/util.c | 134 ++++++++++++++++++++++++++++------------------------- src/util.h | 9 ++-- 2 files changed, 75 insertions(+), 68 deletions(-) diff --git a/src/util.c b/src/util.c index 49a5548..ceb5a98 100644 --- a/src/util.c +++ b/src/util.c @@ -5,22 +5,29 @@ #include #include -TreeNode wm_treenode_new(NodeType type, TreeNode *parent) +TreeNode* wm_treenode_new(NodeType type, TreeNode *parent) { DEBUG_PRINT("%s\n", __func__); - TreeNode node; + TreeNode *node = calloc(sizeof(TreeNode), 1); - node.parent = parent; - node.type = type; - node.children = wm_nodearray_new(); + node->parent = parent; + node->type = type; + node->children = wm_nodearray_new(); node_id++; - node.id = node_id; - node.client = NULL; + node->id = node_id; + node->client = NULL; return node; } +void wm_treenode_free(TreeNode *node) +{ + wm_nodearray_clear(&node->children); + __wm_nodearray_free(&node->children); + free(node); +} + bool wm_treenode_is_empty(TreeNode *node) { DEBUG_PRINT("%s\n", __func__); @@ -107,7 +114,7 @@ void wm_tree_to_DOT(TreeNode *root, const char *filename) bool contains = false; for (size_t j = 0; j < printed_nodes.size; j++) { - if (printed_nodes.nodes[i].id == node->id) + if (printed_nodes.nodes[j]->id == node->id) contains = true; } @@ -119,12 +126,12 @@ void wm_tree_to_DOT(TreeNode *root, const char *filename) memset(buf2, 0, bufsize); wm_node_type_to_str(node->type, buf1, bufsize); - wm_node_type_to_str(node->children.nodes[j].type, buf2, bufsize); + wm_node_type_to_str(node->children.nodes[j]->type, buf2, bufsize); fprintf(fp, "_%d_%s -> _%d_%s;\n", node->id, buf1, - node->children.nodes[j].id, buf2); + node->children.nodes[j]->id, buf2); } - wm_nodearray_push(&printed_nodes, *node); + wm_nodearray_push(&printed_nodes, node); } fprintf(fp, "}"); @@ -132,14 +139,14 @@ void wm_tree_to_DOT(TreeNode *root, const char *filename) fflush(fp); fclose(fp); - wm_nodearray_free(&printed_nodes); + __wm_nodearray_free(&printed_nodes); wm_ptrarray_free(&all_nodes); } int wm_get_node_index(TreeNode *parent, unsigned int node_id) { for (size_t i = 0; i < parent->children.size; i++) { - if (node_id == parent->children.nodes[i].id) + if (node_id == parent->children.nodes[i]->id) return i; } @@ -168,7 +175,7 @@ void wm_treenode_remove_node(TreeNode *root, unsigned int node_id) TreeNode* wm_treenode_split_get_sibling(TreeNode *node) { for (size_t i = 0; i < node->parent->children.size; i++) { - TreeNode *sibling_node = &node->parent->children.nodes[i]; + TreeNode *sibling_node = node->parent->children.nodes[i]; if (sibling_node->id != node->id) { return sibling_node; } @@ -186,21 +193,20 @@ TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client) if (client_node->parent == NULL) { client_node->client = NULL; - wm_nodearray_clear(&client_node->children); - wm_nodearray_free(&client_node->children); + wm_treenode_free(client_node); return NULL; } TreeNode *node = client_node->parent; for (size_t i = 0; i < node->children.size; i++) { - if (node->children.nodes[i].type == NODE_CLIENT && - node->children.nodes[i].client != client) { + if (node->children.nodes[i]->type == NODE_CLIENT && + node->children.nodes[i]->client != client) { node->type = NODE_CLIENT; - node->client = node->children.nodes[i].client; - wm_nodearray_free(&client_node->children); - wm_nodearray_free(&node->children.nodes[i].children); + node->client = node->children.nodes[i]->client; + wm_treenode_free(client_node); + wm_treenode_free(node->children.nodes[i]); wm_nodearray_clear(&node->children); return node; } @@ -209,7 +215,7 @@ TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client) DEBUG_PRINT("%s: other_client was NULL!\n", __func__); TreeNode *sibling_node = wm_treenode_split_get_sibling(client_node); - wm_nodearray_free(&client_node->children); + wm_treenode_free(client_node); // wm_nodearray_free(&node->children); @@ -220,22 +226,22 @@ TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client) // parent is root node DEBUG_PRINT("parent is root node!\n"); sibling_node->parent = NULL; - client->ws->tree = *sibling_node; + client->ws->tree = sibling_node; - client->ws->tree.pos = (Rect) { + client->ws->tree->pos = (Rect) { .x = wm->config.border_width, .y = wm->config.border_width + dock_y , .w = client->ws->monitor->info.width - wm->config.border_width*2, .h = client->ws->monitor->info.height - wm->config.border_width*2 - dock_y, }; - assert(client->ws->tree.children.size == 2); - wm_treenode_split_space(&client->ws->tree, &client->ws->tree.children.nodes[0].pos, - &client->ws->tree.children.nodes[1].pos); + assert(client->ws->tree->children.size == 2); + wm_treenode_split_space(client->ws->tree, &client->ws->tree->children.nodes[0]->pos, + &client->ws->tree->children.nodes[1]->pos); } else *node = *sibling_node; - assert(client->ws->tree.children.size >= 1); - return &node->children.nodes[0]; + assert(client->ws->tree->children.size >= 1); + return node->children.nodes[0]; } NodeArray wm_nodearray_new() @@ -243,27 +249,27 @@ NodeArray wm_nodearray_new() NodeArray arr; arr.capacity = 10; - arr.nodes = calloc(arr.capacity, sizeof(TreeNode)); + arr.nodes = calloc(arr.capacity, sizeof(TreeNode*)); arr.size = 0; return arr; } -void wm_nodearray_push(NodeArray *arr, TreeNode node) +void wm_nodearray_push(NodeArray *arr, TreeNode *node) { assert(arr); arr->size++; if (arr->size >= arr->capacity) { - TreeNode* temp = calloc(arr->capacity, sizeof(TreeNode)); - memcpy(temp, arr->nodes, arr->capacity * sizeof(TreeNode)); + TreeNode* temp = calloc(arr->capacity, sizeof(TreeNode*)); + memcpy(temp, arr->nodes, arr->capacity * sizeof(TreeNode*)); free(arr->nodes); size_t old_capacity = arr->capacity; arr->capacity = old_capacity * 2; - arr->nodes = calloc(arr->capacity, sizeof(TreeNode)); - memcpy(arr->nodes, temp, old_capacity * sizeof(TreeNode)); + arr->nodes = calloc(arr->capacity, sizeof(TreeNode*)); + memcpy(arr->nodes, temp, old_capacity * sizeof(TreeNode*)); free(temp); arr->nodes[arr->size - 1] = node; @@ -282,7 +288,7 @@ bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret) if (arr->size == 0) return false; - *ret = arr->nodes[arr->size - 1]; + ret = arr->nodes[arr->size - 1]; arr->size--; return true; } @@ -295,9 +301,9 @@ bool wm_nodearray_pop_front(NodeArray *arr, TreeNode *ret) if (arr->size == 0) return false; - *ret = arr->nodes[0]; + ret = arr->nodes[0]; arr->size--; - memmove(arr->nodes, arr->nodes+1, arr->size * sizeof(TreeNode)); + memmove(arr->nodes, arr->nodes+1, arr->size * sizeof(TreeNode*)); return true; } @@ -306,7 +312,7 @@ void wm_nodearray_clear(NodeArray *arr) { DEBUG_PRINT("%s\n", __func__); arr->size = 0; - memset(arr->nodes, 0, arr->capacity * sizeof(TreeNode)); + memset(arr->nodes, 0, arr->capacity * sizeof(TreeNode*)); } bool wm_nodearray_remove(NodeArray *arr, size_t index) @@ -325,14 +331,14 @@ bool wm_nodearray_remove(NodeArray *arr, size_t index) return true; } - memmove(arr->nodes + index, arr->nodes + index+1, arr->size-1 * sizeof(TreeNode)); + memmove(arr->nodes + index, arr->nodes + index+1, arr->size-1 * sizeof(TreeNode*)); return true; } -void wm_nodearray_free(NodeArray *arr) +void __wm_nodearray_free(NodeArray *arr) { - DEBUG_PRINT("%s\n", __func__); + // DEBUG_PRINT("%s\n", __func__); assert(arr); arr->capacity = 0; @@ -349,12 +355,12 @@ ClientArray wm_nodearray_find_clients(TreeNode *root) /* storing visited nodes in an array and searching is not optimal, but this is not a performance-critical function. */ NodeArray visited = wm_nodearray_new(); - wm_nodearray_push(&visited, *root); + wm_nodearray_push(&visited, root); NodeArray queue = wm_nodearray_new(); ClientArray clients = wm_clientarray_new(); - wm_nodearray_push(&queue, *root); + wm_nodearray_push(&queue, root); while (queue.size > 0) { TreeNode node; @@ -366,11 +372,11 @@ ClientArray wm_nodearray_find_clients(TreeNode *root) wm_clientarray_push(&clients, *node.client); for (size_t i = 0; i < node.children.size; i++) { - TreeNode child_node = node.children.nodes[i]; + TreeNode *child_node = node.children.nodes[i]; bool _visited = false; for (size_t j = 0; j < visited.size; j++) { - if (visited.nodes[j].id == child_node.id) { + if (visited.nodes[j]->id == child_node->id) { _visited = true; break; } @@ -384,8 +390,8 @@ ClientArray wm_nodearray_find_clients(TreeNode *root) } ret: - wm_nodearray_free(&visited); - wm_nodearray_free(&queue); + __wm_nodearray_free(&visited); + __wm_nodearray_free(&queue); return clients; } @@ -476,7 +482,7 @@ bool wm_ptrarray_remove(PtrArray *arr, size_t index) void wm_ptrarray_free(PtrArray *arr) { - DEBUG_PRINT("%s\n", __func__); + // DEBUG_PRINT("%s\n", __func__); assert(arr); arr->capacity = 0; @@ -492,7 +498,7 @@ TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root) TreeNode *ret = NULL; NodeArray visited = wm_nodearray_new(); - wm_nodearray_push(&visited, *root); + wm_nodearray_push(&visited, root); PtrArray queue = wm_ptrarray_new(); @@ -510,25 +516,25 @@ TreeNode* wm_treenode_ptr_find_focused_client_node(TreeNode *root) } for (size_t i = 0; i < node->children.size; i++) { - TreeNode *child_node = &node->children.nodes[i]; + TreeNode *child_node = node->children.nodes[i]; bool _visited = false; for (size_t j = 0; j < visited.size; j++) { - if (visited.nodes[j].id == child_node->id) { + if (visited.nodes[j]->id == child_node->id) { _visited = true; break; } } if (!_visited) { - wm_nodearray_push(&visited, *child_node); + wm_nodearray_push(&visited, child_node); wm_ptrarray_push(&queue, child_node); } } } ret: - wm_nodearray_free(&visited); + __wm_nodearray_free(&visited); wm_ptrarray_free(&queue); return ret; } @@ -562,7 +568,7 @@ PtrArray wm_treenode_find_client_nodes_ptr(TreeNode *root) PtrArray ret = wm_ptrarray_new(); NodeArray visited = wm_nodearray_new(); - wm_nodearray_push(&visited, *root); + wm_nodearray_push(&visited, root); PtrArray queue = wm_ptrarray_new(); @@ -578,25 +584,25 @@ PtrArray wm_treenode_find_client_nodes_ptr(TreeNode *root) wm_ptrarray_push(&ret, node); for (size_t i = 0; i < node->children.size; i++) { - TreeNode *child_node = &node->children.nodes[i]; + TreeNode *child_node = node->children.nodes[i]; bool _visited = false; for (size_t j = 0; j < visited.size; j++) { - if (visited.nodes[j].id == child_node->id) { + if (visited.nodes[j]->id == child_node->id) { _visited = true; break; } } if (!_visited) { - wm_nodearray_push(&visited, *child_node); + wm_nodearray_push(&visited, child_node); wm_ptrarray_push(&queue, child_node); } } } ret: - wm_nodearray_free(&visited); + __wm_nodearray_free(&visited); wm_ptrarray_free(&queue); return ret; } @@ -609,7 +615,7 @@ PtrArray wm_all_nodes_to_ptrarray(TreeNode *root) PtrArray ret = wm_ptrarray_new(); NodeArray visited = wm_nodearray_new(); - wm_nodearray_push(&visited, *root); + wm_nodearray_push(&visited, root); PtrArray queue = wm_ptrarray_new(); @@ -624,25 +630,25 @@ PtrArray wm_all_nodes_to_ptrarray(TreeNode *root) wm_ptrarray_push(&ret, node); for (size_t i = 0; i < node->children.size; i++) { - TreeNode *child_node = &node->children.nodes[i]; + TreeNode *child_node = node->children.nodes[i]; bool _visited = false; for (size_t j = 0; j < visited.size; j++) { - if (visited.nodes[j].id == child_node->id) { + if (visited.nodes[j]->id == child_node->id) { _visited = true; break; } } if (!_visited) { - wm_nodearray_push(&visited, *child_node); + wm_nodearray_push(&visited, child_node); wm_ptrarray_push(&queue, child_node); } } } ret: - wm_nodearray_free(&visited); + __wm_nodearray_free(&visited); wm_ptrarray_free(&queue); return ret; } diff --git a/src/util.h b/src/util.h index fbf244c..5268d51 100644 --- a/src/util.h +++ b/src/util.h @@ -25,7 +25,7 @@ typedef enum NodeType { typedef struct TreeNode TreeNode; typedef struct { - TreeNode *nodes; + TreeNode **nodes; size_t size; size_t capacity; } NodeArray; @@ -62,7 +62,8 @@ struct TreeNode { unsigned int id; }; -TreeNode wm_treenode_new(NodeType type, TreeNode *parent); +TreeNode* wm_treenode_new(NodeType type, TreeNode *parent); +void wm_treenode_free(TreeNode *node); bool wm_treenode_is_empty(TreeNode *node); void wm_treenode_split_space(TreeNode *node, Rect *ret1, Rect *ret2); TreeNode* wm_treenode_remove_client(Wm *wm, TreeNode *root, Client *client); @@ -72,12 +73,12 @@ void wm_tree_to_DOT(TreeNode *root, const char *filename); void wm_node_type_to_str(NodeType type, char *buf, size_t bufsize); NodeArray wm_nodearray_new(); -void wm_nodearray_push(NodeArray *arr, TreeNode node); +void wm_nodearray_push(NodeArray *arr, TreeNode *node); bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret); bool wm_nodearray_pop_front(NodeArray *arr, TreeNode *ret); void wm_nodearray_clear(NodeArray *arr); bool wm_nodearray_remove(NodeArray *arr, size_t index); -void wm_nodearray_free(NodeArray *arr); +void __wm_nodearray_free(NodeArray *arr); ClientArray wm_nodearray_find_clients(TreeNode *root);