From cfda1fceb2b967d1b758c6dcc54bee15c2910126 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Sun, 15 Jun 2025 00:49:23 +0800 Subject: [PATCH] =?UTF-8?q?ComponentManager=E5=A2=9E=E5=8A=A0=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E9=87=8A=E6=94=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Basic/draw_triangle_use_UBO.cpp | 24 +---------------- inc/hgl/component/Component.h | 24 ++++++++++++++--- inc/hgl/graph/SceneNode.h | 6 ++--- inc/hgl/graph/VKMaterial.h | 7 +++-- inc/hgl/graph/VKPhysicalDevice.h | 1 - inc/hgl/graph/VKShaderModule.h | 5 +--- src/SceneGraph/Vulkan/VKPipelineLayoutData.h | 4 +-- src/SceneGraph/component/Component.cpp | 12 ++++++++- src/SceneGraph/component/ComponentManager.cpp | 27 ++++++++++++++----- src/SceneGraph/scene/SceneNode.cpp | 8 ++++++ 10 files changed, 70 insertions(+), 48 deletions(-) diff --git a/example/Basic/draw_triangle_use_UBO.cpp b/example/Basic/draw_triangle_use_UBO.cpp index d51113cc..a38fa654 100644 --- a/example/Basic/draw_triangle_use_UBO.cpp +++ b/example/Basic/draw_triangle_use_UBO.cpp @@ -42,8 +42,6 @@ private: Pipeline * pipeline =nullptr; - StaticMeshComponent *sm_component=nullptr; - private: bool InitMaterial() @@ -89,33 +87,16 @@ private: {VAN::Color, COLOR_DATA_FORMAT, color_data} }); - return(mesh_triangle); - } - - bool InitScene() - { if(!mesh_triangle) return(false); - SceneNode *scene_root=GetSceneRoot(); ///<取得场景根节点 - - sm_component=CreateComponent(scene_root,mesh_triangle); //创建一个静态网格组件 - - if(!sm_component) - return(false); - - return(true); + return CreateComponent(GetSceneRoot(),mesh_triangle); //创建一个静态网格组件 } public: using WorkObject::WorkObject; - ~TestApp() - { - SAFE_CLEAR(sm_component); - } - bool Init() override { if(!InitMaterial()) @@ -124,9 +105,6 @@ public: if(!InitVBO()) return(false); - if(!InitScene()) - return(false); - return(true); } };//class TestApp:public WorkObject diff --git a/inc/hgl/component/Component.h b/inc/hgl/component/Component.h index 8102cbcf..52c145eb 100644 --- a/inc/hgl/component/Component.h +++ b/inc/hgl/component/Component.h @@ -58,10 +58,24 @@ public: */ class Component { + static uint unique_id_count; + + uint unique_id; + SceneNode * OwnerNode; ComponentManager * Manager; ComponentData * Data; +protected: + + friend class ComponentManager; + + virtual void OnDetachManager(ComponentManager *cm) + { + if(cm==Manager) + Manager=nullptr; + } + public: Component()=delete; @@ -72,6 +86,8 @@ public: public: + uint GetUniqueID ()const{return unique_id;} + SceneNode * GetOwnerNode()const{return OwnerNode;} ComponentManager * GetManager ()const{return Manager;} ComponentData * GetData ()const{return Data;} @@ -83,7 +99,7 @@ public: public: //事件 virtual void OnAttach(SceneNode *node){if(node)OwnerNode=node;} ///<附加到节点事件 - virtual void OnDetach(SceneNode *node){OwnerNode=nullptr;} ///<从节点分离事件 + virtual void OnDetach(SceneNode *){OwnerNode=nullptr;} ///<从节点分离事件 virtual void OnFocusLost(){} ///<焦点丢失事件 virtual void OnFocusGained(){} ///<焦点获得事件 @@ -108,17 +124,17 @@ public: virtual const size_t GetComponentHashCode()const=0; virtual const size_t GetHashCode()const=0; - virtual ~ComponentManager()=default; + virtual ~ComponentManager(); public: virtual Component * CreateComponent(ComponentData *)=0; - int GetComponentCount()const{return component_set.GetCount();} + const size_t GetComponentCount()const{return component_set.GetCount();} ComponentSet & GetComponents(){return component_set;} - int GetComponents(ArrayList &comp_list,SceneNode *); + int GetComponents(ComponentList &comp_list,SceneNode *); virtual void UpdateComponents(const double delta_time); diff --git a/inc/hgl/graph/SceneNode.h b/inc/hgl/graph/SceneNode.h index ac4d5881..ca8a8fa2 100644 --- a/inc/hgl/graph/SceneNode.h +++ b/inc/hgl/graph/SceneNode.h @@ -57,7 +57,7 @@ namespace hgl::graph public: - virtual ~SceneNode()=default; + virtual ~SceneNode(); void Clear() override { @@ -106,8 +106,8 @@ namespace hgl::graph public: //组件相关方法 - bool ComponentIsEmpty ()const{return component_set.GetCount()==0;} ///<是否没有组件 - virtual int GetComponentCount ()const{return component_set.GetCount();} ///<取得组件数量 + bool ComponentIsEmpty ()const{return component_set.IsEmpty();} ///<是否没有组件 + virtual const int64 GetComponentCount ()const{return component_set.GetCount();} ///<取得组件数量 virtual bool AttachComponent (Component *comp) ///<添加一个组件 { if(!comp)return(false); diff --git a/inc/hgl/graph/VKMaterial.h b/inc/hgl/graph/VKMaterial.h index b78e1ba9..e7fc9ca5 100644 --- a/inc/hgl/graph/VKMaterial.h +++ b/inc/hgl/graph/VKMaterial.h @@ -1,8 +1,8 @@ -#ifndef HGL_GRAPH_VULKAN_MATERIAL_INCLUDE -#define HGL_GRAPH_VULKAN_MATERIAL_INCLUDE +#pragma once #include #include +#include #include #include #include @@ -106,6 +106,5 @@ public: MaterialInstance *CreateMI(const VILConfig *vil_cfg=nullptr); };//class Material -using MaterialSets=SortedSet; +using MaterialSet=SortedSet; VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_MATERIAL_INCLUDE diff --git a/inc/hgl/graph/VKPhysicalDevice.h b/inc/hgl/graph/VKPhysicalDevice.h index e3ffd879..d72038f2 100644 --- a/inc/hgl/graph/VKPhysicalDevice.h +++ b/inc/hgl/graph/VKPhysicalDevice.h @@ -2,7 +2,6 @@ #include #include -#include VK_NAMESPACE_BEGIN class VulkanPhyDevice diff --git a/inc/hgl/graph/VKShaderModule.h b/inc/hgl/graph/VKShaderModule.h index 40a50eff..56b2d377 100644 --- a/inc/hgl/graph/VKShaderModule.h +++ b/inc/hgl/graph/VKShaderModule.h @@ -1,9 +1,7 @@ -#ifndef HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE -#define HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE +#pragma once #include #include -#include VK_NAMESPACE_BEGIN @@ -46,4 +44,3 @@ public: operator VkShaderModule ()const{return stage_create_info->module;} };//class ShaderModule VK_NAMESPACE_END -#endif//HGL_GRAPH_VULKAN_SHADER_MODULE_INCLUDE diff --git a/src/SceneGraph/Vulkan/VKPipelineLayoutData.h b/src/SceneGraph/Vulkan/VKPipelineLayoutData.h index efecdd98..6f70216b 100644 --- a/src/SceneGraph/Vulkan/VKPipelineLayoutData.h +++ b/src/SceneGraph/Vulkan/VKPipelineLayoutData.h @@ -3,7 +3,7 @@ #include #include #include -#include + VK_NAMESPACE_BEGIN struct PipelineLayoutData { @@ -21,4 +21,4 @@ public: ~PipelineLayoutData(); };//class PipelineLayoutData -VK_NAMESPACE_END \ No newline at end of file +VK_NAMESPACE_END diff --git a/src/SceneGraph/component/Component.cpp b/src/SceneGraph/component/Component.cpp index c7106cc3..1627dd0d 100644 --- a/src/SceneGraph/component/Component.cpp +++ b/src/SceneGraph/component/Component.cpp @@ -1,26 +1,36 @@ #include #include +#include namespace hgl::graph { + uint Component::unique_id_count=0; + Component::Component(ComponentData *cd,ComponentManager *cm) { + unique_id=++unique_id_count; + OwnerNode=nullptr; Data=cd; Manager=cm; Manager->AttachComponent(this); + + LOG_INFO(AnsiString("Component::Component ")+AnsiString::numberOf(unique_id)+AnsiString(" ")+ToHexString(this)); } Component::~Component() { + LOG_INFO(AnsiString("Component::~Component ")+AnsiString::numberOf(unique_id)+AnsiString(" ")+ToHexString(this)); + if(OwnerNode) { OwnerNode->DetachComponent(this); OwnerNode=nullptr; } - Manager->DetachComponent(this); + if(Manager) + Manager->DetachComponent(this); SAFE_CLEAR(Data); } diff --git a/src/SceneGraph/component/ComponentManager.cpp b/src/SceneGraph/component/ComponentManager.cpp index e97b57a3..a529fdeb 100644 --- a/src/SceneGraph/component/ComponentManager.cpp +++ b/src/SceneGraph/component/ComponentManager.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include namespace hgl::graph { @@ -59,20 +61,33 @@ namespace hgl::graph return component_manager_map->at(hash_code); } - int ComponentManager::GetComponents(ArrayList &comp_list,SceneNode *node) + ComponentManager::~ComponentManager() + { + for(auto *c:component_set) + { + c->OnDetach(nullptr); + + //Component::~Component()函数会再次调用ComponentManager->DetachComponent,其中会执行component_set的删除,整个流程就会出现问题。 + //所以这里先OnDetachManager掉Component中的Manager属性,然后再执行删除 + c->OnDetachManager(this); + + LOG_INFO(AnsiString("~ComponentManager delete ")+AnsiString::numberOf(c->GetUniqueID())); + delete c; + } + } + + int ComponentManager::GetComponents(ComponentList &comp_list,SceneNode *node) { if(!node)return(-1); if(comp_list.IsEmpty())return(-2); if(!component_manager_map)return(-3); - Component **cc=component_set.GetData(); - int result=0; - for(int i=0;iGetOwnerNode()==node) + for(auto cc:component_set) + if(cc->GetOwnerNode()==node) { - comp_list.Add(cc[i]); + comp_list.Add(cc); ++result; } diff --git a/src/SceneGraph/scene/SceneNode.cpp b/src/SceneGraph/scene/SceneNode.cpp index 1c3cbc98..e4ef267d 100644 --- a/src/SceneGraph/scene/SceneNode.cpp +++ b/src/SceneGraph/scene/SceneNode.cpp @@ -126,4 +126,12 @@ namespace hgl::graph return(false); } + + SceneNode::~SceneNode() + { + for(Component *c:component_set) + { + c->OnDetach(this); + } + } }//namespace hgl::graph