#include #include #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(); }