structure dorne cli as a binary tree

This commit is contained in:
Emile Clark-Boman 2025-09-10 22:49:24 +10:00
parent c3074a75eb
commit 79272e8421
2 changed files with 174 additions and 0 deletions

116
cli/tree.c Normal file
View file

@ -0,0 +1,116 @@
#include <assert.h>
#include <stdlib.h>
#include "curse.h"
#include "tree.h"
/* Internal allocator method for crs_node structures.
*/
static inline struct crs_node *__alloc_node(const enum crs_nodetype type) {
struct crs_node *node = (struct crs_node *)malloc(sizeof(struct crs_node));
node->type = type;
return node;
}
/* Construct a new window node (crs_node of type NODE_WIN).
*/
static struct crs_node *init_node_window(WINDOW *win) {
struct crs_node *node = __alloc_node(NODE_WINDOW);
node->win = win;
return node;
}
static struct crs_node *init_node_abstract(struct crs_node *node1,
struct crs_node *node2,
float ratio) {
struct crs_node *node = __alloc_node(NODE_ABSTRACT);
node->ratio = ratio;
node->child[0] = node1;
node->child[1] = node2;
return node;
}
static void destroy_node(struct crs_node *node) {
if (node->type == NODE_WINDOW) {
/* Window Node */
delwin(node->win);
goto end;
}
/* Abstract Node */
destroy_node(node->child[0]);
destroy_node(node->child[1]);
end:
free(node);
}
/* Subdivide a window node's allocated region into two window nodes
* replacing the original node with an abstract node.
* Parameters:
* axis - controls which direction the subdivision occurs
* invert - invert index of the original node in the new abstract node
*/
static void bifurcate_window_node(struct crs_node **node, enum crs_axis axis,
int invert, float ratio) {
assert((*node)->type == NODE_ABSTRACT);
struct crs_node *original_node = *node;
struct crs_node *bi_node = init_node_window(); // WARNING: TODO
if (!invert) {
/* Inverted Bifurcation */
*node = init_node_abstract(bi_node, original_node, ratio);
} else {
/* Non-Inverted Bifurcation */
*node = init_node_abstract(original_node, bi_node, ratio);
}
resize_abstract_node(*node);
}
/* Collapse an abstract node, killing one child node and resizing
* the other to take its place.
*/
static void collapse_abstract_node(struct crs_node **node,
const int collapse_i) {
assert((*node)->type == NODE_ABSTRACT);
assert(0 <= collapse_i && collapse_i < NODE_CHILD_N);
// WARNING: only works for NODE_CHILD_N=2 (binary trees)
destroy_node((*node)->child[!collapse_i]);
struct crs_node *collapse_target = (*node)->child[collapse_i];
free(*node);
*node = collapse_target;
}
/*
*/
static struct crs_node *init_root_node(void) {
WINDOW *rootwin = newwin(0, 0, 0, 0);
return init_node_window(rootwin);
}
int init_tree(struct crs_tree **tree) {
*tree = (struct crs_tree *)malloc(sizeof(struct crs_tree));
/* Initialise NCurses Library & Standard Screen */
crs_init(&(*tree)->stdscr);
/* */
(*tree)->root = init_root_node();
// (*tree)->root = __alloc_node(NODE_WINDOW);
// crs_init(&(*tree)->root->win);
return EXIT_SUCCESS;
}
void destroy_tree(struct crs_tree *tree) {
/* WARNING: is it ok to delwin(stdscr) ?? */
destroy_node(tree->root);
endwin();
}

58
cli/tree.h Normal file
View file

@ -0,0 +1,58 @@
#ifndef DORNE_TREE_H
#define DORNE_TREE_H
# ifndef __NCURSES_H
typedef struct _win_st WINDOW;
# endif /* __NCURSES_H */
#define NODE_CHILD_N 2
/* MACRO:
* void NODEDIMS(struct crs_node *node, struct crs_nodedims dims);
*/
#define NODEDIMS(node, dims) (getbegyx(dims.y, dims.x); getmaxyx(dims.y, dims.x))
enum crs_nodetype {
NODE_WINDOW,
NODE_ABSTRACT,
};
/* Stores a node's starting x,y coordinates, width, & height.
* NOTE: Intended for interfunction communication.
*/
struct crs_nodedims {
int x, y, width, height;
};
enum crs_axis {
AXIS_X,
AXIS_Y,
};
struct crs_node {
enum crs_nodetype type;
// union value depends on crs_node.type
union {
WINDOW *win;
struct {
float ratio;
struct crs_node *child[NODE_CHILD_N];
};
};
};
struct crs_tree {
WINDOW *stdscr;
struct crs_node *root;
};
/* === External Interface === */
// struct crs_node *init_node_window(void);
// struct crs_node *init_node_abstract(void);
// void destroy_node(struct crs_node *node);
int init_tree(struct crs_tree **tree);
void update_tree(struct crs_tree *tree);
void destroy_tree(struct crs_tree *tree);
#endif /* DORNE_TREE_H */