From c50f9eac72dc7a728d3afbd2dc330d06fdc42752 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sun, 27 Apr 2025 00:50:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=85=A8=E6=96=B0=E7=9A=84Tr?= =?UTF-8?q?eeNode=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/hgl/type/TreeNode.h | 204 +++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 9 ++ src/Type/TreeNode.cpp | 93 ++++++++++++++++ src/Type/TreeNodeManager.cpp | 92 ++++++++++++++++ 4 files changed, 398 insertions(+) create mode 100644 inc/hgl/type/TreeNode.h create mode 100644 src/Type/TreeNode.cpp create mode 100644 src/Type/TreeNodeManager.cpp diff --git a/inc/hgl/type/TreeNode.h b/inc/hgl/type/TreeNode.h new file mode 100644 index 0000000..5af1493 --- /dev/null +++ b/inc/hgl/type/TreeNode.h @@ -0,0 +1,204 @@ +#pragma once + +#include +#include +#include +#include + +namespace hgl +{ + class TreeBaseNodeManager; + + template class TreeNodeManager; + + enum class TreeNodeLifePhase + { + None=0, ///<未知 + Work, ///<工作中(一般的使用状态) + Recycled, ///<已回收(走过了回收流程,但并未释放资源) + WaitDestory, ///<等待销毁(已经进入真正的销毁流程) + Destory, ///<销毁(已经被销毁,不存这种对像,只在根据ID获取状态时可以得到) + + ENUM_CLASS_RANGE(None,Destory) + }; + + class TreeBaseNode + { + TreeBaseNodeManager *manager; ///<管理器指针 + size_t unique_id; ///<唯一ID + + TreeBaseNode *parent_node; ///<父节点指针 + tsl::robin_map child_map; ///<子节点集合 + + TreeNodeLifePhase life_phase; ///<生命周期状态 + + public: + + TreeBaseNodeManager *GetManager() {return manager;} ///<获取管理器指针 + const TreeBaseNodeManager *GetManager()const{return manager;} ///<获取管理器指针 + + const size_t GetManagerID ()const; ///<获取管理器ID + const size_t GetUniqueID ()const{return unique_id;} ///<获取对象唯一ID + + const TreeNodeLifePhase GetLifePhase()const{return life_phase;} ///<获取生命周期状态 + + const bool IsWork ()const{return life_phase==TreeNodeLifePhase::Work;} ///<可以工作 + const bool IsRecycled ()const{return life_phase==TreeNodeLifePhase::Recycled;} ///<是否已经回收 + const bool IsWaitDestory()const{return life_phase==TreeNodeLifePhase::WaitDestory;} ///<是否已经进入等待销毁状态 + + private: + + friend class TreeBaseNodeManager; + template friend class TreeNode; + template friend class TreeNodeManager; + + TreeBaseNode(TreeBaseNodeManager *nm,const size_t uid); + virtual ~TreeBaseNode(); + + protected: + + virtual void MarkWaitDestory(){life_phase=TreeNodeLifePhase::WaitDestory;} ///<标记为等待销毁状态 + + virtual void OnDestory(); ///<最后的真实销毁调用操作(默认为delete this) + + public: + + virtual void Destory(); ///<销毁节点(标记为等待销毁状态) + + 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;} ///<获取父节点指针 + + 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 DestoryAllChild(); + };//class TreeBaseNode + + class TreeBaseNodeManager + { + static const size_t AcquireManagerID(){static size_t id_count=0;return ++id_count;} + + private: + + size_t manager_serial; + size_t node_serial; + + private: + + tsl::robin_map node_map; ///<节点集合 + + tsl::robin_set wait_destory_node_set; ///<等待销毁的节点集合 + + tsl::robin_set destored_node_set; ///<已经销毁的节点集合 + + protected: + + friend class TreeBaseNode; + + const size_t AcquireNodeID(){return ++node_serial;} + + virtual TreeBaseNode * OnCreateNode(const size_t node_id)=0; ///<创建节点时调用 + virtual void OnDestoryNode(TreeBaseNode *node)=0; ///<销毁节点时调用 + + void OnNodeDirectDestory(TreeBaseNode *node); ///<直接销毁,这种情况只在对象被直接delete的情况下,一般不需要 + + public: + + const size_t GetMangaerID()const{return manager_serial;} + + public: + + TreeBaseNodeManager() + { + manager_serial=AcquireManagerID(); + node_serial=0; + } + + virtual ~TreeBaseNodeManager(){} + + virtual void ForceClear(); + + TreeBaseNode * CreateNode(); + + const bool ContainsNode(TreeBaseNode *tn)const; + + bool DestoryNode(TreeBaseNode *node); + + TreeBaseNode * GetNode(const size_t node_id); + + virtual void Update(){} + };//class TreeBaseNodeManager + + template class TreeNode:public TreeBaseNode + { + T node_data; + + private: + + friend class TreeNodeManager; ///<树节点管理器 + + using TreeBaseNode::TreeBaseNode; + + public: + + virtual ~TreeNode()override{} + + public: + + operator T &() {return node_data;} + operator const T &()const {return node_data;} + + T &operator *() {return node_data;} + const T &operator *()const{return node_data;} + + T &get() {return node_data;} + const T &get()const {return node_data;} + + T *operator ->() {return &node_data;} + const T *operator ->()const {return &node_data;} + + T &operator = (const T &data) + { + node_data=data; + return node_data; + } + };//class TreeNode + + template class TreeNodeManager:public TreeBaseNodeManager + { + public: + + using NodeType=TreeNode; ///<节点类型 + + protected: + + TreeBaseNode *OnCreateNode(const size_t node_id) override + { + return(new NodeType(this,node_id)); + } + + void OnDestoryNode(TreeBaseNode *node)override + { + if(!node)return; + + node->OnDestory(); + } + + public: + + using TreeBaseNodeManager::TreeBaseNodeManager; + virtual ~TreeNodeManager() + { + ForceClear(); + } + + NodeType *Create(){return (NodeType *)CreateNode();} + };//class TreeNodeManager +}//namespace hgl diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d618d29..bfff8f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,12 @@ SET(TYPE_DATA_CHAIN_SOURCE ${TYPE_INCLUDE_PATH}/DataChain.h SOURCE_GROUP("DataType\\DataChain" FILES ${TYPE_DATA_CHAIN_SOURCE}) +SET(TREE_NODE_FILES ${TYPE_INCLUDE_PATH}/TreeNode.h + Type/TreeNode.cpp + Type/TreeNodeManager.cpp) + +SOURCE_GROUP("DataType\\Tree" FILES ${TREE_NODE_FILES}) + SET(ACTIVE_MANAGER_FILES ${TYPE_INCLUDE_PATH}/ActiveIDManager.h ${TYPE_INCLUDE_PATH}/ActiveMemoryBlockManager.h ${TYPE_INCLUDE_PATH}/ActiveDataManager.h @@ -52,6 +58,7 @@ file(GLOB TYPE_TEMPLATE_HEADER ${TYPE_INCLUDE_PATH}/*.h) SOURCE_GROUP("DataType\\ActiveManager" FILES ${ACTIVE_MANAGER_FILES}) + SET(SYSTEM_INFO_SOURCE ${CORE_PLATFORM_INCLUDE_PATH}/SystemInfo.h SystemInfo.cpp) @@ -261,6 +268,8 @@ add_cm_library(CMCore "CM" ${CORE_PLATFORM_HEADER_FILES} ${BITS_ARRAY_FILES} + ${TREE_NODE_FILES} + ${COLOR_HEADER_FILES} ${COLOR_SOURCE_FILES} diff --git a/src/Type/TreeNode.cpp b/src/Type/TreeNode.cpp new file mode 100644 index 0000000..b346e92 --- /dev/null +++ b/src/Type/TreeNode.cpp @@ -0,0 +1,93 @@ +#include + +namespace hgl +{ + TreeBaseNode::TreeBaseNode(TreeBaseNodeManager *nm,const size_t uid) + { + manager=nm; + unique_id=uid; + + life_phase=TreeNodeLifePhase::None; + + parent_node=nullptr; + } + + TreeBaseNode::~TreeBaseNode() + { + if(GetChildCount()) + DestoryAllChild(); + + if(parent_node) + parent_node->DetachChild(this); //从父节点中移除 + + if(life_phaseOnNodeDirectDestory(this); //直接销毁 + } + + const size_t TreeBaseNode::GetManagerID()const + { + return manager->GetMangaerID(); + } + + void TreeBaseNode::Destory() + { + manager->DestoryNode(this); + } + + void TreeBaseNode::OnDestory() + { + life_phase=TreeNodeLifePhase::Destory; //设置为销毁状态 + delete 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 diff --git a/src/Type/TreeNodeManager.cpp b/src/Type/TreeNodeManager.cpp new file mode 100644 index 0000000..3145538 --- /dev/null +++ b/src/Type/TreeNodeManager.cpp @@ -0,0 +1,92 @@ +#include + +namespace hgl +{ + void TreeBaseNodeManager::OnNodeDirectDestory(TreeBaseNode *node) ///<直接销毁,这种情况只在对象被直接delete的情况下,一般不需要 + { + if(!node)return; + + if(wait_destory_node_set.contains(node)) + wait_destory_node_set.erase(node); + + if(!destored_node_set.contains(node)) + destored_node_set.emplace(node); + } + + void TreeBaseNodeManager::ForceClear() + { + if(!node_map.empty()) + { + for(auto &it:node_map) + { + it.second->MarkWaitDestory(); + + wait_destory_node_set.insert(it.second); + } + + node_map.clear(); + } + + //正式的销毁可能是需要考虑node顺序的,需要根据依赖进行排序.这里暂时没做。 + + if(!wait_destory_node_set.empty()) + { + for(auto *node:wait_destory_node_set) + OnDestoryNode(node); //销毁节点 + + wait_destory_node_set.clear(); + } + } + + TreeBaseNode *TreeBaseNodeManager::CreateNode() + { + const size_t node_id=AcquireNodeID(); + + TreeBaseNode *node=OnCreateNode(node_id); + + if(!node) + return(nullptr); + + node_map.emplace(node_id,node); + + return(node); + } + + const bool TreeBaseNodeManager::ContainsNode(TreeBaseNode *tn)const + { + if(!tn)return(false); + if(tn->GetManagerID()!=GetMangaerID())return(false); + + if(!node_map.contains(tn->GetUniqueID())) + return(false); + + return(true); + } + + bool TreeBaseNodeManager::DestoryNode(TreeBaseNode *node) + { + if(!node)return(false); + + if(wait_destory_node_set.contains(node)) + return(true); + + if(!ContainsNode(node)) + return(false); + + node->MarkWaitDestory(); + node_map.erase(node->GetUniqueID()); + wait_destory_node_set.insert(node); + + return(true); + } + + TreeBaseNode *TreeBaseNodeManager::GetNode(const size_t node_id) + { + auto iter=node_map.find(node_id); + + if(iter==node_map.end()) + return(nullptr); + + return(iter->second); + } +}//namespace hgl