Added Object/ObjectAllocator/ObjectManager ....

This commit is contained in:
hyzboy 2024-10-05 22:14:04 +08:00
parent afa80ed4de
commit e16b93400b
11 changed files with 637 additions and 2 deletions

View File

@ -0,0 +1,14 @@
#pragma once
namespace hgl
{
struct SourceCodeLocation
{
const char * file; ///<源文件
const char * func; ///<函数
size_t line; ///<行号
};
#define HGL_SOURCE_CODE_LOCATION __FILE__,__FUNCTION__,__LINE__
}//namespace hgl

View File

@ -1,4 +1,5 @@
#pragma once
#include<hgl/type/TypeInfo.h>
#include<hgl/math/Matrix.h>
#include<hgl/type/ObjectList.h>
#include<hgl/type/VersionData.h>

9
inc/hgl/type/TypeInfo.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include<typeinfo>
namespace hgl
{
template<typename T> inline constexpr const size_t GetTypeHash()noexcept{return typeid(T).hash_code();} ///<取得一个类型的哈希值
template<typename T> inline constexpr const char * GetTypeName()noexcept{return typeid(T).name();} ///<取得一个类型的名称
}//namespace hgl

View File

@ -0,0 +1,34 @@
#pragma once
#include<hgl/type/object/ObjectManager.h>
namespace hgl
{
template<typename T,typename ...ARGS> SafePtr<T> DefaultCreateObject(const char *source_file,const char *source_function,const size_t source_line,ARGS...args)
{
const size_t hc=GetTypeHash<T>();
ObjectManager *om=GetObjectManager(hc);
if(!om)
return SafePtr<T>();
DefaultObjectManager<T> *dom=static_cast<DefaultObjectManager<T> *>(om);
const SourceCodeLocation scl
{
.file=source_file,
.func=source_function,
.line=source_line
};
SafePtrData<T> *spd=dom->CreateObject(scl,args...);
return SafePtr<T>(spd);
}
#define HGL_NEW_OBJECT(class_name,...) DefaultCreateObject<class_name>(__FILE__,__FUNCTION__,__LINE__ __VA_OPT__(,) __VA_ARGS__)
#define HGL_DEFINE_OBJECT(class_name,type_name,...) SafePtr<class_name> type_name=HGL_NEW_OBJECT(class_name __VA_OPT__(,) __VA_ARGS__)
}//namespace hgl

View File

@ -0,0 +1,228 @@
#pragma once
#include<hgl/type/object/ObjectBaseInfo.h>
namespace hgl
{
/**
* .
*/
class Object
{
ObjectBaseInfo object_base_info;
public:
const ObjectBaseInfo & GetObjectBaseInfo () const noexcept { return object_base_info; } ///<获取对象基本信息
ObjectManager * GetObjectManager () noexcept { return object_base_info.object_manager; } ///<获取对象管理器
const size_t GetHashCode () const noexcept { return object_base_info.hash_code; } ///<获取对象数据类型的hash值
const size_t GetSerialNumber () const noexcept { return object_base_info.serial_number; } ///<获取对象的序列号
protected:
template<typename T> friend class SafePtr;
template<typename T> friend struct DefaultObjectAllocator;
Object(const ObjectBaseInfo &obi) noexcept { object_base_info=obi; }
virtual ~Object()=default;
virtual void Deinitailize()=0;
};//class Object
template<typename T> class DefaultObjectManager;
#define HGL_OBJECT_CLASS_BODY(class_name) \
private: \
\
friend struct DefaultObjectAllocator<class_name>;\
\
class_name(const ObjectBaseInfo &obi):Object(obi)=default; \
/*{std::cout<<#class_name " Construct("<<GetSerialNumber()<<")"<<std::endl;}*/ \
\
virtual ~class_name() override=default; \
/*{std::cout<<#class_name " Destruct("<<GetSerialNumber()<<")"<<std::endl;}*/ \
\
public: \
\
static const size_t StaticHashCode() noexcept {return GetTypeHash<class_name>();} \
template<typename T> struct SafePtrData
{
T *ptr;
int count;
private:
SafePtrData(T *p)
{
ptr=p;
count=0;
}
~SafePtrData()=default;
template<typename T> friend class DefaultObjectManager;
};
/**
* 访<Br>
* WeakPtr:
* <ul>
* <li>SafePtr不使用atom计数器线</li>
* <li>SafePtr不会自动释放指针访nullptr</li>
* </ul>
*/
template<typename T> class SafePtr
{
SafePtrData<T> *data;
public:
SafePtr()
{
data=nullptr;
}
SafePtr(SafePtrData<T> *spd)
{
data=spd;
if(data)
++data->count;
}
public:
virtual ~SafePtr()
{
Release();
}
T *Get() {return data?data->ptr:nullptr;}
const T *Get() const {return data?data->ptr:nullptr;}
T *operator->() { return Get(); }
T &operator* () { return *Get(); }
const T *operator->() const { return Get(); }
const bool operator==(const T *ptr) const noexcept { return Get()==ptr; }
const bool operator!=(const T *ptr) const noexcept { return Get()!=ptr; }
const bool operator==(const SafePtr<T> &sp) const { return Get()==sp.Get(); }
const bool operator!=(const SafePtr<T> &sp) const { return Get()!=sp.Get(); }
const bool IsValid() const noexcept ///<当前对象指针是否有效
{
return data&&data->ptr;
}
SafePtr<T> &operator=(SafePtr<T> &sp)
{
if(!sp.IsValid())
{
Release();
return *this;
}
if(data)
{
if(data->ptr==sp.data->ptr)
return *this;
Release();
}
data=sp.data;
++data->count;
return *this;
}
template<typename OT>
SafePtr<T> &operator=(SafePtr<OT> &spd)
{
if(T::StaticHashCode()!=OT.StaticHashCode())
{
Release();
return *this;
}
if(data!=spd.data)
{
Release();
data=spd.data;
++data->count;
}
return *this;
}
SafePtr<T> &operator=(Object *obj)=delete;
/**
* ()
*/
void Destory()
{
if(!data)
return;
if(!data->ptr)
return;
ObjectManager *om=data->ptr->GetObjectManager();
if(!om)
{
//std::cerr<<"SafePtr<"<<GetTypeName<T>()<<">::Destory() error, manager is null."<<std::endl;
return;
}
//std::cout<<"SafePtr<"<<GetTypeName<T>()<<">::Destory() serial:"<<data->ptr->GetSerialNumber()<<std::endl;
DefaultObjectManager<T> *dom=static_cast<DefaultObjectManager<T> *>(om);
dom->ReleaseObject(data);
data=nullptr;
}
/**
* (0)
*
* \return
*/
int Release()
{
if(!data)
return -1;
//if(data->ptr)
//{
// std::cout<<"SafePtr<"<<GetTypeName<T>()<<">::Release() serial:"<<data->ptr->GetSerialNumber()<<std::endl;
//}
int result;
if(data->count==1)
{
Destory();
result=0;
}
else
{
--data->count;
result=data->count;
}
data=nullptr;
return result;
}
};//template<typename T> class SafePtr
}//namespace hgl

View File

@ -0,0 +1,60 @@
#pragma once
//#include<iostream>
namespace hgl
{
struct ObjectBaseInfo;
class Object;
class ObjectManager;
/**
* .
*/
struct ObjectAllocator
{
virtual void Join (ObjectManager *) {}; ///<桥接一个对象管理器
virtual void Unjoin (ObjectManager *) {}; ///<断开一个对象管理器
virtual Object *Create (const ObjectBaseInfo &obi)=0; ///<创建一个新对象
virtual void Release (Object *)=0; ///<释放一个对象
/**
*
* @param not_release_objects_count
* @return (true则会调用CleanNotReleaseObject逐个释放)
*/
virtual bool PreUnjoin(int not_release_objects_count)
{
//std::cerr<<"DefaultObjectManager::~DefaultObjectManager("<<GetTypename()<<") "<<object_set.size()<<" objects havn't been release."<<std::endl;
return(true);
}
virtual void CleanNotReleaseObject(Object *obj) ///<清理一个未释放的对象(用于没有手动释放时的自动清理)
{
//const ObjectBaseInfo &obi=obj->GetObjectBaseInfo();
//std::cout<<"Object(hash_code="<<obi.hash_code
// <<", serial_number="<<obi.serial_number
// <<", source_file="<<obi.source_code_location.file
// <<", source_function="<<obi.source_code_location.func
// <<", source_line="<<obi.source_code_location.line
// <<")"<<std::endl;
Release(obj);
}
};
template<typename T> struct DefaultObjectAllocator:public ObjectAllocator
{
virtual Object *Create(const ObjectBaseInfo &obi)override
{
return new T(obi);
}
virtual void Release(Object *obj)override
{
delete obj;
}
};
}//namespace hgl

View File

@ -0,0 +1,18 @@
#pragma once
#include<hgl/SourceCodeLocation.h>
namespace hgl
{
class ObjectManager;
struct ObjectBaseInfo
{
size_t hash_code; ///<对象数据类型的hash值
ObjectManager * object_manager; ///<对象管理器
size_t serial_number; ///<对象序列号
SourceCodeLocation source_code_location;
};
}//namespace hgl

View File

@ -0,0 +1,169 @@
#pragma once
#include"Object.h"
#include"ObjectAllocator.h"
#include<tsl/robin_set.h>
#include<tsl/robin_map.h>
namespace hgl
{
class Object;
/**
* .
*/
class ObjectManager
{
size_t object_hash_code;
const char *object_type_name;
size_t object_count;
protected:
const size_t AcquireSerialNumber(){return ++object_count;}
public:
const size_t GetHashCode()const{return object_hash_code;}
const char * GetTypename()const{return object_type_name;}
const size_t GetCount()const{return object_count;}
public:
ObjectManager(const size_t &hc,const char *tn)
{
object_hash_code=hc;
object_type_name=tn;
object_count=0;
}
virtual ~ObjectManager()=default;
};//class ObjectManager
bool RegistryObjectManager(ObjectManager *om); ///<注册一个对象管理器
void UnregistryObjectManager(ObjectManager *om); ///<注销一个对象管理器
/**
*
*/
template<typename T> class DefaultObjectManager:public ObjectManager
{
tsl::robin_set<T *> object_set;
tsl::robin_map<size_t,SafePtrData<T> *> object_map;
ObjectAllocator *object_allocator;
public:
DefaultObjectManager(ObjectAllocator *oa):ObjectManager(typeid(T).hash_code(),typeid(T).name())
{
object_allocator=oa;
object_allocator->Join(this);
RegistryObjectManager(this);
}
virtual ~DefaultObjectManager()
{
if(object_set.size())
{
if(object_allocator->PreUnjoin(object_set.size())) //这里返回的是是否需要逐个释放
{
for(auto &it:object_set)
{
object_allocator->CleanNotReleaseObject(it);
}
}
}
object_allocator->Unjoin(this);
UnregistryObjectManager(this);
}
protected:
template<typename T,typename ...ARGS> friend SafePtr<T> DefaultCreateObject(const char *source_file,const char *source_function,const size_t source_line,ARGS...args);
template<typename ...ARGS>
SafePtrData<T> *CreateObject(const SourceCodeLocation &scl,ARGS...args)
{
ObjectBaseInfo obi
{
.hash_code =GetHashCode(),
.object_manager =this,
.serial_number =AcquireSerialNumber(),
.source_code_location=scl
};
Object *obj=object_allocator->Create(obi);
SafePtrData<T> *spd=new SafePtrData<T>((T *)obj);
object_set.insert({(T *)obj});
object_map.insert({obj->GetSerialNumber(),spd});
spd->ptr->Initailize(args...);
return spd;
}
template<typename T> friend class SafePtr;
void ReleaseObject(SafePtrData<T> *spd)
{
if(!spd)
return;
object_map.erase(spd->ptr->GetSerialNumber());
object_set.erase(spd->ptr);
if(spd->ptr)
{
spd->ptr->Deinitailize();
object_allocator->Release(spd->ptr);
spd->ptr=nullptr;
}
if(spd->count>1)
{
--spd->count;
}
else
{
delete spd;
}
}
template<typename T> friend SafePtr<T> GetObjectBySerial(const size_t &serial);
SafePtrData<T> *GetObjectBySerial(const size_t &serial)
{
return object_map.at(serial);
}
};//class DefaultObjectManager
#define HGL_DEFINE_DEFAULT_OBJECT_MANAGER(T) namespace \
{ \
static DefaultObjectAllocator<T> T##ObjectAllocator; \
static DefaultObjectManager<T> T##ObjectManager(&T##ObjectAllocator); \
}
ObjectManager *GetObjectManager(const size_t &hash_code); ///<取得一个对象管理器
template<typename T> inline ObjectManager *GetObjectManager() ///<取得一个对象管理器
{
return GetObjectManager(typeid(T).hash_code());
}
template<typename T> inline SafePtr<T> GetObjectBySerial(const size_t &serial) ///<通过序列号取得一个对象
{
ObjectManager *om=GetObjectManager<T>();
if(!om)
return SafePtr<T>();
DefaultObjectManager<T> *dom=static_cast<DefaultObjectManager<T> *>(om);
return SafePtr<T>(dom->GetObjectBySerial(serial));
}
}//namespace hgl

View File

@ -13,6 +13,10 @@ SET(CORE_PLATFORM_HEADER_FILES ${CORE_PLATFORM_HEADER_FILES}
${CORE_PLATFORM_OS_FILES}
${CORE_PLATFORM_COMPILER_FILES})
SET(TYPE_INFO_FILE ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/TypeInfo.h)
SOURCE_GROUP("DataType" FILES ${TYPE_INFO_FILE})
SET(TYPE_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type)
SET(TYPE_IDNAME_HEADER_FILES ${TYPE_INCLUDE_PATH}/ConstStringSet.h
@ -48,9 +52,18 @@ SET(SYSTEM_INFO_SOURCE ${CORE_PLATFORM_INCLUDE_PATH}/SystemInfo.h
SET(MATH_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/math)
SET(BASE_OBJECT_SOURCE_FILES Object/TickObject.cpp)
SET(BASE_OBJECT_HEADER_FILES ${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/ObjectBaseInfo.h
${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/Object.h
${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/ObjectAllocator.h
${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/ObjectManager.h
${CMCORE_ROOT_INCLUDE_PATH}/hgl/type/object/DefaultCreateObject.h)
SOURCE_GROUP("DataType\\Object" FILES ${BASE_OBJECT_SOURCE_FILES})
SET(BASE_OBJECT_SOURCE_FILES Object/Object.cpp
Object/ObjectManager.cpp
Object/TickObject.cpp)
SOURCE_GROUP("DataType\\Object" FILES ${BASE_OBJECT_HEADER_FILES}
${BASE_OBJECT_SOURCE_FILES})
##Math--------------------------------------------------------
SET(MATH_HEADER_FILES ${MATH_INCLUDE_PATH}/bvec.h
@ -237,6 +250,8 @@ SOURCE_GROUP("Log\\Source Files" FILES ${BASE_LOG_SOURCE})
add_cm_library(CMCore "CM" ${CORE_PLATFORM_HEADER_FILES}
#${SYSTEM_INFO_SOURCE}
${TYPE_INFO_FILE}
${BASE_OBJECT_HEADER_FILES}
${BASE_OBJECT_SOURCE_FILES}
${COLOR_HEADER_FILES}

16
src/Object/Object.cpp Normal file
View File

@ -0,0 +1,16 @@
//#include<hgl/type/object/Object.h>
namespace hgl
{
//Object::Object(const ObjectBaseInfo &obi) noexcept
//{
// object_base_info=obi;
// std::cout<<"Object Construct("<<GetSerialNumber()<<")"<<std::endl;
//}
//Object::~Object()
//{
// std::cout<<"Object Destruct("<<GetSerialNumber()<<")."<<std::endl;
//}
}//namespace hgl

View File

@ -0,0 +1,71 @@
#include<hgl/type/object/ObjectManager.h>
//#include<hgl/type/object/Object.h>
//#include<iostream>
#include<tsl/robin_map.h>
namespace hgl
{
namespace
{
using ObjectManagerMap=tsl::robin_map<size_t,ObjectManager *>;
static ObjectManagerMap *object_manager_map=nullptr;
ObjectManagerMap *GetObjectManagerMap()
{
if(!object_manager_map)
object_manager_map=new ObjectManagerMap;
return(object_manager_map);
}
}//namespace
bool RegistryObjectManager(ObjectManager *om)
{
if(!om)
return(false);
const size_t hc=om->GetHashCode();
auto *omm=GetObjectManagerMap();
if(omm->contains(hc))
return(false);
omm->insert({hc,om});
//std::cout<<"RegistryObjectManager("<<std::hex<<hc<<":"<<om->GetTypename()<<")"<<std::endl;
return(true);
}
void UnregistryObjectManager(ObjectManager *om)
{
if(!om)
return;
const size_t hc=om->GetHashCode();
auto *omm=GetObjectManagerMap();
auto omi=omm->find(hc);
if(omi.key()!=hc)
return;
//std::cout<<"UnregistryObjectManager("<<std::hex<<hc<<":"<<om->GetTypename()<<")"<<std::endl;
omm->erase(hc);
}
ObjectManager *GetObjectManager(const size_t &hash_code)
{
auto *omm=GetObjectManagerMap();
auto omi=omm->find(hash_code);
if(omi.key()==hash_code)
return(omi.value());
else
return(nullptr);
}
}//namespace hgl