2024-11-19 01:38:03 +08:00
|
|
|
|
/**
|
|
|
|
|
|
|
|
|
|
对象关系测试
|
|
|
|
|
|
|
|
|
|
1.每个对象有自己的 type_hash , 由typeid(T).hash_code()获取。
|
|
|
|
|
同时含有唯一 serial number
|
|
|
|
|
|
|
|
|
|
2.每个对象都有自己的引用计数和引用记录
|
|
|
|
|
|
|
|
|
|
3.引用记录中,会记录当前对象被谁引用,以及引用代码的位置
|
|
|
|
|
|
|
|
|
|
4.同时,引用记录中,会包含一个引用serial,用于标识当前引用的唯一性。
|
|
|
|
|
在出现对象泄露时,可根据引用记录查询是那个对象忘记了释放引用。
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include<hgl/type/object/Object.h>
|
|
|
|
|
#include<hgl/type/List.h>
|
2024-11-19 02:22:55 +08:00
|
|
|
|
#include<tsl/robin_set.h>
|
2024-11-19 01:38:03 +08:00
|
|
|
|
#include<iostream>
|
|
|
|
|
|
|
|
|
|
using namespace hgl;
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
2024-11-19 02:06:33 +08:00
|
|
|
|
#define CLASS_TYPE_HASH(type) static const size_t StaticTypeHash(){return typeid(type).hash_code();}
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
|
|
|
|
class BaseObject
|
|
|
|
|
{
|
2025-01-26 10:20:33 +08:00
|
|
|
|
ObjectBaseInfo object_simple_info;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
2025-01-26 10:20:33 +08:00
|
|
|
|
BaseObject(const ObjectBaseInfo &osi)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-19 02:22:55 +08:00
|
|
|
|
object_simple_info=osi;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~BaseObject()=default;
|
2024-11-19 02:06:33 +08:00
|
|
|
|
|
|
|
|
|
CLASS_TYPE_HASH(BaseObject)
|
|
|
|
|
|
2025-01-26 10:20:33 +08:00
|
|
|
|
const ObjectBaseInfo &GetObjectBaseInfo()const{return object_simple_info;}
|
2024-11-19 02:22:55 +08:00
|
|
|
|
const size_t GetTypeHash()const{return object_simple_info.hash_code;}
|
2025-01-26 10:20:33 +08:00
|
|
|
|
const size_t GetObjectSerial()const{return object_simple_info.unique_id;}
|
2024-11-20 02:47:51 +08:00
|
|
|
|
|
|
|
|
|
virtual void Destory()
|
|
|
|
|
{
|
|
|
|
|
delete this;
|
|
|
|
|
}
|
2024-11-19 01:38:03 +08:00
|
|
|
|
};//class BaseObject
|
|
|
|
|
|
2024-11-19 02:06:33 +08:00
|
|
|
|
#define CLASS_BODY(class_type) private: \
|
2024-11-19 01:38:03 +08:00
|
|
|
|
static const size_t CreateObjectSerial(){static size_t serial=0;return ++serial;} \
|
|
|
|
|
public: \
|
2025-01-26 10:20:33 +08:00
|
|
|
|
class_type():BaseObject(ObjectBaseInfo(class_type::StaticTypeHash(),class_type::CreateObjectSerial())){} \
|
2024-11-19 02:06:33 +08:00
|
|
|
|
virtual ~class_type()=default; \
|
|
|
|
|
CLASS_TYPE_HASH(class_type)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T> inline const bool IsType(BaseObject *bo){return bo?(bo->GetTypeHash()==T::StaticTypeHash()):false;}
|
|
|
|
|
|
2024-11-19 02:06:33 +08:00
|
|
|
|
inline const bool TypeEqual(BaseObject *bo1,BaseObject *bo2)
|
|
|
|
|
{
|
|
|
|
|
if(!bo1||!bo2)return(false);
|
|
|
|
|
|
|
|
|
|
return bo1->GetTypeHash()==bo2->GetTypeHash();
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-19 01:38:03 +08:00
|
|
|
|
class TestObject:public BaseObject
|
|
|
|
|
{
|
|
|
|
|
CLASS_BODY(TestObject)
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
void test1()
|
|
|
|
|
{
|
|
|
|
|
TestObject to1,to2,to3;
|
|
|
|
|
|
|
|
|
|
BaseObject *bo=&to3;
|
|
|
|
|
|
|
|
|
|
std::cout<<"TestObject::StaticHash:"<<TestObject::StaticTypeHash()<<std::endl;
|
|
|
|
|
|
|
|
|
|
std::cout<<"to1.serial: "<<to1.GetObjectSerial()<<std::endl;
|
|
|
|
|
std::cout<<"to2.serial: "<<to2.GetObjectSerial()<<std::endl;
|
|
|
|
|
|
|
|
|
|
std::cout<<"bo->StaticHash: "<<bo->StaticTypeHash()<<std::endl;
|
|
|
|
|
std::cout<<"bo->TypeHash: "<<bo->GetTypeHash()<<std::endl;
|
|
|
|
|
std::cout<<"bo->Serial: "<<bo->GetObjectSerial()<<std::endl;
|
|
|
|
|
|
|
|
|
|
bool result=IsType<TestObject>(bo);
|
|
|
|
|
|
|
|
|
|
std::cout<<"IsType<TestObject>(bo) result is "<<(result?"true":"false")<<std::endl;
|
|
|
|
|
|
|
|
|
|
result=TypeEqual(&to1,bo);
|
|
|
|
|
|
|
|
|
|
std::cout<<"TypeEqual(&to1,bo) result is "<<(result?"true":"false")<<std::endl;
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-26 10:20:33 +08:00
|
|
|
|
using ObjectSimpleInfoSet=tsl::robin_set<ObjectBaseInfo>;
|
2024-11-19 02:22:55 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
template<typename T> class RefPtr;
|
|
|
|
|
|
2024-11-19 02:22:55 +08:00
|
|
|
|
/**
|
2024-11-20 02:47:51 +08:00
|
|
|
|
* 引用对象
|
2024-11-19 02:22:55 +08:00
|
|
|
|
*/
|
2024-11-20 02:47:51 +08:00
|
|
|
|
template<typename T> class RefObject
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
T *obj;
|
2024-11-19 02:22:55 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
ObjectSimpleInfoSet ref_me_set; ///<引用我的对象
|
|
|
|
|
ObjectSimpleInfoSet me_ref_set; ///<我引用的对象
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
template<typename T> friend class RefPtr;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
RefObject(T *o)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
obj=o;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
~RefObject()
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
|
|
|
|
if(obj)
|
2024-11-20 02:47:51 +08:00
|
|
|
|
obj->Destory();
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
/**
|
|
|
|
|
* 申请一个引用
|
|
|
|
|
*/
|
2025-01-26 10:20:33 +08:00
|
|
|
|
RefPtr<T> Acquire(const ObjectBaseInfo *osi,const SourceCodeLocation &scl);
|
2024-11-20 02:47:51 +08:00
|
|
|
|
|
|
|
|
|
void Release(RefPtr<T> *rp,const SourceCodeLocation &)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
if(!rp)return;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2024-11-20 02:47:51 +08:00
|
|
|
|
};//template<typename T> class RefObject
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
template<typename T> class RefPtr
|
|
|
|
|
{
|
|
|
|
|
RefObject<T> *ref_obj;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
RefPtr()
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
ref_obj=nullptr;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
RefPtr(RefObject<T> *ro)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
ref_obj=ro;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
~RefPtr()
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
if(ref_obj)
|
|
|
|
|
ref_obj->Release(this,HGL_SCL_HERE);
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
bool IsValid()const
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
if(!this)return(false);
|
|
|
|
|
if(!ref_obj)return(false);
|
|
|
|
|
if(!ref_obj->obj)return(false);
|
|
|
|
|
|
|
|
|
|
return(true);
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
operator T *()
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
return ref_obj->obj;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
2024-11-20 02:47:51 +08:00
|
|
|
|
|
|
|
|
|
void Release(const SourceCodeLocation &scl)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
if(!ref_obj)return;
|
|
|
|
|
|
|
|
|
|
ref_obj->Release(this,scl);
|
2024-11-19 01:38:03 +08:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-26 10:20:33 +08:00
|
|
|
|
#define ACQUIRE_REF(ref_object,self) ref_object->Acquire(&self->GetObjectBaseInfo(),HGL_SCL_HERE);
|
2024-11-20 02:47:51 +08:00
|
|
|
|
|
|
|
|
|
#define REF_PTR_RELEASE(obj) obj->Release(HGL_SCL_HERE);
|
|
|
|
|
|
|
|
|
|
class TestTexture:public BaseObject
|
2024-11-19 01:38:03 +08:00
|
|
|
|
{
|
2024-11-20 02:47:51 +08:00
|
|
|
|
CLASS_BODY(TestTexture)
|
|
|
|
|
};
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
class TestMaterial:public BaseObject
|
|
|
|
|
{
|
|
|
|
|
CLASS_BODY(TestMaterial)
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
RefPtr<TestTexture> texture;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
public:
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
void Init(RefObject<TestTexture> *ref_tex)
|
|
|
|
|
{
|
|
|
|
|
texture=ACQUIRE_REF(ref_tex,this);
|
|
|
|
|
}
|
|
|
|
|
};
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
void test2()
|
|
|
|
|
{
|
|
|
|
|
RefObject<TestTexture> ref_tex1=new TestTexture;
|
2024-11-19 01:38:03 +08:00
|
|
|
|
|
2024-11-20 02:47:51 +08:00
|
|
|
|
TestMaterial *mtl=new TestMaterial;
|
|
|
|
|
|
|
|
|
|
mtl->Init(&ref_tex1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int,char **)
|
|
|
|
|
{
|
2024-11-19 02:06:33 +08:00
|
|
|
|
|
|
|
|
|
|
2024-11-19 01:38:03 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|