Newton Dynamics  4.00
ndNodeHierarchy.h
1 /* Copyright (c) <2003-2022> <Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely
10 */
11 
12 #ifndef __ND_NODE_HIERARCHY_H__
13 #define __ND_NODE_HIERARCHY_H__
14 
15 #include "ndCoreStdafx.h"
16 #include "ndContainersAlloc.h"
17 
18 template<class T>
20 {
21  public:
22  ndNodeHierarchy ();
23  virtual T* CreateClone() const;
24 
25  void Attach(ndNodeHierarchy<T>* const parent);
26  void Detach ();
27 
28  T* GetParent() const;
29  T* GetLastChild() const;
30  T* GetFirstChild() const;
31 
32  T* GetPrev() const;
33  T* GetNext () const;
34  T* GetRoot () const;
35 
36  T* IteratorFirst() const;
37  T* IteratorNext() const;
38 
39  protected:
40  ndNodeHierarchy (const ndNodeHierarchy<T>& clone);
41  virtual ~ndNodeHierarchy ();
42 
43  ndNodeHierarchy<T>* m_next;
44  ndNodeHierarchy<T>* m_prev;
45  ndNodeHierarchy<T>* m_parent;
46  ndNodeHierarchy<T>* m_lastChild;
47  ndNodeHierarchy<T>* m_firstChild;
48 };
49 
50 template<class T>
53  ,m_next(nullptr)
54  ,m_prev(nullptr)
55  ,m_parent(nullptr)
56  ,m_lastChild(nullptr)
57  ,m_firstChild(nullptr)
58 {
59 }
60 
61 template<class T>
64  ,m_next(nullptr)
65  ,m_prev(nullptr)
66  ,m_parent(nullptr)
67  ,m_lastChild(nullptr)
68  ,m_firstChild(nullptr)
69 {
70  for (ndNodeHierarchy<T>* obj = clone.m_firstChild; obj; obj = obj->m_next)
71  {
72  T* const child = obj->CreateClone();
73  child->Attach(this);
74  }
75 }
76 
77 template<class T>
79 {
80  while (m_firstChild)
81  {
82  delete m_firstChild;
83  }
84  if (m_parent)
85  {
86  ndAssert(!m_prev);
87  if (m_next)
88  {
89  m_next->m_prev = nullptr;
90  }
91  m_parent->m_firstChild = m_next;
92  if (!m_next)
93  {
94  m_parent->m_lastChild = nullptr;
95  }
96  }
97  else if (m_next)
98  {
99  m_next->m_prev = nullptr;
100  }
101  m_next = nullptr;
102  ndAssert(!m_prev);
103  ndAssert(!m_lastChild);
104  ndAssert(!m_firstChild);
105 }
106 
107 template<class T>
109 {
110  return (T*) new ndNodeHierarchy<T>(*this);
111 }
112 
113 template<class T>
115 {
116  ndAssert(parent);
117  ndAssert(!m_parent);
118 
119  m_parent = parent;
120  if (m_parent->m_firstChild)
121  {
122  ndAssert(!m_prev);
123  m_prev = m_parent->m_lastChild;
124  m_parent->m_lastChild->m_next = this;
125  }
126  else
127  {
128  m_parent->m_firstChild = this;
129  }
130  m_parent->m_lastChild = this;
131 }
132 
133 template<class T>
135 {
136  ndAssert(0);
137  //NodeBaseHierarchy::Detach ();
138 }
139 
140 template<class T>
142 {
143  return (T*)m_firstChild;
144 }
145 
146 template<class T>
148 {
149  return (T*)m_lastChild;
150 }
151 
152 template<class T>
154 {
155  return (T*)m_next;
156 }
157 
158 template<class T>
160 {
161  return (T*)m_prev;
162 }
163 
164 template<class T>
166 {
167  return (T*) m_parent;
168 }
169 
170 template<class T>
171 T* ndNodeHierarchy<T>::GetRoot () const
172 {
173  const ndNodeHierarchy<T>* root = this;
174  for (; root->m_parent; root = root->m_parent);
175  return (T*)root;
176 }
177 
178 template<class T>
180 {
181  const ndNodeHierarchy<T>* ptr = this;
182  for (; ptr->m_firstChild; ptr = ptr->m_firstChild);
183  return (T*)ptr;
184 }
185 
186 template<class T>
188 {
189  if (m_next)
190  {
191  return m_next->IteratorFirst();
192  }
193 
194  const ndNodeHierarchy<T>* x = this;
195  const ndNodeHierarchy<T>* ptr = m_parent;
196  for (; ptr && (x == ptr->m_next); ptr = ptr->m_parent)
197  {
198  x = ptr;
199  }
200  return (T*)ptr;
201 }
202 
203 #endif
204 
ndNodeHierarchy
Definition: ndNodeHierarchy.h:20
ndContainersFreeListAlloc
Definition: ndContainersAlloc.h:60