00001 // Copyright (C) 2005 Dave Griffiths 00002 // 00003 // This program is free software; you can redistribute it and/or modify 00004 // it under the terms of the GNU General Public License as published by 00005 // the Free Software Foundation; either version 2 of the License, or 00006 // (at your option) any later version. 00007 // 00008 // This program is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 // GNU General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this program; if not, write to the Free Software 00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00016 00017 #include "Tree.h" 00018 #include "Trace.h" 00019 00020 using namespace Fluxus; 00021 00022 void Node::RemoveChild(int ID) 00023 { 00024 for (vector<Node*>::iterator i=Children.begin(); i!=Children.end(); ++i) 00025 { 00026 if ((*i)->ID==ID) 00027 { 00028 Children.erase(i); 00029 return; 00030 } 00031 } 00032 00033 Trace::Stream<<"Node::RemoveChild : could not find "<<ID<<endl; 00034 } 00035 00037 00038 Tree::Tree() 00039 { 00040 m_CurrentID=1; 00041 m_Root=NULL; 00042 } 00043 00044 Tree::~Tree() 00045 { 00046 RemoveNode(m_Root); 00047 } 00048 00049 int Tree::AddNode(int ParentID, Node *node) 00050 { 00051 if (m_Root!=NULL) 00052 { 00053 Node *parent=FindNode(ParentID); 00054 if (!parent) 00055 { 00056 Trace::Stream<<"Tree::AddNode : can't find parent node "<<ParentID<<endl; 00057 return 0; 00058 } 00059 00060 node->ID=m_CurrentID++; 00061 parent->Children.push_back(node); 00062 node->Parent=parent; 00063 } 00064 else 00065 { 00066 node->ID=m_CurrentID++; 00067 m_Root=node; 00068 } 00069 00070 // store in the node map for quick searching... 00071 m_NodeMap[node->ID]=node; 00072 00073 return node->ID; 00074 } 00075 00076 Node *Tree::FindNode(int ID) const 00077 { 00078 map<int,Node*>::const_iterator i=m_NodeMap.find(ID); 00079 if (i!=m_NodeMap.end()) 00080 { 00081 return i->second; 00082 } 00083 00084 return NULL; 00085 } 00086 00087 void Tree::RemoveNode(Node *node) 00088 { 00089 if (node==NULL) return; 00090 00091 // remove from node map 00092 map<int,Node*>::iterator i=m_NodeMap.find(node->ID); 00093 if (i!=m_NodeMap.end()) 00094 { 00095 m_NodeMap.erase(i); 00096 } 00097 00098 // if not root, remove ourself from our parent's child vector 00099 if (node->Parent) 00100 { 00101 node->Parent->RemoveChild(node->ID); 00102 } 00103 00104 RemoveNodeWalk(node); 00105 } 00106 00107 void Tree::RemoveNodeWalk(Node *node) 00108 { 00109 if (node==NULL) return; 00110 for (vector<Node*>::iterator i=node->Children.begin(); i!=node->Children.end(); ++i) 00111 { 00112 RemoveNodeWalk(*i); 00113 } 00114 00115 // remove from node map 00116 map<int,Node*>::iterator i=m_NodeMap.find(node->ID); 00117 if (i!=m_NodeMap.end()) 00118 { 00119 m_NodeMap.erase(i); 00120 } 00121 00122 delete node; 00123 } 00124 00125 bool Tree::IsDecendedFrom(Node *Parent, Node *Child) const 00126 { 00127 Node *current = Child; 00128 00129 // iterate back up the tree looking at parents... 00130 while(current!=NULL) 00131 { 00132 if (current==Parent) 00133 { 00134 return true; 00135 } 00136 current=current->Parent; 00137 } 00138 return false; 00139 } 00140 00141 void Tree::Dump(int Depth,Node *node) const 00142 { 00143 if (node==NULL) node=m_Root; 00144 if (node==NULL) return; 00145 00146 for (int n=0; n<Depth; n++) Trace::Stream<<" "; 00147 Trace::Stream<<node->ID<<endl; 00148 00149 Depth++; 00150 00151 for (vector<Node*>::iterator i=node->Children.begin(); i!=node->Children.end(); ++i) 00152 { 00153 Dump(Depth,*i); 00154 } 00155 }