mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-11 22:54:34 +00:00
cleanups and a few more utility methods
This commit is contained in:
parent
0175c109ac
commit
09f0fa2861
1 changed files with 171 additions and 17 deletions
|
|
@ -32,13 +32,20 @@ class TreeNode : public Vector<TreeNode<T>*> {
|
||||||
public:
|
public:
|
||||||
T data;
|
T data;
|
||||||
TreeNode<T>* parent;
|
TreeNode<T>* parent;
|
||||||
TreeNode(const T& val = T(), TreeNode<T>* p = NULL) : data(val), parent(p){}
|
TreeNode(const T& val = T(), TreeNode<T>* p = NULL) : data(val), parent(p) {}
|
||||||
virtual ~TreeNode()
|
virtual ~TreeNode()
|
||||||
{
|
{
|
||||||
deleteChildren();
|
deleteChildren();
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
{
|
||||||
parent->remove(this);
|
for (U32 i = 0; i < parent->size(); i++)
|
||||||
|
{
|
||||||
|
if ((*parent)[i] == this)
|
||||||
|
{
|
||||||
|
parent->erase(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,12 +53,14 @@ public:
|
||||||
//description logic
|
//description logic
|
||||||
inline bool isRoot() const { return parent == NULL; }
|
inline bool isRoot() const { return parent == NULL; }
|
||||||
inline bool isLeaf() const { return size() == 0; }
|
inline bool isLeaf() const { return size() == 0; }
|
||||||
|
// Parent logic
|
||||||
//parent logic
|
|
||||||
inline TreeNode<T>* getParent() const { return parent; }
|
inline TreeNode<T>* getParent() const { return parent; }
|
||||||
|
|
||||||
inline void setParent(TreeNode<T>* p)
|
inline void setParent(TreeNode<T>* p)
|
||||||
{
|
{
|
||||||
if (parent) parent->remove(this);
|
if (parent == p) return;
|
||||||
|
|
||||||
|
if (parent) parent->removeChild(this);
|
||||||
parent = p;
|
parent = p;
|
||||||
if (parent) parent->push_back(this);
|
if (parent) parent->push_back(this);
|
||||||
}
|
}
|
||||||
|
|
@ -65,10 +74,21 @@ public:
|
||||||
}
|
}
|
||||||
inline void addChild(TreeNode<T>* child)
|
inline void addChild(TreeNode<T>* child)
|
||||||
{
|
{
|
||||||
if (child) {
|
if (!child) return;
|
||||||
child->parent = this;
|
|
||||||
push_back(child);
|
// Check if already a child to prevent duplicates
|
||||||
|
for (U32 i = 0; i < size(); i++)
|
||||||
|
{
|
||||||
|
if ((*this)[i] == child)
|
||||||
|
return; // Already a child
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove from old parent if needed
|
||||||
|
if (child->parent && child->parent != this)
|
||||||
|
child->parent->removeChild(child);
|
||||||
|
|
||||||
|
child->parent = this;
|
||||||
|
push_back(child);
|
||||||
}
|
}
|
||||||
inline void setChild(U32 i, TreeNode<T>* child)
|
inline void setChild(U32 i, TreeNode<T>* child)
|
||||||
{
|
{
|
||||||
|
|
@ -80,12 +100,41 @@ public:
|
||||||
(*this)[j] = NULL;
|
(*this)[j] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TreeNode<T>* oldChild = (*this)[i];
|
||||||
|
if (oldChild == child) return;
|
||||||
|
|
||||||
|
// Unlink old child
|
||||||
|
if (oldChild)
|
||||||
|
{
|
||||||
|
oldChild->parent = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (child == NULL)
|
if (child == NULL)
|
||||||
{
|
{
|
||||||
removeChild(i);
|
(*this)[i] = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Handle moving from different parent vs same parent
|
||||||
|
if (child->parent && child->parent != this)
|
||||||
|
{
|
||||||
|
child->parent->removeChild(child);
|
||||||
|
}
|
||||||
|
else if (child->parent == this)
|
||||||
|
{
|
||||||
|
// Moving within same parent - find and remove from old slot
|
||||||
|
for (U32 j = 0; j < size(); j++)
|
||||||
|
{
|
||||||
|
if (j != i && (*this)[j] == child)
|
||||||
|
{
|
||||||
|
erase(j);
|
||||||
|
if (j < i)
|
||||||
|
i--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(*this)[i] = child;
|
(*this)[i] = child;
|
||||||
child->parent = this;
|
child->parent = this;
|
||||||
}
|
}
|
||||||
|
|
@ -93,8 +142,6 @@ public:
|
||||||
|
|
||||||
inline TreeNode<T>* getChild(U32 i) const
|
inline TreeNode<T>* getChild(U32 i) const
|
||||||
{
|
{
|
||||||
if (!this)
|
|
||||||
return NULL;
|
|
||||||
if (i < size())
|
if (i < size())
|
||||||
return (*this)[i];
|
return (*this)[i];
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -103,12 +150,28 @@ public:
|
||||||
inline void addChildren(const Vector<T>* children)
|
inline void addChildren(const Vector<T>* children)
|
||||||
{
|
{
|
||||||
if (!children) return;
|
if (!children) return;
|
||||||
for (U32 i = 0; i < children->size(); i++) {
|
for (U32 i = 0; i < children->size(); i++)
|
||||||
|
{
|
||||||
TreeNode<T>* child = new TreeNode<T>((*children)[i], this);
|
TreeNode<T>* child = new TreeNode<T>((*children)[i], this);
|
||||||
push_back(child);
|
push_back(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void removeChild(TreeNode<T>* child)
|
||||||
|
{
|
||||||
|
if (!child) return;
|
||||||
|
|
||||||
|
for (U32 i = 0; i < size(); i++)
|
||||||
|
{
|
||||||
|
if ((*this)[i] == child)
|
||||||
|
{
|
||||||
|
child->parent = NULL;
|
||||||
|
erase(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void removeChild(U32 i)
|
inline void removeChild(U32 i)
|
||||||
{
|
{
|
||||||
if (i < size())
|
if (i < size())
|
||||||
|
|
@ -119,6 +182,62 @@ public:
|
||||||
erase(i);
|
erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inline void replaceChild(TreeNode<T>* oldChild, TreeNode<T>* newChild)
|
||||||
|
{
|
||||||
|
if (!oldChild) return;
|
||||||
|
|
||||||
|
for (U32 i = 0; i < size(); i++)
|
||||||
|
{
|
||||||
|
if ((*this)[i] == oldChild)
|
||||||
|
{
|
||||||
|
oldChild->parent = NULL;
|
||||||
|
|
||||||
|
if (newChild)
|
||||||
|
{
|
||||||
|
// Handle moving from different parent vs same parent
|
||||||
|
if (newChild->parent && newChild->parent != this)
|
||||||
|
{
|
||||||
|
newChild->parent->removeChild(newChild);
|
||||||
|
}
|
||||||
|
else if (newChild->parent == this)
|
||||||
|
{
|
||||||
|
// Moving within same parent - find and remove from old slot
|
||||||
|
for (U32 j = 0; j < size(); j++)
|
||||||
|
{
|
||||||
|
if (j != i && (*this)[j] == newChild)
|
||||||
|
{
|
||||||
|
erase(j);
|
||||||
|
if (j < i)
|
||||||
|
i--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*this)[i] = newChild;
|
||||||
|
newChild->parent = this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*this)[i] = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void compact()
|
||||||
|
{
|
||||||
|
// Remove NULL entries from children array
|
||||||
|
for (U32 i = 0; i < size(); )
|
||||||
|
{
|
||||||
|
if ((*this)[i] == NULL)
|
||||||
|
erase(i);
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void operator =(Vector<T>* other) { clear(); addChildren(other); }
|
void operator =(Vector<T>* other) { clear(); addChildren(other); }
|
||||||
|
|
||||||
inline U32 getNumChildren() const { return size(); }
|
inline U32 getNumChildren() const { return size(); }
|
||||||
|
|
@ -128,13 +247,18 @@ public:
|
||||||
Vector<TreeNode<T>*> children;
|
Vector<TreeNode<T>*> children;
|
||||||
children.reserve(size());
|
children.reserve(size());
|
||||||
for (U32 i = 0; i < size(); i++)
|
for (U32 i = 0; i < size(); i++)
|
||||||
children.push_back((*this)[i]);
|
{
|
||||||
|
if ((*this)[i]) // Skip NULLs
|
||||||
|
children.push_back((*this)[i]);
|
||||||
|
}
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void deleteChildren()
|
inline void deleteChildren()
|
||||||
{
|
{
|
||||||
Vector<TreeNode<T>*> children;
|
Vector<TreeNode<T>*> children;
|
||||||
for (U32 i = 0; i < size(); i++) {
|
for (U32 i = 0; i < size(); i++)
|
||||||
|
{
|
||||||
children.push_back((*this)[i]);
|
children.push_back((*this)[i]);
|
||||||
}
|
}
|
||||||
clear();
|
clear();
|
||||||
|
|
@ -156,9 +280,10 @@ public:
|
||||||
if (!parent) return siblings;
|
if (!parent) return siblings;
|
||||||
|
|
||||||
siblings.reserve(parent->size() - 1);
|
siblings.reserve(parent->size() - 1);
|
||||||
for (U32 i = 0; i < parent->size(); i++) {
|
for (U32 i = 0; i < parent->size(); i++)
|
||||||
|
{
|
||||||
TreeNode<T>* sibling = (*parent)[i];
|
TreeNode<T>* sibling = (*parent)[i];
|
||||||
if (sibling != this)
|
if (sibling && sibling != this) // Skip NULLs
|
||||||
siblings.push_back(sibling);
|
siblings.push_back(sibling);
|
||||||
}
|
}
|
||||||
return siblings;
|
return siblings;
|
||||||
|
|
@ -169,6 +294,35 @@ public:
|
||||||
inline void setData(const T& val) { data = val; }
|
inline void setData(const T& val) { data = val; }
|
||||||
inline void operator =(const T& val) { data = val; }
|
inline void operator =(const T& val) { data = val; }
|
||||||
inline T* getDataPtr() { return &data; }
|
inline T* getDataPtr() { return &data; }
|
||||||
|
|
||||||
|
// Traversal helpers
|
||||||
|
inline U32 getDepth() const
|
||||||
|
{
|
||||||
|
U32 depth = 0;
|
||||||
|
TreeNode<T>* current = parent;
|
||||||
|
while (current)
|
||||||
|
{
|
||||||
|
depth++;
|
||||||
|
current = current->parent;
|
||||||
|
}
|
||||||
|
return depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline TreeNode<T>* getRoot()
|
||||||
|
{
|
||||||
|
TreeNode<T>* current = this;
|
||||||
|
while (current->parent)
|
||||||
|
current = current->parent;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const TreeNode<T>* getRoot() const
|
||||||
|
{
|
||||||
|
const TreeNode<T>* current = this;
|
||||||
|
while (current->parent)
|
||||||
|
current = current->parent;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TreeObject : public SimObject {
|
class TreeObject : public SimObject {
|
||||||
|
|
@ -213,7 +367,7 @@ public:
|
||||||
bool toParent(S32 key, S32 newParentKey);
|
bool toParent(S32 key, S32 newParentKey);
|
||||||
|
|
||||||
Vector<S32> getChildren(S32 key);
|
Vector<S32> getChildren(S32 key);
|
||||||
S32 getNumChildren(S32 key) {return getChildren(key).size();};
|
S32 getNumChildren(S32 key) { return getChildren(key).size(); };
|
||||||
|
|
||||||
Vector<S32> getSiblings(S32 key);
|
Vector<S32> getSiblings(S32 key);
|
||||||
S32 getNumSiblings(S32 key) { return getSiblings(key).size(); };
|
S32 getNumSiblings(S32 key) { return getSiblings(key).size(); };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue