删除旧的对象管理
This commit is contained in:
parent
29e758f963
commit
32c5b6731f
@ -1,34 +0,0 @@
|
|||||||
#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
|
|
||||||
|
|
@ -1,235 +1,231 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include<hgl/type/DataType.h>
|
#include<hgl/type/DataType.h>
|
||||||
#include<hgl/type/object/ObjectBaseInfo.h>
|
#include<hgl/type/object/ObjectBaseInfo.h>
|
||||||
#include<hgl/type/object/ObjectRelation.h>
|
|
||||||
|
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* 基础对象.
|
* 基础对象
|
||||||
*/
|
*/
|
||||||
class Object
|
class Object
|
||||||
{
|
{
|
||||||
ObjectBaseInfo object_base_info;
|
ObjectBaseInfo object_info;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const ObjectSimpleInfo &GetObjectSimpleInfo () const noexcept { return object_base_info; } ///<获取对象简单信息
|
const ObjectBaseInfo & GetObjectBaseInfo () const noexcept { return object_info; } ///<获取对象简单信息
|
||||||
const ObjectBaseInfo & GetObjectBaseInfo () const noexcept { return object_base_info; } ///<获取对象基本信息
|
|
||||||
|
|
||||||
ObjectManager * GetObjectManager () noexcept { return object_base_info.object_manager; } ///<获取对象管理器
|
const size_t GetTypeHash () const noexcept { return object_info.hash_code; } ///<获取对象数据类型的hash值
|
||||||
|
const size_t GetUniqueID () const noexcept { return object_info.unique_id; } ///<获取对象的唯一序列号
|
||||||
|
|
||||||
const size_t GetTypeHash () const noexcept { return object_base_info.hash_code; } ///<获取对象数据类型的hash值
|
public:
|
||||||
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;
|
||||||
template<typename T> friend class SafePtr;
|
|
||||||
template<typename T> friend struct DefaultObjectAllocator;
|
|
||||||
|
|
||||||
NO_COPY(Object)
|
NO_COPY(Object)
|
||||||
NO_MOVE(Object)
|
NO_MOVE(Object)
|
||||||
|
|
||||||
Object(const ObjectBaseInfo &obi) noexcept { object_base_info=obi; }
|
Object(const ObjectBaseInfo &oi) noexcept { object_info=oi; }
|
||||||
virtual ~Object()=default;
|
virtual ~Object()=default;
|
||||||
|
|
||||||
virtual void Deinitailize()=0;
|
//virtual bool Initailize()=0;
|
||||||
|
//virtual void Deinitailize()=0;
|
||||||
};//class Object
|
};//class Object
|
||||||
|
|
||||||
template<typename T> class DefaultObjectManager;
|
template<typename T> inline T *New(const SourceCodeLocation &scl)
|
||||||
|
|
||||||
#define HGL_OBJECT_CLASS_BODY(class_name) \
|
|
||||||
private: \
|
|
||||||
\
|
|
||||||
friend struct DefaultObjectAllocator<class_name>;\
|
|
||||||
\
|
|
||||||
using Object::Object; \
|
|
||||||
/*class_name(const ObjectBaseInfo &obi):Object(obi)*/ \
|
|
||||||
/*{std::cout<<#class_name " Construct("<<GetSerialNumber()<<")"<<std::endl;}*/ \
|
|
||||||
\
|
|
||||||
virtual ~class_name()=default; \
|
|
||||||
/*{std::cout<<#class_name " Destruct("<<GetSerialNumber()<<")"<<std::endl;}*/ \
|
|
||||||
\
|
|
||||||
public: \
|
|
||||||
\
|
|
||||||
static const size_t StaticTypeHash() noexcept {return hgl::GetTypeHash<class_name>();} \
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T> struct SafePtrData
|
|
||||||
{
|
{
|
||||||
T *ptr;
|
static size_t new_count=0;
|
||||||
int count;
|
|
||||||
|
|
||||||
private:
|
ObjectBaseInfo obi;
|
||||||
|
|
||||||
SafePtrData(T *p)
|
obi.hash_code=GetTypeHash<T>();
|
||||||
{
|
obi.unique_id=new_count;
|
||||||
ptr=p;
|
obi.scl=scl;
|
||||||
count=0;
|
|
||||||
|
++new_count;
|
||||||
|
|
||||||
|
T *obj=new T(obi);
|
||||||
|
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
~SafePtrData()=default;
|
#define NewObject(T,obj) T *obj=New<T>(HGL_SCL_HERE);
|
||||||
|
|
||||||
template<typename T> friend class DefaultObjectManager;
|
//template<typename T> struct SafePtrData
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 安全访问指针<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::StaticTypeHash()!=OT::StaticTypeHash())
|
|
||||||
{
|
|
||||||
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;
|
// T *ptr;
|
||||||
|
// int count;
|
||||||
|
|
||||||
|
//private:
|
||||||
|
|
||||||
|
// SafePtrData(T *p)
|
||||||
|
// {
|
||||||
|
// ptr=p;
|
||||||
|
// count=0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
int result;
|
// ~SafePtrData()=default;
|
||||||
|
|
||||||
if(data->count==1)
|
// template<typename T> friend class DefaultObjectManager;
|
||||||
{
|
//};
|
||||||
Destory();
|
|
||||||
result=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
--data->count;
|
|
||||||
|
|
||||||
result=data->count;
|
///**
|
||||||
}
|
// * 安全访问指针<Br>
|
||||||
|
// * 其本质类似于的WeakPtr,但是不同的是:
|
||||||
|
// * <ul>
|
||||||
|
// * <li>SafePtr不使用atom计数器,所以它不是线程安全的</li>
|
||||||
|
// * <li>SafePtr不会自动释放指针,它是在访问时检查指针是否有效,如果无效则返回nullptr</li>
|
||||||
|
// * </ul>
|
||||||
|
// */
|
||||||
|
//template<typename T> class SafePtr
|
||||||
|
//{
|
||||||
|
// SafePtrData<T> *data;
|
||||||
|
|
||||||
data=nullptr;
|
//public:
|
||||||
return result;
|
|
||||||
}
|
// SafePtr()
|
||||||
};//template<typename T> class 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::StaticTypeHash()!=OT::StaticTypeHash())
|
||||||
|
// {
|
||||||
|
// 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
|
}//namespace hgl
|
||||||
|
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
#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(size_t 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
|
|
||||||
|
|
@ -1,28 +1,32 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include<hgl/SourceCodeLocation.h>
|
#include<hgl/SourceCodeLocation.h>
|
||||||
|
#include<typeinfo>
|
||||||
|
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
class ObjectManager;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象简单信息
|
* 对象简单信息
|
||||||
*/
|
*/
|
||||||
struct ObjectSimpleInfo
|
struct ObjectBaseInfo
|
||||||
{
|
{
|
||||||
size_t hash_code; ///<对象数据类型的hash值
|
size_t hash_code; ///<对象数据类型的hash值
|
||||||
size_t serial_number; ///<对象序列号
|
size_t unique_id; ///<唯一序列号
|
||||||
|
|
||||||
|
SourceCodeLocation scl;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
struct ObjectTotalInfo
|
||||||
* 对象基本信息
|
|
||||||
*/
|
|
||||||
struct ObjectBaseInfo:public ObjectSimpleInfo
|
|
||||||
{
|
{
|
||||||
ObjectManager * object_manager; ///<对象管理器
|
size_t hash_code;
|
||||||
|
|
||||||
SourceCodeLocation source_code_location; ///<对象创建的源代码位置
|
std::type_info *info;
|
||||||
|
|
||||||
|
size_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void RegistryObjectHash(const size_t &hash_code,const std::type_info *);
|
||||||
|
|
||||||
|
const ObjectTotalInfo *GetObjectTotalInfo(const size_t &hash_code);
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
|
|
||||||
|
@ -1,168 +0,0 @@
|
|||||||
#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 GetTypeHash()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;
|
|
||||||
|
|
||||||
obi.hash_code =GetTypeHash();
|
|
||||||
obi.object_manager =this;
|
|
||||||
obi.serial_number =AcquireSerialNumber();
|
|
||||||
obi.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
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include<hgl/type/object/ObjectBaseInfo.h>
|
|
||||||
#include<hgl/type/List.h>
|
|
||||||
//#include<tsl/robin_map.h>
|
|
||||||
|
|
||||||
namespace hgl
|
|
||||||
{
|
|
||||||
struct ObjectReferringRecord
|
|
||||||
{
|
|
||||||
ObjectSimpleInfo osi;
|
|
||||||
|
|
||||||
size_t refer_serial; ///<引用序号
|
|
||||||
|
|
||||||
SourceCodeLocation scl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对象引用关系
|
|
||||||
*/
|
|
||||||
struct ObjectRelation
|
|
||||||
{
|
|
||||||
List<ObjectReferringRecord> referring_me; ///<引用自己的对象
|
|
||||||
List<ObjectReferringRecord> me_referring; ///<自己引用的对象
|
|
||||||
|
|
||||||
//tsl::robin_map< size_t, /*refer_serial*/
|
|
||||||
// ObjectReferringRecord *> referring_me_map; ///<引用自己的对象
|
|
||||||
};//struct ObjectRelation
|
|
||||||
}//namespace hgl
|
|
@ -58,14 +58,10 @@ SET(SYSTEM_INFO_SOURCE ${CORE_PLATFORM_INCLUDE_PATH}/SystemInfo.h
|
|||||||
SET(MATH_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/math)
|
SET(MATH_INCLUDE_PATH ${CMCORE_ROOT_INCLUDE_PATH}/hgl/math)
|
||||||
|
|
||||||
SET(BASE_OBJECT_HEADER_FILES ${TYPE_INCLUDE_PATH}/object/ObjectBaseInfo.h
|
SET(BASE_OBJECT_HEADER_FILES ${TYPE_INCLUDE_PATH}/object/ObjectBaseInfo.h
|
||||||
${TYPE_INCLUDE_PATH}/object/ObjectRelation.h
|
${TYPE_INCLUDE_PATH}/object/Object.h)
|
||||||
${TYPE_INCLUDE_PATH}/object/Object.h
|
|
||||||
${TYPE_INCLUDE_PATH}/object/ObjectAllocator.h
|
|
||||||
${TYPE_INCLUDE_PATH}/object/ObjectManager.h
|
|
||||||
${TYPE_INCLUDE_PATH}/object/DefaultCreateObject.h)
|
|
||||||
|
|
||||||
SET(BASE_OBJECT_SOURCE_FILES Object/Object.cpp
|
SET(BASE_OBJECT_SOURCE_FILES Object/ObjectBaseInfo.cpp
|
||||||
Object/ObjectManager.cpp
|
Object/Object.cpp
|
||||||
Object/TickObject.cpp)
|
Object/TickObject.cpp)
|
||||||
|
|
||||||
SOURCE_GROUP("DataType\\Object" FILES ${BASE_OBJECT_HEADER_FILES}
|
SOURCE_GROUP("DataType\\Object" FILES ${BASE_OBJECT_HEADER_FILES}
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
#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->GetTypeHash();
|
|
||||||
|
|
||||||
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->GetTypeHash();
|
|
||||||
|
|
||||||
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
|
|
Loading…
x
Reference in New Issue
Block a user