added LifetimeCallback.h
This commit is contained in:
37
inc/hgl/type/LifetimeCallback.h
Normal file
37
inc/hgl/type/LifetimeCallback.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include<hgl/TypeFunc.h>
|
||||||
|
namespace hgl
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ԭ<><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ص<EFBFBD>
|
||||||
|
*/
|
||||||
|
template<typename T> struct RawLifetimeCallback
|
||||||
|
{
|
||||||
|
virtual bool Create(T *){return true;}
|
||||||
|
virtual void Clear(T *){return;}
|
||||||
|
|
||||||
|
virtual void Copy(T *dst,T *src,int count)
|
||||||
|
{
|
||||||
|
hgl_cpy(dst,src,count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ص<EFBFBD>
|
||||||
|
*/
|
||||||
|
template<typename T> struct ObjectLifetimeCallback:public RawLifetimeCallback<T *>
|
||||||
|
{
|
||||||
|
virtual bool Create(T **) override=0;
|
||||||
|
virtual void Clear(T **) override=0;
|
||||||
|
};//struct ObjectLifetimeCallback
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ȱʡ<C8B1><CAA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD>ص<EFBFBD>
|
||||||
|
*/
|
||||||
|
template<typename T> struct DefaultObjectLifetimeCallback:public ObjectLifetimeCallback<T>
|
||||||
|
{
|
||||||
|
virtual bool Create(T **obj) override {*obj=new T;return(true);}
|
||||||
|
virtual void Clear(T **obj) override {if(obj&&*obj)delete *obj;}
|
||||||
|
};//struct DefaultObjectLifetimeCallback
|
||||||
|
}//namespace hgl
|
@@ -11,7 +11,10 @@ namespace hgl
|
|||||||
if(num<=0)return;
|
if(num<=0)return;
|
||||||
|
|
||||||
for(int i=0;i<num;i++)
|
for(int i=0;i<num;i++)
|
||||||
Inactive.Push(Create());
|
{
|
||||||
|
T value=Create();
|
||||||
|
Inactive.Push(value);
|
||||||
|
}
|
||||||
|
|
||||||
alloc_count+=num;
|
alloc_count+=num;
|
||||||
if(alloc_count>history_max)
|
if(alloc_count>history_max)
|
||||||
@@ -160,14 +163,14 @@ namespace hgl
|
|||||||
|
|
||||||
Clear(p,ic);
|
Clear(p,ic);
|
||||||
|
|
||||||
Inactive.ClearData();
|
Inactive.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void Pool<T>::ClearAll()
|
void Pool<T>::ClearAll()
|
||||||
{
|
{
|
||||||
Clear(Inactive.GetData(),Inactive.GetCount());
|
Clear(Inactive.GetData(),Inactive.GetCount());
|
||||||
Inactive.ClearData();
|
Inactive.Clear();
|
||||||
|
|
||||||
Clear(Active.GetData(),Active.GetCount());
|
Clear(Active.GetData(),Active.GetCount());
|
||||||
Active.ClearData();
|
Active.ClearData();
|
||||||
|
@@ -1,265 +0,0 @@
|
|||||||
#ifndef HGL_QUEUE_CPP
|
|
||||||
#define HGL_QUEUE_CPP
|
|
||||||
|
|
||||||
namespace hgl
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 本类构造函数
|
|
||||||
* @param m 如果m的值不为0,则表示使用固定的队列大小。固定大小的队列会在一开始即分配好内存。
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
Queue<T>::Queue(int m)
|
|
||||||
{
|
|
||||||
cur_count=0;
|
|
||||||
|
|
||||||
if(m)
|
|
||||||
{
|
|
||||||
max_count=m;
|
|
||||||
|
|
||||||
items=hgl_align_malloc<T>(max_count);
|
|
||||||
}
|
|
||||||
else max_count=0;
|
|
||||||
|
|
||||||
alloc_count=max_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Queue<T>::~Queue()
|
|
||||||
{
|
|
||||||
if(cur_count||max_count)hgl_free(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::AllocMemory(int count)
|
|
||||||
{
|
|
||||||
if(max_count)
|
|
||||||
if(count>max_count)return(false);
|
|
||||||
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
if(count>alloc_count)
|
|
||||||
{
|
|
||||||
alloc_count=power_to_2(count);
|
|
||||||
|
|
||||||
items=(T *)hgl_align_realloc<T>(items,alloc_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alloc_count=power_to_2(count);
|
|
||||||
|
|
||||||
items=hgl_align_malloc<T>(alloc_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改队列的最大值
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::SetMaxCount(int m)
|
|
||||||
{
|
|
||||||
if(max_count)
|
|
||||||
{
|
|
||||||
if(max_count==m)return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
if(cur_count>m)
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
max_count=m;
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除队列中的所有数据
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
void Queue<T>::Free()
|
|
||||||
{
|
|
||||||
if(max_count==0)
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
hgl_free(items);
|
|
||||||
alloc_count=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_count=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除队列中的所有数据,但不释放内存
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
void Queue<T>::ClearData()
|
|
||||||
{
|
|
||||||
cur_count=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 访问队列中的一个数据,但不清除它
|
|
||||||
* @param t 取出的数据保存地
|
|
||||||
* @return 是否成功取出数据
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::Peek(T &t)
|
|
||||||
{
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
// t=items[0];
|
|
||||||
memcpy(&t,items,sizeof(T));
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除队列中的指定数据
|
|
||||||
* @param index 索引
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::Delete(int index)
|
|
||||||
{
|
|
||||||
if(index<0||index>=cur_count)
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
cur_count--;
|
|
||||||
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
if(index<cur_count)
|
|
||||||
memmove(items+index,items+index+1,(cur_count-index)*sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从队列中取出一个数据
|
|
||||||
* @param t 取出的数据保存地
|
|
||||||
* @return 是否成功取出数据
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::Pop(T &t)
|
|
||||||
{
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
// t=items[0];
|
|
||||||
memcpy(&t,items,sizeof(T));
|
|
||||||
|
|
||||||
cur_count--;
|
|
||||||
|
|
||||||
if(max_count==0)
|
|
||||||
{
|
|
||||||
if(cur_count)
|
|
||||||
{
|
|
||||||
//memcpy(items,items+1,count*sizeof(T));
|
|
||||||
memmove(items,items+1,cur_count*sizeof(T));
|
|
||||||
// items=(T *)hgl_realloc(items,count*sizeof(T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(items,items+1,cur_count*sizeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向队列中放入一个数据
|
|
||||||
* @param data 要放入的数据指针
|
|
||||||
* @return true 放入数据成功
|
|
||||||
* @return false 放入数据失败
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::Push(const T &data)
|
|
||||||
{
|
|
||||||
if(!AllocMemory(cur_count+1))
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
// items[count++]=data;
|
|
||||||
memcpy(items+cur_count,&data,sizeof(T));
|
|
||||||
cur_count++;
|
|
||||||
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 向队列中压入一堆数据
|
|
||||||
* @param dp 要放入的数据指针
|
|
||||||
* @param dc 要放入的数据数量
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool Queue<T>::Push(T *dp,const int dc)
|
|
||||||
{
|
|
||||||
if(!AllocMemory(cur_count+dc))
|
|
||||||
return(false);
|
|
||||||
|
|
||||||
memcpy(items+cur_count,dp,sizeof(T)*dc);
|
|
||||||
cur_count+=dc;
|
|
||||||
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
int Queue<T>::Find(const T &data)
|
|
||||||
{
|
|
||||||
if(cur_count<=0)
|
|
||||||
return(-1);
|
|
||||||
|
|
||||||
T *p=items;
|
|
||||||
for(int i=0;i<cur_count;i++)
|
|
||||||
{
|
|
||||||
if(*p==data)
|
|
||||||
return(i);
|
|
||||||
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void Queue<T>::operator =(const Queue<T> &ori)
|
|
||||||
{
|
|
||||||
if(ori.cur_count==0)return;
|
|
||||||
|
|
||||||
Free();
|
|
||||||
|
|
||||||
max_count=ori.cur_count;
|
|
||||||
cur_count=ori.cur_count;
|
|
||||||
|
|
||||||
if(max_count==0)
|
|
||||||
alloc_count=cur_count;
|
|
||||||
else
|
|
||||||
alloc_count=max_count;
|
|
||||||
|
|
||||||
items=hgl_align_malloc<T>(alloc_count);
|
|
||||||
|
|
||||||
memcpy(items,ori.items,alloc_count*sizeof(T));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace hgl
|
|
||||||
{
|
|
||||||
template<typename T>
|
|
||||||
void QueueObject<T>::Clear()
|
|
||||||
{
|
|
||||||
int n=Queue<T *>::cur_count;
|
|
||||||
|
|
||||||
while(n--)
|
|
||||||
delete Queue<T *>::items[n];
|
|
||||||
|
|
||||||
Queue<T *>::Free();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif//HGL_QUEUE_CPP
|
|
@@ -1,82 +1,180 @@
|
|||||||
#ifndef HGL_QUEUE_INCLUDE
|
#pragma once
|
||||||
#define HGL_QUEUE_INCLUDE
|
|
||||||
|
|
||||||
#include<hgl/type/DataType.h>
|
#include<hgl/type/DataArray.h>
|
||||||
namespace hgl
|
namespace hgl
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Queue模板类用于保存一个先进先出、后进后出的数据队列
|
* Queue模板类用于保存一个先进先出、后进后出的数据队列
|
||||||
*
|
|
||||||
* 注:这个类还在测试中,请不要修改这个类的源代码,如有修改意见,请致电作者。
|
|
||||||
*/
|
*/
|
||||||
template<typename T> class Queue ///队列顺序数据访问类
|
template<typename T> class Queue ///队列顺序数据访问类
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
int max_count; ///<最大可分配空间数量
|
DataArray<T> data_array[2];
|
||||||
int alloc_count; ///<已分配的空间数量
|
|
||||||
int cur_count;
|
int read_index;
|
||||||
T *items;
|
int write_index;
|
||||||
|
|
||||||
|
int read_offset;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool AllocMemory(int);
|
void SwapIndex()
|
||||||
|
{
|
||||||
|
if(read_index==0)
|
||||||
|
{
|
||||||
|
read_index=1;
|
||||||
|
write_index=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read_index=0;
|
||||||
|
write_index=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_offset=0;
|
||||||
|
}
|
||||||
|
|
||||||
public: //属性
|
public: //属性
|
||||||
|
|
||||||
T * GetData ()const{return items;} ///<取得原始数据
|
const int GetAllocCount ()const{return data_array[0].GetAllocCount()+
|
||||||
int GetCount ()const{return cur_count;} ///<取得数据数量
|
data_array[1].GetAllocCount();} ///<取得已分配的数据数量
|
||||||
|
|
||||||
int GetMaxCount ()const{return max_count;} ///<取得最大数量
|
const int GetCount ()const{return data_array[0].GetCount()+
|
||||||
bool SetMaxCount (int); ///<设置最大数量
|
data_array[1].GetCount();} ///<取得列表内数据数量
|
||||||
|
|
||||||
const T *begin()const{return items;}
|
virtual bool PreAlloc (int count) ///<预分配数据空间
|
||||||
const T *end()const{return items+cur_count;}
|
|
||||||
|
|
||||||
public: //方法
|
|
||||||
|
|
||||||
Queue(int=0);
|
|
||||||
virtual ~Queue();
|
|
||||||
|
|
||||||
bool Peek (T &); ///<尝试访问一个数据
|
|
||||||
bool Pop (T &); ///<弹出一个数据
|
|
||||||
bool Push (const T &); ///<压入一个数据
|
|
||||||
bool Push (T *,int); ///<压入一批数据
|
|
||||||
|
|
||||||
int Find (const T &); ///<查找队列中这个数据的编号
|
|
||||||
bool IsExist (const T &data)const{return this->Find(data)!=-1;} ///<确认是否有这个数据
|
|
||||||
bool Delete (int); ///<删除队列中指定编号的数据
|
|
||||||
|
|
||||||
void Free (); ///<清除所有数据
|
|
||||||
void ClearData (); ///<清除所有数据,但不释放内存
|
|
||||||
|
|
||||||
bool GetItem (int n,T &ti) ///<取得指定项数据
|
|
||||||
{
|
{
|
||||||
if(n<0||n>=cur_count)return(false);
|
if(!data_array[0].Alloc(count))return(false);
|
||||||
|
if(!data_array[1].Alloc(count))return(false);
|
||||||
|
|
||||||
ti=items[n];
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void operator =(const Queue<T> &);
|
const bool IsEmpty ()const{return GetCount()==0;} ///<确认列表是否为空
|
||||||
|
|
||||||
|
public: //方法
|
||||||
|
|
||||||
|
Queue()
|
||||||
|
{
|
||||||
|
write_index=0;
|
||||||
|
read_index=1;
|
||||||
|
read_offset=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Queue()=default;
|
||||||
|
|
||||||
|
virtual bool Push (T *data,int count) ///<压入一批数据
|
||||||
|
{
|
||||||
|
if(!data||count<=0)return(false);
|
||||||
|
|
||||||
|
int offset=data_array[write_index].GetCount();
|
||||||
|
|
||||||
|
if(!data_array[write_index].AddCount(count))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
data_array[write_index].WriteAt(data,offset,count);
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Push (T &data){return Push(&data,1);} ///<压入一个数据
|
||||||
|
|
||||||
|
virtual bool Peek (T &data) ///<尝试访问一个数据
|
||||||
|
{
|
||||||
|
if(data_array[read_index].GetCount()>=read_offset)
|
||||||
|
{
|
||||||
|
if(data_array[write_index].GetCount()<=0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
data_array[write_index].ReadAt(data,0);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data_array[read_index].ReadAt(data,read_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Pop (T &data) ///<弹出一个数据
|
||||||
|
{
|
||||||
|
if(data_array[read_index].GetCount()>=read_offset)
|
||||||
|
{
|
||||||
|
if(data_array[write_index].GetCount()<=0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
data_array[read_index].Clear();
|
||||||
|
|
||||||
|
SwapIndex();
|
||||||
|
|
||||||
|
data_array[read_index].ReadAt(data,0);
|
||||||
|
|
||||||
|
++read_offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data_array[read_index].ReadAt(data,read_offset);
|
||||||
|
|
||||||
|
++read_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void Clear (){data_array[0].Clear();data_array[1].Clear();} ///<清除所有数据
|
||||||
|
virtual void Free (){data_array[0].Free();data_array[1].Free();} ///<清除所有数据并释放内存
|
||||||
};//template<typename T> class Queue
|
};//template<typename T> class Queue
|
||||||
|
|
||||||
template<typename T> class QueueObject:public Queue<T *> ///堆栈对象
|
template<typename T> class ObjectQueue:public Queue<T *> ///对象队列
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void DeleteObject(T *obj){if(obj)delete obj;}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using Queue<T *>::Queue;
|
using Queue<T *>::Queue;
|
||||||
virtual ~QueueObject(){Clear();}
|
virtual ~ObjectQueue(){Free();}
|
||||||
|
|
||||||
void Clear();
|
virtual bool Push(T *obj)
|
||||||
|
|
||||||
T *operator[](int n)const
|
|
||||||
{
|
{
|
||||||
if(n<0||n>=Queue<T *>::cur_count)return(nullptr);
|
if(!obj)return(false);
|
||||||
|
|
||||||
return Queue<T *>::items[n];
|
return Queue<T *>::Push(obj);
|
||||||
}
|
}
|
||||||
};//template<typename T> class QueueObject
|
|
||||||
|
virtual T *Pop()
|
||||||
|
{
|
||||||
|
T *obj;
|
||||||
|
|
||||||
|
if(!Queue<T *>::Pop(obj))
|
||||||
|
return(nullptr);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
for(T *obj:data_array[0])
|
||||||
|
DeleteObject(obj);
|
||||||
|
|
||||||
|
for(T *obj:data_array[1])
|
||||||
|
DeleteObject(obj);
|
||||||
|
|
||||||
|
data_array[0].Clear();
|
||||||
|
data_array[1].Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free()
|
||||||
|
{
|
||||||
|
ObjectQueue<T>::Clear();
|
||||||
|
|
||||||
|
data_array[0].Free();
|
||||||
|
data_array[1].Free();
|
||||||
|
}
|
||||||
|
};//template<typename T> class ObjectQueue
|
||||||
}//namespace hgl
|
}//namespace hgl
|
||||||
#include<hgl/type/Queue.cpp>
|
|
||||||
#endif//HGL_QUEUE_INCLUDE
|
|
||||||
|
@@ -5,8 +5,6 @@ namespace hgl
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Stack模板类用于保存一个先进后出、后进先出的数据堆栈
|
* Stack模板类用于保存一个先进后出、后进先出的数据堆栈
|
||||||
*
|
|
||||||
* 注:这个类还在测试中,请不要修改这个类的源代码,如有修改意见,请致电作者。
|
|
||||||
*/
|
*/
|
||||||
template<typename T> class Stack ///堆栈顺序数据访问类
|
template<typename T> class Stack ///堆栈顺序数据访问类
|
||||||
{
|
{
|
||||||
@@ -75,6 +73,8 @@ namespace hgl
|
|||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
virtual void Clear (){data_array.Clear();} ///<清除所有数据
|
virtual void Clear (){data_array.Clear();} ///<清除所有数据
|
||||||
virtual void Free (){data_array.Free();} ///<清除所有数据并释放内存
|
virtual void Free (){data_array.Free();} ///<清除所有数据并释放内存
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user