Add Node2D
This commit is contained in:
parent
48908719fa
commit
643e2e5ba4
2
Makefile
2
Makefile
|
@ -6,7 +6,7 @@
|
|||
|
||||
CC="tcc"
|
||||
|
||||
main: src/main.c src/node.c
|
||||
main: src/main.c src/node/node.c src/node2d/node2d.c
|
||||
tcc -o $@ -I src $^
|
||||
|
||||
clean:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include<stdio.h>
|
||||
|
||||
#include "node.h"
|
||||
#include "node/node.h"
|
||||
#include "node2d/node2d.h"
|
||||
|
||||
int main(int argc, char* *argv){
|
||||
NOD_Node *distros = NOD_CreateNode("Distros");
|
||||
|
@ -20,6 +21,9 @@ int main(int argc, char* *argv){
|
|||
NOD_Node *openbsd = NOD_CreateNode("OpenBSD");
|
||||
NOD_Node *debianbsd = NOD_CreateNode("Debian GNU/kFreeBSD");
|
||||
|
||||
NOD_Node *test = NOD_CreateNode2D("This is a test");
|
||||
NOD_NodeAddChild(debian, test);
|
||||
|
||||
NOD_NodeAddChild(distros, linoox);
|
||||
NOD_NodeAddChild(distros, bsd);
|
||||
|
||||
|
@ -45,6 +49,7 @@ int main(int argc, char* *argv){
|
|||
|
||||
NOD_PrintNodeTree(distros);
|
||||
|
||||
NOD_DestroyNodeBranch(distros);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
208
src/node.c
208
src/node.c
|
@ -1,208 +0,0 @@
|
|||
#include "node.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
NOD_Node *NOD_CreateNode(char *name){
|
||||
NOD_Node *node = malloc(sizeof(NOD_Node));
|
||||
|
||||
if(node != NULL){
|
||||
node->name = name;
|
||||
|
||||
node->parent = NULL;
|
||||
node->childv = NULL;
|
||||
node->childc = 0;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void NOD_DestroyNode(NOD_Node *node){
|
||||
if(node != NULL){
|
||||
printf("NOD_Info: Deleting node \"%s\"\n", node->name);
|
||||
/** Cleanup dependencies on this node by its parent */
|
||||
NOD_NodeUnparent(node);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
void NOD_DestroyNodeBranch(NOD_Node *node){
|
||||
if(node != NULL){
|
||||
for(int i = 0; i < node->childc && node->childv != NULL; i++){
|
||||
NOD_DestroyNodeBranch(node->childv[i]);
|
||||
}
|
||||
NOD_DestroyNode(node);
|
||||
}
|
||||
}
|
||||
|
||||
void NOD_NodeAddChild(NOD_Node *parent, NOD_Node *child){
|
||||
if(parent != NULL && child != NULL){
|
||||
/** Prevent recursion */
|
||||
if(parent == child){
|
||||
fprintf(stderr, "NOD_Warning: A node cannot be added to itself.\n");
|
||||
return;
|
||||
}
|
||||
///** Don't allow tree-breaking reparenting */
|
||||
//NOD_Node *tmp_parent = parent->parent;
|
||||
//while(tmp_parent != NULL){
|
||||
//if(tmp_parent == child){
|
||||
//fprintf(stderr, "NOD_Warning: Can't add a parent of a node as its child.\n");
|
||||
//return;
|
||||
//}
|
||||
//tmp_parent = tmp_parent->parent;
|
||||
//}
|
||||
/** Check if child already in vector */
|
||||
for(int i = 0; i < parent->childc; i++){
|
||||
if(parent->childv[i] == child){
|
||||
fprintf(stderr, "NOD_Warning: Adding child \"%s\" already in the vector \"%s\".\n",
|
||||
child->name,
|
||||
parent->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** If it had a parent before, unparent before reparenting */
|
||||
if(child->parent != NULL && child->parent != parent){
|
||||
printf("NOD_Info: Reparenting node \"%s\"\n", child->name);
|
||||
NOD_NodeUnparent(child);
|
||||
}
|
||||
|
||||
/** Create child vector if it hasn't been used */
|
||||
if(parent->childc <= 0 || parent->childv == NULL){
|
||||
parent->childv = malloc(sizeof(child));
|
||||
|
||||
if(parent->childv != NULL){
|
||||
parent->childv[0] = child;
|
||||
parent->childc = 1;
|
||||
|
||||
child->parent = parent;
|
||||
|
||||
return;
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,
|
||||
"NOD_Error: Failed to allocate space on \"%s\"for child vector \"%s\"\n",
|
||||
parent->name, child->name);
|
||||
}
|
||||
}
|
||||
|
||||
/** If there is a blank space, use it */
|
||||
for(int i = 0; i < parent->childc; i++){
|
||||
if(parent->childv[i] == NULL){
|
||||
printf("NOD_Info: Reused blank space for child :D\n");
|
||||
parent->childv[i] = child;
|
||||
|
||||
child->parent = parent;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** If not, reallocate vector to fit the child */
|
||||
parent->childv = realloc(parent->childv,
|
||||
sizeof(child) *(parent->childc+1));
|
||||
|
||||
if(parent->childv != NULL){
|
||||
parent->childv[parent->childc] = child;
|
||||
parent->childc++;
|
||||
|
||||
child->parent = parent;
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,
|
||||
"NOD_Error: Failed to reallocate space on \"%s\"for child vector \"%s\"\n",
|
||||
parent->name, child->name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void NOD_NodeUnparent(NOD_Node *node){
|
||||
if(node != NULL && node->parent != NULL){
|
||||
NOD_Node *parent = node->parent;
|
||||
|
||||
for(int i = 0; i < parent->childc; i ++){
|
||||
if(parent->childv[i] == node){
|
||||
parent->childv[i] = NULL;
|
||||
|
||||
/* Free allocated memory if last child */
|
||||
if(i + 1 == parent->childc){
|
||||
fprintf(stderr,
|
||||
"NOD_Debug: Freeing last child \"%s\" of vector \"%s\"...\n",
|
||||
node->name, parent->name);
|
||||
parent->childv = realloc(parent->childv, sizeof(node) *parent->childc);
|
||||
parent->childc--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
node->parent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int get_child_pos(NOD_Node *node){
|
||||
int count = 0;
|
||||
if(node != NULL && node->parent != NULL){
|
||||
for(int i = 0; i < node->parent->childc; i++){
|
||||
if(node->parent->childv[i] == node) return count;
|
||||
count++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void nodetree_print_branch(NOD_Node *node, char* level){
|
||||
if(node != NULL){
|
||||
|
||||
for(int i = 0; level[i] != '\0'; i++){
|
||||
if(level[i] == 'y') printf("│ ");
|
||||
else printf(" ");
|
||||
}
|
||||
|
||||
if(node->parent != NULL){
|
||||
if(get_child_pos(node)+1 != node->parent->childc){
|
||||
printf("├─ ");
|
||||
strcat(level, "y");
|
||||
}
|
||||
else{
|
||||
printf("└─ ");
|
||||
strcat(level, "n");
|
||||
}
|
||||
}
|
||||
printf("%s\n", node->name);
|
||||
|
||||
/** Recurse */
|
||||
for(int i = 0; i < node->childc; i++){
|
||||
nodetree_print_branch(node->childv[i], level);
|
||||
}
|
||||
|
||||
if(node->parent != NULL){
|
||||
level = (char *)realloc(level, strlen(level) * sizeof(char));
|
||||
level[strlen(level)-1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NOD_PrintNodeTree(NOD_Node *node){
|
||||
if(node != NULL){
|
||||
char* level = strdup("");
|
||||
|
||||
printf("%s\n", node->name);
|
||||
for(int i = 0; i < node->childc; i++){
|
||||
nodetree_print_branch(node->childv[i], level);
|
||||
}
|
||||
|
||||
free(level);
|
||||
}
|
||||
}
|
||||
|
||||
int NOD_NodeChildCount(NOD_Node *node){
|
||||
int count = 0;
|
||||
for(int i = 0; i < node->childc; i++){
|
||||
if(node->childv[i] != NULL) count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
26
src/node.h
26
src/node.h
|
@ -1,26 +0,0 @@
|
|||
#ifndef __NODE_H_
|
||||
#define __NODE_H_
|
||||
|
||||
typedef struct node{
|
||||
char *name;
|
||||
|
||||
/** childc keeps track of allocated space,
|
||||
not amount of children. For that use
|
||||
NOD_NodeChildCount */
|
||||
int childc;
|
||||
struct node* *childv;
|
||||
struct node *parent;
|
||||
|
||||
} NOD_Node;
|
||||
|
||||
NOD_Node *NOD_CreateNode(char *name);
|
||||
void NOD_DestroyNode(NOD_Node *node);
|
||||
void NOD_DestroyNodeBranch(NOD_Node *node);
|
||||
|
||||
void NOD_NodeAddChild(NOD_Node *parent, NOD_Node *child);
|
||||
void NOD_NodeUnparent(NOD_Node *child);
|
||||
|
||||
void NOD_PrintNodeTree(NOD_Node *node);
|
||||
int NOD_NodeChildCount(NOD_Node *node);
|
||||
|
||||
#endif // __NODE_H_
|
Loading…
Reference in New Issue