ULRE/inc/hgl/component/Component.h

148 lines
4.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include<hgl/type/DataType.h>
#include<hgl/type/SortedSet.h>
#include<hgl/type/ArrayList.h>
/**
* Component/Data/Manager 体系设计简要说明
*
* 本体系参考AMD FidelityFX但并不完全一致。
*
* AMD FidelityFX中Component存放于Entity下而我方中与其类似的定义为SceneNode。
* 不管是Entity还是SceneNode它们都提供空间变换以及子节点、Component的管理。
* 而AMD FidelityFX中的Scene类似于我方的Scene用于储存一个场景世界的根节点及其它世界唯一数据。
*
* ComponentData是每个Component的数据用于向Component或是其它模块提供数据。
* ComponentManager是Component的管理器用于管理Component的创建、销毁、更新等。
*
* 需要注意的是同AMD FidelityFX一样大部分ComponentManager与Scene基本无关。
* 因为同样的数据可能出现在多个World之中。
* 仅有那些与Scene密切相关的Component它对应的Manager才会出现在Scene中比如CameraManager/LightManager。
* 而如StaticMeshComponent之类的纯资源型就会是独立存在的。
*
* Component是组件的基类所有组件都从这里派生。
*
* SceneComponent是场景组件基类只要是放在场景中的都从它派生
*
* PrimitiveComponent是图元组件的基类所有图元组件都从这里派生。
* 它再度派生出的任何Component都必须是一个有3D空间的几何图元。
* 引擎中的空间、物理、等都由PrimitiveComponent提供数据进行计算。
* RenderComponent是可渲染组件的基类所有可渲染组件都从这里派生。
*
* StaticMeshComponent是静态网格组件它是一个具体的RenderComponent实现。
*
*/
#define COMPONENT_NAMESPACE hgl::graph
#define COMPONENT_NAMESPACE_BEGIN namespace COMPONENT_NAMESPACE {
#define COMPONENT_NAMESPACE_END }
COMPONENT_NAMESPACE_BEGIN
class ComponentManager;
class SceneNode;
struct ComponentData
{
public:
ComponentData()=default;
virtual ~ComponentData()=default;
};
/**
* 基础组件<br>
* 是一切组件的基类
*/
class Component
{
SceneNode * OwnerNode;
ComponentManager * Manager;
ComponentData * Data;
public:
Component()=delete;
Component(ComponentData *,ComponentManager *);
virtual ~Component();
virtual const size_t GetHashCode()const=0;
public:
SceneNode * GetOwnerNode()const{return OwnerNode;}
ComponentManager * GetManager ()const{return Manager;}
ComponentData * GetData ()const{return Data;}
public:
//virtual void Update(const double delta_time)=0;
public: //事件
virtual void OnAttach(SceneNode *node){if(node)OwnerNode=node;} ///<附加到节点事件
virtual void OnDetach(SceneNode *node){OwnerNode=nullptr;} ///<从节点分离事件
virtual void OnFocusLost(){} ///<焦点丢失事件
virtual void OnFocusGained(){} ///<焦点获得事件
};//class Component
using ComponentSet=SortedSet<Component *>;
using ComponentList=ArrayList<Component *>;
class ComponentManager
{
ComponentSet component_set;
protected:
friend class Component; //Component可以直接访问ComponentManager的成员
virtual void AttachComponent(Component *c){if(!c)return;component_set.Add(c);}
virtual void DetachComponent(Component *c){if(!c)return;component_set.Delete(c);}
public:
virtual const size_t GetComponentHashCode()const=0;
virtual const size_t GetHashCode()const=0;
virtual ~ComponentManager()=default;
public:
virtual Component * CreateComponent(ComponentData *)=0;
int GetComponentCount()const{return component_set.GetCount();}
ComponentSet & GetComponents(){return component_set;}
int GetComponents(ArrayList<Component *> &comp_list,SceneNode *);
virtual void UpdateComponents(const double delta_time);
public: //事件
virtual void OnFocusLost(){} ///<焦点丢失事件
virtual void OnFocusGained(){} ///<焦点获得事件
};//class ComponentManager
bool RegistryComponentManager(ComponentManager *);
ComponentManager *GetComponentManager(const size_t hash_code);
template<typename T> inline T *GetComponentManager(bool create_default=true)
{
T *cm=(T *)GetComponentManager(T::StaticHashCode());
if(!cm&&create_default)
{
cm=new T;
RegistryComponentManager(cm);
}
return cm;
}
COMPONENT_NAMESPACE_END