Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

MyTree.h

Go to the documentation of this file.
00001 /* ***********************************************************************************
00002         Writer:         Sebastien Bloc
00003         Copyright:      2003-2004
00004         eMail:          sebastien.bloc@free.fr
00005         URL:            http://mignonsoft.free.fr
00006 
00007         This program is free software; you can redistribute it and/or
00008         modify it under the terms of the GNU General Public License
00009         as published by the Free Software Foundation; either version 2
00010         of the License, or (at your option) any later version.
00011 
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU General Public License for more details.
00016         http://www.gnu.org/copyleft/gpl.html
00017 *********************************************************************************** */
00018 
00023 #ifndef INCLUDE_MY_TREE_INCLUDE
00024 #define INCLUDE_MY_TREE_INCLUDE
00025 
00026 #include "MyList.h"
00027 
00028 
00037 template <class T> 
00038 class MyTreeNode
00039 {
00040 public:
00041         T *elem;                                                        // element de la liste 
00042         MyTreeNode *parent;
00043         MyList<MyTreeNode *> childs;      // enfants 
00044 
00045 private:
00046         void Init()
00047         {
00048                 elem = NULL;
00049                 parent=NULL;
00050         }
00051 
00052 public:
00053         typedef MyTreeNode<T> MyTreeNodeItem;
00054 
00055         MyTreeNode() { Init(); }
00056 
00057         MyTreeNode(T &_elem) 
00058         {
00059                 Init();
00060                 elem = new T;
00061                 if (!elem) throw MyExceptionMemory("MyTreeNode","constructor",sizeof(T));
00062                 *elem=_elem; //operator=(T &source) de la class appelé
00063         }
00064 
00066         MyTreeNode(T *_elem) 
00067         {
00068                 Init();
00069                 elem=_elem; 
00070         }
00071 
00072         ~MyTreeNode() 
00073         { 
00074                 if (elem) delete elem; 
00075         }
00076 
00077         BOOL SuprChilds(BOOL recursif=FALSE)
00078         {
00079                 MyTreeNodeItem *node;
00080                 MyListItem<MyTreeNodeItem *> *item;
00081                 item = childs.first;
00082                 while (item)
00083                 {
00084                         node = *item->elem;
00085                         item = item->after;
00086                         if (recursif) node->SuprChilds(TRUE);
00087                         node->SuprOnParent();
00088                         delete node;
00089                 }
00090                 return TRUE;
00091         }
00092 
00093         BOOL SuprOnParent()
00094         {
00095                 if (!parent) return FALSE;
00096                 if (!parent->childs.i.GoTo(this)) return FALSE;
00097                 parent->childs.i.Supr();
00098                 return TRUE;
00099         }
00100 
00101         MyTreeNode<T> * operator [] (int num)
00102         {
00103                 return childs[num];
00104         }
00105 
00109         BOOL MoveTo(MyTreeNode<T> *dest)
00110         {
00111                 if (!dest) return FALSE; // erreur si pas de destinataire
00112 
00113                 // supression des lien dans la source: recherche du lien du fils dans le pere
00114                 BOOL find=FALSE;
00115                 for (parent->childs.i=0;parent->childs.i.More();parent->childs.i++)
00116                 {
00117                         if (this==parent->childs.i.GetElem()) 
00118                         {
00119                                 parent->childs.i.Supr();
00120                                 find=TRUE;
00121                                 break;
00122                         }
00123                 }
00124                 if (!find) return FALSE; // pas trouvé dans la liste des fils du pere (normalement impossible)
00125 
00126                 // nouvelle emplacement dans la destination
00127                 parent=dest;
00128                 dest->childs.i+=this;
00129                 return TRUE; 
00130         }
00131 
00132         BOOL FindOnParent(MyListIterator<MyTreeNodeItem *> &it)
00133         {
00134                 if (!parent) return FALSE;
00135                 it.Bind(&parent->childs);
00136                 for (it=0;it.More();it++)
00137                 {
00138                         if (this==it.GetElem()) return TRUE;
00139                 }
00140                 return FALSE;
00141         }
00142 
00143         void MoveToFirstChild()
00144         {
00145                 MyListIterator<MyTreeNodeItem *> it;
00146                 if (FindOnParent(it))
00147                 {
00148                         it.MoveFirst();
00149                 }
00150         }
00151         void MoveToLastChild()
00152         {
00153                 MoveTo(parent);
00154         }
00155 
00156         T * Elems(int num)
00157         {
00158                 return childs.i[num]->elem;
00159         }
00160 
00161         void operator=(MyTreeNode &source)
00162         {
00163                 if (source.elem) 
00164                 {
00165                         elem = new T;
00166                         if (!elem) throw CMyExceptionMemory("MyTreeNode","operator=",sizeof(T));
00167                         *elem=*source.elem;
00168                 }
00169                 else elem=NULL;
00170                 parent=source.parent;
00171                 childs=source.childs;
00172         }
00173 };
00174 
00223 template <class T> 
00224 class MyTree
00225 {
00226 private:
00227         MyTreeNode<T> *root;
00228         MyTreeNode<T> *current;
00229 
00230 private:
00231         void Init()
00232         {
00233                 root = NULL;
00234                 current = NULL;
00235         }
00236 
00237 public:
00238         MyTreeNode<T> * GetRoot() { return root; }
00239         MyTreeNode<T> * GetCurrent() { return current; }
00240 
00241         MyTree()
00242         {
00243                 Init();
00244         }
00245 
00246         ~MyTree()
00247         {
00248                 SuprAll();
00249         }
00250 
00251         BOOL SuprNode(MyTreeNode<T> *node,BOOL recursif=TRUE)
00252         {
00253                 if (!node) return FALSE;
00254                 if (recursif) node->SuprChilds(TRUE);
00255                 node->SuprOnParent();
00256                 delete node;
00257                 return TRUE;
00258         }
00259 
00260         void SuprAll()
00261         {
00262                 SuprNode(root);
00263                 Init();
00264         }
00265 
00266         void operator=(MyTreeNode<T> *node)
00267         {
00268                 SuprAll();
00269                 operator+=(node);
00270         }
00271 
00272         void operator+=(MyTreeNode<T> *node)
00273         {
00274                 Clone (node,NULL);
00275         }
00276 
00277         void Clone(MyTreeNode<T> *nodeSource,MyTreeNode<T> *nodeParentClone)
00278         {
00279                 if (!nodeSource) return;
00280                 nodeParentClone = Add(*nodeSource->elem,nodeParentClone);
00281                 for (nodeSource->childs.i=0;nodeSource->childs.i.More();nodeSource->childs.i++)
00282                 {
00283                         Clone(nodeSource->childs.i.GetElem(),nodeParentClone);
00284                 }
00285         }
00286 
00287         void operator=(MyTree<T> *otherTree)
00288         {
00289                 SuprAll();
00290                 operator+=(otherTree->GetRoot());
00291         }
00292 
00293         void operator+=(MyTree<T> *otherTree)
00294         {
00295                 operator+=(otherTree->GetRoot());
00296         }
00297 
00298         MyTreeNode<T> *GoToChild(int numChild,MyTreeNode<T> *parent=NULL)
00299         {
00300                 MyTreeNode<T> *xcurrent = GetChild(numChild,parent);
00301                 if (xcurrent) current=xcurrent;
00302                 return xcurrent;
00303         }
00304 
00305         MyTreeNode<T> * GoTo(MyTreeNode<T> *node)
00306         {
00307                 MyTreeNode<T> * oldCurrent;
00308                 oldCurrent = current;
00309                 current=node;
00310                 return oldCurrent;
00311         }
00312 
00313         MyTreeNode<T> *GetChild(int numChild,MyTreeNode<T> *parent=NULL)
00314         {
00315                 if (!parent) 
00316                 {
00317                         parent = current;
00318                         if (!parent) return NULL;
00319                 }
00320                 return parent->childs.i[numChild];
00321         }
00322 
00323         MyTreeNode<T> *GoToParent(MyTreeNode<T> *parent=NULL)
00324         {
00325                 MyTreeNode<T> *xcurrent = GetParent(parent);
00326                 if (current) current=xcurrent;
00327                 return xcurrent;
00328         }
00329 
00330         MyTreeNode<T> *GetParent(MyTreeNode<T> *parent=NULL)
00331         {
00332                 if (!parent) 
00333                 {
00334                         parent = current;
00335                         if (!parent) return NULL;
00336                 }
00337                 return parent->parent;
00338         }
00339 
00340         MyTreeNode<T> * Add(T& elem,MyTreeNode<T> *parent=NULL)
00341         {
00342                 MyTreeNode<T> *node = new MyTreeNode<T>(elem); // Creation d'un nouveau noeud
00343                 if (!parent) parent = current;    // Attacher ce noeud a son parent
00344                 if (parent)                      // si premier alors devient root
00345                 {
00346                         node->parent = parent;
00347                         parent->childs.i+=node;
00348                 }
00349                 else { current = root = node; }
00350                 return node;
00351         }
00352 
00353         MyTreeNode<T> * Add(T* elem,MyTreeNode<T> *parent=NULL)
00354         {
00355                 MyTreeNode<T> *node = new MyTreeNode<T>(elem); // Creation d'un nouveau noeud
00356                 if (!parent) parent = current;    // Attacher ce noeuf a son parent
00357                 if (parent)                      // si premier alors devient root
00358                 {
00359                         node->parent = parent;
00360                         parent->childs.i+=node;
00361                 }
00362                 else { current = root = node; }
00363                 return node;
00364         }
00365 };
00366 
00367 #endif

Generated on Fri Aug 20 19:19:48 2004 for 3d Controls by doxygen 1.3.6