重新独立TreeBaseNode.h/.cpp
This commit is contained in:
parent
ebae11e0c3
commit
e1a8241d16
@ -61,13 +61,13 @@ namespace hgl
|
|||||||
|
|
||||||
};//class Node
|
};//class Node
|
||||||
|
|
||||||
template<typename T> class DataNode:public Node
|
template<typename T,typename SuperNode=Node> class DataNode:public SuperNode
|
||||||
{
|
{
|
||||||
T node_data;
|
T node_data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Node::Node;
|
using SuperNode::SuperNode;
|
||||||
virtual ~DataNode()override=default;
|
virtual ~DataNode()override=default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
51
inc/hgl/type/TreeBaseNode.h
Normal file
51
inc/hgl/type/TreeBaseNode.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<hgl/type/Node.h>
|
||||||
|
#include<tsl/robin_map.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
class TreeBaseNode:public Node
|
||||||
|
{
|
||||||
|
TreeBaseNode *parent_node; ///<父节点指针
|
||||||
|
tsl::robin_map<size_t,TreeBaseNode *> child_map; ///<子节点集合
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void DetachAll();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TreeBaseNode(NodeManager *nm,const size_t uid):Node(nm,uid)
|
||||||
|
{
|
||||||
|
parent_node=nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~TreeBaseNode()
|
||||||
|
{
|
||||||
|
DetachAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void OnAttachParentNode(TreeBaseNode *pn){parent_node=pn;} ///<被附加到父节点时调用(参见AttachChild)
|
||||||
|
virtual void OnDetachParentNode(){parent_node=nullptr;} ///<被从父节点中移除时调用(参见DetachChild)
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const TreeBaseNode * GetParent()const{return parent_node;} ///<获取父节点指针
|
||||||
|
|
||||||
|
const size_t GetChildCount()const{return child_map.size();} ///<获取子节点数量
|
||||||
|
|
||||||
|
const bool Contains(const size_t id)const{return child_map.contains(id);} ///<根据ID判断是否包含子节点
|
||||||
|
const bool Contains(const TreeBaseNode *node)const;
|
||||||
|
|
||||||
|
const bool AttachChild(TreeBaseNode *node);
|
||||||
|
void DetachChild(TreeBaseNode *node);
|
||||||
|
void DetachAllChild();
|
||||||
|
|
||||||
|
void DestoryAllChild();
|
||||||
|
|
||||||
|
void DetachParent();
|
||||||
|
};//class TreeBaseNode
|
||||||
|
}//namespace hgl
|
@ -1,97 +1,60 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include<hgl/type/NodeManager.h>
|
#include<hgl/type/NodeManager.h>
|
||||||
|
#include<hgl/type/TreeBaseNode.h>
|
||||||
|
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
template<typename T> class TreeNode:public DataNode<T>
|
template<typename T> class TreeNode:public DataNode<T,TreeBaseNode>
|
||||||
{
|
{
|
||||||
TreeNode<T> *parent_node; ///<父节点指针
|
|
||||||
tsl::robin_map<size_t,TreeNode<T> *> child_map; ///<子节点集合
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
using SuperNode=DataNode<T,TreeBaseNode>;
|
||||||
|
|
||||||
friend class NodeManager;
|
friend class NodeManager;
|
||||||
|
|
||||||
template<typename T> friend class DataNodeManager;
|
template<typename T> friend class DataNodeManager;
|
||||||
|
|
||||||
TreeNode(NodeManager *nm,const size_t uid):DataNode<T>(nm,uid)
|
TreeNode(NodeManager *nm,const size_t uid):SuperNode(nm,uid){}
|
||||||
{
|
|
||||||
parent_node=nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~TreeNode()
|
virtual ~TreeNode()
|
||||||
{
|
{
|
||||||
if(GetChildCount())
|
//这里必须处理DetachChild问题,不然各种OnDetach虚拟函数回调就失效了
|
||||||
DestoryAllChild();
|
TreeBaseNode::DetachAll();
|
||||||
|
|
||||||
if(parent_node)
|
|
||||||
parent_node->DetachChild(this); //从父节点中移除
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T *operator ->() {return DataNode<T>::get_ptr();}
|
T *operator ->() {return SuperNode::get_ptr();}
|
||||||
const T *operator ->()const {return DataNode<T>::get_ptr();}
|
const T *operator ->()const {return SuperNode::get_ptr();}
|
||||||
|
|
||||||
public: //子节点相关
|
TreeNode *GetParent()
|
||||||
|
{
|
||||||
|
return (TreeNode *)SuperNode::GetParent();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnAttachParent(TreeNode<T> *pn){parent_node=pn;} ///<被附加到父节点时调用(参见AttachChild)
|
public:
|
||||||
virtual void OnDetachParent(TreeNode<T> *pn){parent_node=nullptr;} ///<被从父节点中移除时调用(参见DetachChild)
|
|
||||||
const TreeNode<T> * GetParent()const{return parent_node;} ///<获取父节点指针
|
|
||||||
|
|
||||||
const size_t GetChildCount()const{return child_map.size();} ///<获取子节点数量
|
virtual void OnAttachParent(TreeNode *){} ///<被附加到父节点时调用
|
||||||
|
virtual void OnDetachParent(){} ///<被从父节点中移除时调用
|
||||||
|
|
||||||
const bool Contains(const size_t id)const{return child_map.contains(id);} ///<根据ID判断是否包含子节点
|
virtual void OnAttachParentNode(TreeBaseNode *pn)override ///<被附加到父节点时调用(参见AttachChild)
|
||||||
const bool Contains(const TreeNode<T> *node)const
|
{
|
||||||
{
|
SuperNode::OnAttachParentNode(pn);
|
||||||
if(!node)return(false);
|
OnAttachParent((TreeNode *)pn);
|
||||||
if(node->Node::GetManager()!=Node::GetManager())return(false);
|
}
|
||||||
|
|
||||||
return Contains(node->GetUniqueID());
|
virtual void OnDetachParentNode()override ///<被从父节点中移除时调用(参见DetachChild)
|
||||||
}
|
{
|
||||||
|
OnDetachParent();
|
||||||
|
SuperNode::OnDetachParentNode();
|
||||||
|
}
|
||||||
|
|
||||||
const bool AttachChild(TreeNode<T> *node)
|
virtual void OnDestory()override
|
||||||
{
|
{
|
||||||
if(!node)return(false);
|
TreeBaseNode::DetachParent();
|
||||||
if(Contains(node))return(false);
|
TreeBaseNode::DetachAllChild();
|
||||||
|
SuperNode::OnDestory();
|
||||||
child_map.emplace(node->GetUniqueID(),node);
|
}
|
||||||
node->OnAttachParent(this);
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DetachChild(TreeNode<T> *node)
|
|
||||||
{
|
|
||||||
if(!node)return;
|
|
||||||
|
|
||||||
if(node->Node::GetManager()!=Node::GetManager())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const size_t child_id=node->GetUniqueID();
|
|
||||||
|
|
||||||
if(child_map.contains(child_id))
|
|
||||||
child_map.erase(child_id);
|
|
||||||
|
|
||||||
node->OnDetachParent(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestoryAllChild()
|
|
||||||
{
|
|
||||||
for(auto &it:child_map)
|
|
||||||
{
|
|
||||||
TreeNode<T> *node=it.second;
|
|
||||||
|
|
||||||
if(!node)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
child_map.erase(node->GetUniqueID()); //从子节点集合中移除
|
|
||||||
node->OnDetachParent(this); //从父节点中移除
|
|
||||||
|
|
||||||
node->Destory(); //销毁子节点
|
|
||||||
}
|
|
||||||
|
|
||||||
child_map.clear();
|
|
||||||
}
|
|
||||||
};//class TreeNode
|
};//class TreeNode
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
|
@ -44,9 +44,11 @@ SOURCE_GROUP("DataType\\DataChain" FILES ${TYPE_DATA_CHAIN_SOURCE})
|
|||||||
|
|
||||||
SET(TREE_NODE_FILES ${TYPE_INCLUDE_PATH}/Node.h
|
SET(TREE_NODE_FILES ${TYPE_INCLUDE_PATH}/Node.h
|
||||||
${TYPE_INCLUDE_PATH}/NodeManager.h
|
${TYPE_INCLUDE_PATH}/NodeManager.h
|
||||||
|
${TYPE_INCLUDE_PATH}/TreeBaseNode.h
|
||||||
${TYPE_INCLUDE_PATH}/TreeNode.h
|
${TYPE_INCLUDE_PATH}/TreeNode.h
|
||||||
Type/Node.cpp
|
Type/Node.cpp
|
||||||
Type/NodeManager.cpp)
|
Type/NodeManager.cpp
|
||||||
|
Type/TreeBaseNode.cpp)
|
||||||
|
|
||||||
SOURCE_GROUP("DataType\\Node" FILES ${TREE_NODE_FILES})
|
SOURCE_GROUP("DataType\\Node" FILES ${TREE_NODE_FILES})
|
||||||
|
|
||||||
|
89
src/Type/TreeBaseNode.cpp
Normal file
89
src/Type/TreeBaseNode.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include<hgl/type/TreeBaseNode.h>
|
||||||
|
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
void TreeBaseNode::DetachAll()
|
||||||
|
{
|
||||||
|
if(GetChildCount())
|
||||||
|
DestoryAllChild();
|
||||||
|
|
||||||
|
if(parent_node)
|
||||||
|
parent_node->DetachChild(this); //从父节点中移除
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool TreeBaseNode::Contains(const TreeBaseNode *node)const
|
||||||
|
{
|
||||||
|
if(!node)return(false);
|
||||||
|
if(node->GetManager()!=GetManager())return(false);
|
||||||
|
if(node->GetParent()!=this)return(false);
|
||||||
|
return Contains(node->GetUniqueID());
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool TreeBaseNode::AttachChild(TreeBaseNode *node)
|
||||||
|
{
|
||||||
|
if(!node)return(false);
|
||||||
|
if(Contains(node))return(false);
|
||||||
|
|
||||||
|
child_map.emplace(node->GetUniqueID(),node);
|
||||||
|
node->OnAttachParentNode(this);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeBaseNode::DetachChild(TreeBaseNode *node)
|
||||||
|
{
|
||||||
|
if(!node)return;
|
||||||
|
|
||||||
|
if(node->Node::GetManager()!=Node::GetManager())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const size_t child_id=node->GetUniqueID();
|
||||||
|
|
||||||
|
if(!child_map.contains(child_id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
child_map.erase(child_id);
|
||||||
|
node->OnDetachParentNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeBaseNode::DetachAllChild()
|
||||||
|
{
|
||||||
|
for(auto &it:child_map)
|
||||||
|
{
|
||||||
|
TreeBaseNode *node=it.second;
|
||||||
|
|
||||||
|
if(!node)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
node->OnDetachParentNode(); //从父节点中移除
|
||||||
|
}
|
||||||
|
|
||||||
|
child_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeBaseNode::DestoryAllChild()
|
||||||
|
{
|
||||||
|
for(auto &it:child_map)
|
||||||
|
{
|
||||||
|
TreeBaseNode *node=it.second;
|
||||||
|
|
||||||
|
if(!node)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
child_map.erase(node->GetUniqueID()); //从子节点集合中移除
|
||||||
|
node->OnDetachParentNode(); //从父节点中移除
|
||||||
|
|
||||||
|
node->Destory(); //销毁子节点
|
||||||
|
}
|
||||||
|
|
||||||
|
child_map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TreeBaseNode::DetachParent()
|
||||||
|
{
|
||||||
|
if(!parent_node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
parent_node->DetachChild(this); //从父节点中移除
|
||||||
|
parent_node=nullptr;
|
||||||
|
}
|
||||||
|
}//namespace hgl
|
Loading…
x
Reference in New Issue
Block a user