Compare commits
2 Commits
2f048f7856
...
ebae11e0c3
Author | SHA1 | Date | |
---|---|---|---|
ebae11e0c3 | |||
59dd2332a2 |
@ -60,4 +60,30 @@ namespace hgl
|
||||
virtual void Destory(); ///<销毁节点(标记为等待销毁状态)
|
||||
|
||||
};//class Node
|
||||
|
||||
template<typename T> class DataNode:public Node
|
||||
{
|
||||
T node_data;
|
||||
|
||||
public:
|
||||
|
||||
using Node::Node;
|
||||
virtual ~DataNode()override=default;
|
||||
|
||||
public:
|
||||
|
||||
T & get_data() {return node_data;}
|
||||
const T & get_data()const {return node_data;}
|
||||
|
||||
T * get_ptr () {return &node_data;}
|
||||
const T * get_ptr ()const {return &node_data;}
|
||||
|
||||
operator T & () {return node_data;}
|
||||
operator const T & ()const {return node_data;}
|
||||
|
||||
virtual void set_data(const T &data)
|
||||
{
|
||||
node_data=data;
|
||||
}
|
||||
};//class DataNode
|
||||
}//namespcae hgl
|
||||
|
@ -61,4 +61,37 @@ namespace hgl
|
||||
|
||||
virtual void Update(){}
|
||||
};//class NodeManager
|
||||
|
||||
template<typename T> class DataNodeManager:public NodeManager
|
||||
{
|
||||
protected: //事件
|
||||
|
||||
Node *OnCreateNode(const size_t node_id) override
|
||||
{
|
||||
return(new T(this,node_id));
|
||||
}
|
||||
|
||||
void OnDestoryNode(Node *node)override
|
||||
{
|
||||
if(!node)return;
|
||||
|
||||
node->OnDestory();
|
||||
delete node;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using NodeManager::NodeManager;
|
||||
virtual ~DataNodeManager()
|
||||
{
|
||||
ForceClear();
|
||||
}
|
||||
|
||||
T *Create()
|
||||
{
|
||||
return (T *)CreateNode();
|
||||
//走基类的CreateNode()是为了添加到管理器中
|
||||
//基类会通过虚拟的OnCreateNode()再度回到本类来创建节点
|
||||
}
|
||||
};//class DataNodeManager
|
||||
}//namespace hgl
|
||||
|
@ -4,100 +4,94 @@
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
class TreeBaseNode:public Node
|
||||
template<typename T> class TreeNode:public DataNode<T>
|
||||
{
|
||||
TreeBaseNode *parent_node; ///<父节点指针
|
||||
tsl::robin_map<size_t,TreeBaseNode *> child_map; ///<子节点集合
|
||||
TreeNode<T> *parent_node; ///<父节点指针
|
||||
tsl::robin_map<size_t,TreeNode<T> *> child_map; ///<子节点集合
|
||||
|
||||
private:
|
||||
|
||||
friend class NodeManager;
|
||||
template<typename T> friend class TreeNode;
|
||||
template<typename T> friend class TreeNodeManager;
|
||||
|
||||
TreeBaseNode(NodeManager *nm,const size_t uid);
|
||||
virtual ~TreeBaseNode();
|
||||
template<typename T> friend class DataNodeManager;
|
||||
|
||||
TreeNode(NodeManager *nm,const size_t uid):DataNode<T>(nm,uid)
|
||||
{
|
||||
parent_node=nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual ~TreeNode()
|
||||
{
|
||||
if(GetChildCount())
|
||||
DestoryAllChild();
|
||||
|
||||
if(parent_node)
|
||||
parent_node->DetachChild(this); //从父节点中移除
|
||||
}
|
||||
|
||||
T *operator ->() {return DataNode<T>::get_ptr();}
|
||||
const T *operator ->()const {return DataNode<T>::get_ptr();}
|
||||
|
||||
public: //子节点相关
|
||||
|
||||
virtual void OnAttachParent(TreeBaseNode *pn){parent_node=pn;} ///<被附加到父节点时调用(参见AttachChild)
|
||||
virtual void OnDetachParent(TreeBaseNode *pn){parent_node=nullptr;} ///<被从父节点中移除时调用(参见DetachChild)
|
||||
const TreeBaseNode * GetParent()const{return parent_node;} ///<获取父节点指针
|
||||
virtual void OnAttachParent(TreeNode<T> *pn){parent_node=pn;} ///<被附加到父节点时调用(参见AttachChild)
|
||||
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();} ///<获取子节点数量
|
||||
|
||||
const bool Contains(const size_t id)const{return child_map.contains(id);} ///<根据ID判断是否包含子节点
|
||||
const bool Contains(const TreeBaseNode *node)const;
|
||||
const bool Contains(const TreeNode<T> *node)const
|
||||
{
|
||||
if(!node)return(false);
|
||||
if(node->Node::GetManager()!=Node::GetManager())return(false);
|
||||
|
||||
const bool AttachChild(TreeBaseNode *node);
|
||||
void DetachChild(TreeBaseNode *node);
|
||||
void DestoryAllChild();
|
||||
};//class TreeBaseNode
|
||||
return Contains(node->GetUniqueID());
|
||||
}
|
||||
|
||||
template<typename T> class TreeNode:public TreeBaseNode
|
||||
{
|
||||
T node_data;
|
||||
const bool AttachChild(TreeNode<T> *node)
|
||||
{
|
||||
if(!node)return(false);
|
||||
if(Contains(node))return(false);
|
||||
|
||||
private:
|
||||
child_map.emplace(node->GetUniqueID(),node);
|
||||
node->OnAttachParent(this);
|
||||
return(true);
|
||||
}
|
||||
|
||||
friend class TreeNodeManager<T>; ///<树节点管理器
|
||||
void DetachChild(TreeNode<T> *node)
|
||||
{
|
||||
if(!node)return;
|
||||
|
||||
using TreeBaseNode::TreeBaseNode;
|
||||
if(node->Node::GetManager()!=Node::GetManager())
|
||||
return;
|
||||
|
||||
public:
|
||||
const size_t child_id=node->GetUniqueID();
|
||||
|
||||
virtual ~TreeNode()override=default;
|
||||
if(child_map.contains(child_id))
|
||||
child_map.erase(child_id);
|
||||
|
||||
public:
|
||||
node->OnDetachParent(this);
|
||||
}
|
||||
|
||||
operator T &() {return node_data;}
|
||||
operator const T &()const {return node_data;}
|
||||
void DestoryAllChild()
|
||||
{
|
||||
for(auto &it:child_map)
|
||||
{
|
||||
TreeNode<T> *node=it.second;
|
||||
|
||||
T &operator *() {return node_data;}
|
||||
const T &operator *()const{return node_data;}
|
||||
if(!node)
|
||||
continue;
|
||||
|
||||
T &get() {return node_data;}
|
||||
const T &get()const {return node_data;}
|
||||
child_map.erase(node->GetUniqueID()); //从子节点集合中移除
|
||||
node->OnDetachParent(this); //从父节点中移除
|
||||
|
||||
T *operator ->() {return &node_data;}
|
||||
const T *operator ->()const {return &node_data;}
|
||||
node->Destory(); //销毁子节点
|
||||
}
|
||||
|
||||
T &operator = (const T &data)
|
||||
{
|
||||
node_data=data;
|
||||
return node_data;
|
||||
}
|
||||
child_map.clear();
|
||||
}
|
||||
};//class TreeNode
|
||||
|
||||
template<typename T> class TreeNodeManager:public NodeManager
|
||||
{
|
||||
public:
|
||||
|
||||
using NodeType=TreeNode<T>; ///<节点类型
|
||||
|
||||
protected:
|
||||
|
||||
Node *OnCreateNode(const size_t node_id) override
|
||||
{
|
||||
return(new NodeType(this,node_id));
|
||||
}
|
||||
|
||||
void OnDestoryNode(Node *node)override
|
||||
{
|
||||
if(!node)return;
|
||||
|
||||
node->OnDestory();
|
||||
delete node;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
using NodeManager::NodeManager;
|
||||
virtual ~TreeNodeManager()
|
||||
{
|
||||
ForceClear();
|
||||
}
|
||||
|
||||
NodeType *Create(){return (NodeType *)CreateNode();}
|
||||
};//class TreeNodeManager
|
||||
}//namespace hgl
|
||||
|
@ -46,8 +46,7 @@ SET(TREE_NODE_FILES ${TYPE_INCLUDE_PATH}/Node.h
|
||||
${TYPE_INCLUDE_PATH}/NodeManager.h
|
||||
${TYPE_INCLUDE_PATH}/TreeNode.h
|
||||
Type/Node.cpp
|
||||
Type/NodeManager.cpp
|
||||
Type/TreeNode.cpp)
|
||||
Type/NodeManager.cpp)
|
||||
|
||||
SOURCE_GROUP("DataType\\Node" FILES ${TREE_NODE_FILES})
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
#include<hgl/type/TreeNode.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
TreeBaseNode::TreeBaseNode(NodeManager *nm,const size_t uid):Node(nm,uid)
|
||||
{
|
||||
parent_node=nullptr;
|
||||
}
|
||||
|
||||
TreeBaseNode::~TreeBaseNode()
|
||||
{
|
||||
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);
|
||||
|
||||
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->OnAttachParent(this);
|
||||
return(true);
|
||||
}
|
||||
|
||||
void TreeBaseNode::DetachChild(TreeBaseNode *node)
|
||||
{
|
||||
if(!node)return;
|
||||
|
||||
if(node->GetManager()!=GetManager())
|
||||
return;
|
||||
|
||||
const size_t child_id=node->GetUniqueID();
|
||||
|
||||
if(child_map.contains(child_id))
|
||||
child_map.erase(child_id);
|
||||
|
||||
node->OnDetachParent(this);
|
||||
}
|
||||
|
||||
void TreeBaseNode::DestoryAllChild()
|
||||
{
|
||||
for(auto &it:child_map)
|
||||
{
|
||||
TreeBaseNode *node=it.second;
|
||||
|
||||
if(!node)
|
||||
continue;
|
||||
|
||||
child_map.erase(node->GetUniqueID()); //从子节点集合中移除
|
||||
node->OnDetachParent(this); //从父节点中移除
|
||||
|
||||
node->Destory(); //销毁子节点
|
||||
}
|
||||
|
||||
child_map.clear();
|
||||
}
|
||||
}//namespace hgl
|
Loading…
x
Reference in New Issue
Block a user