Add Node2D
This commit is contained in:
		
							parent
							
								
									643e2e5ba4
								
							
						
					
					
						commit
						9e702bcdbb
					
				| 
						 | 
					@ -0,0 +1,213 @@
 | 
				
			||||||
 | 
					#include "node.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOD_Node *NOD_CreateNode(char *name){
 | 
				
			||||||
 | 
					  return NOD_CreateNodeEX("Node", name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOD_Node *NOD_CreateNodeEX(char* type, char *name){
 | 
				
			||||||
 | 
					  NOD_Node *node = malloc(sizeof(NOD_Node));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if(node != NULL){
 | 
				
			||||||
 | 
					    node->name = name;
 | 
				
			||||||
 | 
					    node->type = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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 (%s)\n", node->name, node->type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** 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 (%s)\n", node->name, node->type);
 | 
				
			||||||
 | 
					    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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					#ifndef __NODE_H_
 | 
				
			||||||
 | 
					#define __NODE_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct node{
 | 
				
			||||||
 | 
					  char *name;
 | 
				
			||||||
 | 
					  char *type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** childc keeps track of allocated space,
 | 
				
			||||||
 | 
					      not amount of children. For that use
 | 
				
			||||||
 | 
					      NOD_NodeChildCount */
 | 
				
			||||||
 | 
					  int childc;
 | 
				
			||||||
 | 
					  struct node* *childv;
 | 
				
			||||||
 | 
					  struct node *parent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void* data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} NOD_Node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOD_Node *NOD_CreateNode(char *name);
 | 
				
			||||||
 | 
					NOD_Node *NOD_CreateNodeEX(char *type, 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_
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					#include "node2d.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOD_Node *NOD_CreateNode2D(char *name){
 | 
				
			||||||
 | 
					  return NOD_CreateNodeEX("Node2D", name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					#include"../node/node.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include<stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOD_Node *NOD_CreateNode2D(char *name);
 | 
				
			||||||
 | 
					void NOD_DestroyNode2D(NOD_Node *node);
 | 
				
			||||||
		Loading…
	
		Reference in New Issue