List删除不合理设计的[]操作符重载
This commit is contained in:
parent
52fb2eed7e
commit
5c3caf4111
@ -1,4 +1,4 @@
|
||||
#ifndef HGL_MACRO_INCLUDE
|
||||
#ifndef HGL_MACRO_INCLUDE
|
||||
#define HGL_MACRO_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
@ -50,7 +50,7 @@ namespace hgl
|
||||
if(name[free_object_array_number]) \
|
||||
delete name[free_object_array_number]; \
|
||||
\
|
||||
cm_free(name); \
|
||||
hgl_free(name); \
|
||||
name=nullptr; \
|
||||
} \
|
||||
}
|
||||
@ -62,7 +62,7 @@ namespace hgl
|
||||
|
||||
#define SAFE_FREE(name) { \
|
||||
if(name) \
|
||||
cm_free(name); \
|
||||
hgl_free(name); \
|
||||
}
|
||||
|
||||
#define SAFE_RECREATE(name,code) { \
|
||||
|
@ -198,7 +198,7 @@ namespace hgl
|
||||
template<typename T> T ToBigEndian(T value){return value;}
|
||||
|
||||
template<typename T> inline void ToBigEndian(T *value,const int64 count){}
|
||||
template<typename D,typename S> inline void ToBigEndian(D *dst,const S *src,const int64 count){cm_cpy(dst,src,count);}
|
||||
template<typename D,typename S> inline void ToBigEndian(D *dst,const S *src,const int64 count){hgl_cpy(dst,src,count);}
|
||||
|
||||
template<typename T> T ToLittleEndian(T value){return EndianSwap(value);}
|
||||
|
||||
@ -223,7 +223,7 @@ namespace hgl
|
||||
template<typename T> T ToLittleEndian(T value){return value;}
|
||||
|
||||
template<typename T> inline void ToLittleEndian(T *,const int64){}
|
||||
template<typename D,typename S> inline void ToLittleEndian(D *dst,const S *src,const int64 count){cm_cpy(dst,src,count);}
|
||||
template<typename D,typename S> inline void ToLittleEndian(D *dst,const S *src,const int64 count){hgl_cpy(dst,src,count);}
|
||||
|
||||
#endif//HGL_BIG_ENDIAN
|
||||
|
||||
|
195
inc/hgl/render/Shader.h
Normal file
195
inc/hgl/render/Shader.h
Normal file
@ -0,0 +1,195 @@
|
||||
#ifndef HGL_SHADER_INCLUDE
|
||||
#define HGL_SHADER_INCLUDE
|
||||
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/type/Map.h>
|
||||
#include<hgl/algorithm/Math.h>
|
||||
// #include<hgl/graph/UBO.h>
|
||||
// #include<hgl/graph/SSBO.h>
|
||||
namespace hgl
|
||||
{
|
||||
constexpr uint HGL_MAX_SHADER_NAME_LENGTH=128; ///<最大Shader名称长度
|
||||
|
||||
/**
|
||||
* 着色程序类型枚举
|
||||
*/
|
||||
enum ShaderType ///着色程序类型
|
||||
{
|
||||
stVertex=0, ///<顶点着色程序
|
||||
stTessControl, ///<镶嵌控制着色程序(需OpenGL 4.0或ARB_tessellation_shader)
|
||||
stTessEval, ///<镶嵌评估着色程序(需OpenGL 4.0或ARB_tessellation_shader)
|
||||
stGeometry, ///<几何着色程序
|
||||
stFragment, ///<片断着色程序
|
||||
stCompute, ///<计算着色程序(需OpenGL 4.3或ARB_compute_shader)
|
||||
|
||||
stEnd
|
||||
};//enum ShaderType
|
||||
|
||||
extern const char ShaderTypeName[ShaderType::stEnd][32]; ///<着色程序名称
|
||||
|
||||
/**
|
||||
* 着色器程序
|
||||
*/
|
||||
class Shader
|
||||
{
|
||||
uint program;
|
||||
|
||||
uint shader_index[ShaderType::stEnd];
|
||||
|
||||
private:
|
||||
|
||||
bool Link(); ///<连接使用当前着色程序
|
||||
|
||||
protected:
|
||||
|
||||
Map<UTF8String,int> attrib_location;
|
||||
Map<UTF8String,int> uniform_location;
|
||||
|
||||
// Map<UTF8String,int> uniform_block_index;
|
||||
// MapObject<UTF8String,UBO> uniform_block_object;
|
||||
//
|
||||
// Map<UTF8String,int> ssbo_index;
|
||||
// MapObject<UTF8String,SSBO> ssbo_object;
|
||||
|
||||
int _GetAttribLocation(const char *); ///<取得指定属性地址
|
||||
int _GetUniformLocation(const char *); ///<取得一个变量的地址
|
||||
// int _GetUniformBlockIndex(const char *); ///<取得一个只读数据块的地址索引
|
||||
// int _GetShaderStorageIndex(const char *); ///<取得一个数据存储区的地址索引
|
||||
|
||||
public:
|
||||
|
||||
Shader(){program=0;hgl_zero(shader_index,ShaderType::stEnd);}
|
||||
~Shader(){Clear();}
|
||||
|
||||
void Clear(); ///<清除着色程序
|
||||
|
||||
bool AddShader (const int shader_type,const char *); ///<增加一个着色程序
|
||||
|
||||
bool AddVertexShader (const char *code){return AddShader(ShaderType::stVertex,code);} ///<增加一个顶点着色程序
|
||||
bool AddGeometryShader (const char *code){return AddShader(ShaderType::stGeometry,code);} ///<增加一个几何着色程序
|
||||
bool AddFragmentShader (const char *code){return AddShader(ShaderType::stFragment,code);} ///<增加一个片断着色程序
|
||||
bool AddComputeShader (const char *code){return AddShader(ShaderType::stFragment,code);} ///<增加一个计算着色程序
|
||||
|
||||
bool AddTessShader (const char *tess_control_shader,const char *tess_evaluation_shader) ///<增加一个镶嵌着色程序
|
||||
{
|
||||
if(!AddShader(ShaderType::stTessControl,tess_control_shader ))return(false);
|
||||
if(!AddShader(ShaderType::stTessEval, tess_evaluation_shader ))return(false);
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Build(); ///<构建当前添加的着色程序
|
||||
|
||||
bool Use(); ///<使用当前着色程序
|
||||
|
||||
int GetAttribLocation(const char *); ///<取得指定属性地址
|
||||
int GetUniformLocation(const char *); ///<取得一个变量的地址
|
||||
// int GetUniformBlockIndex(const char *); ///<取得一个只读数据块索引
|
||||
// int GetShaderStorageIndex(const char *); ///<取得一个数据存储区索引
|
||||
|
||||
//bool SetAttrib1f(int,float);
|
||||
//bool GetAttrib1f(int,float &);
|
||||
|
||||
public: //设置一致变量用函数
|
||||
|
||||
bool SetUniform1f(int,float);
|
||||
bool SetUniform2f(int,float,float);
|
||||
bool SetUniform3f(int,float,float,float);
|
||||
bool SetUniform4f(int,float,float,float,float);
|
||||
|
||||
bool SetUniform1i(int,int);
|
||||
bool SetUniform2i(int,int,int);
|
||||
bool SetUniform3i(int,int,int,int);
|
||||
bool SetUniform4i(int,int,int,int,int);
|
||||
|
||||
bool SetUniform1ui(int,unsigned int);
|
||||
bool SetUniform2ui(int,unsigned int,unsigned int);
|
||||
bool SetUniform3ui(int,unsigned int,unsigned int,unsigned int);
|
||||
bool SetUniform4ui(int,unsigned int,unsigned int,unsigned int,unsigned int);
|
||||
|
||||
bool SetUniform1fv(int,const float *);
|
||||
bool SetUniform2fv(int,const float *);
|
||||
bool SetUniform3fv(int,const float *);
|
||||
bool SetUniform4fv(int,const float *);
|
||||
|
||||
bool SetUniform2fv(int index,const Vector2f &v){return SetUniform2fv(index,(const float *)&v);}
|
||||
bool SetUniform3fv(int index,const Vector3f &v){return SetUniform3fv(index,(const float *)&v);}
|
||||
bool SetUniform4fv(int index,const Vector4f &v){return SetUniform4fv(index,(const float *)&v);}
|
||||
|
||||
bool SetUniform1iv(int,const int *);
|
||||
bool SetUniform2iv(int,const int *);
|
||||
bool SetUniform3iv(int,const int *);
|
||||
bool SetUniform4iv(int,const int *);
|
||||
|
||||
bool SetUniform1uiv(int,const unsigned int *);
|
||||
bool SetUniform2uiv(int,const unsigned int *);
|
||||
bool SetUniform3uiv(int,const unsigned int *);
|
||||
bool SetUniform4uiv(int,const unsigned int *);
|
||||
|
||||
bool SetUniformMatrix2fv(int,const float *);
|
||||
bool SetUniformMatrix3fv(int,const float *);
|
||||
bool SetUniformMatrix4fv(int,const float *);
|
||||
|
||||
bool SetUniformMatrix2x3fv(int,const float *);
|
||||
bool SetUniformMatrix3x2fv(int,const float *);
|
||||
bool SetUniformMatrix2x4fv(int,const float *);
|
||||
bool SetUniformMatrix4x2fv(int,const float *);
|
||||
bool SetUniformMatrix3x4fv(int,const float *);
|
||||
bool SetUniformMatrix4x3fv(int,const float *);
|
||||
|
||||
public:
|
||||
|
||||
bool SetUniform1f(const char *,float);
|
||||
bool SetUniform2f(const char *,float,float);
|
||||
bool SetUniform3f(const char *,float,float,float);
|
||||
bool SetUniform4f(const char *,float,float,float,float);
|
||||
|
||||
bool SetUniform1i(const char *,int);
|
||||
bool SetUniform2i(const char *,int,int);
|
||||
bool SetUniform3i(const char *,int,int,int);
|
||||
bool SetUniform4i(const char *,int,int,int,int);
|
||||
|
||||
bool SetUniform1ui(const char *,unsigned int);
|
||||
bool SetUniform2ui(const char *,unsigned int,unsigned int);
|
||||
bool SetUniform3ui(const char *,unsigned int,unsigned int,unsigned int);
|
||||
bool SetUniform4ui(const char *,unsigned int,unsigned int,unsigned int,unsigned int);
|
||||
|
||||
bool SetUniform1fv(const char *,const float *);
|
||||
bool SetUniform2fv(const char *,const float *);
|
||||
bool SetUniform3fv(const char *,const float *);
|
||||
bool SetUniform4fv(const char *,const float *);
|
||||
|
||||
bool SetUniform2fv(const char *name,const Vector2f &v){return SetUniform2fv(name,(const float *)&v);}
|
||||
bool SetUniform3fv(const char *name,const Vector3f &v){return SetUniform3fv(name,(const float *)&v);}
|
||||
bool SetUniform4fv(const char *name,const Vector4f &v){return SetUniform4fv(name,(const float *)&v);}
|
||||
|
||||
bool SetUniform1iv(const char *,const int *);
|
||||
bool SetUniform2iv(const char *,const int *);
|
||||
bool SetUniform3iv(const char *,const int *);
|
||||
bool SetUniform4iv(const char *,const int *);
|
||||
|
||||
bool SetUniform1uiv(const char *,const unsigned int *);
|
||||
bool SetUniform2uiv(const char *,const unsigned int *);
|
||||
bool SetUniform3uiv(const char *,const unsigned int *);
|
||||
bool SetUniform4uiv(const char *,const unsigned int *);
|
||||
|
||||
bool SetUniformMatrix2fv(const char *,const float *);
|
||||
bool SetUniformMatrix3fv(const char *,const float *);
|
||||
bool SetUniformMatrix4fv(const char *,const float *);
|
||||
|
||||
bool SetUniformMatrix3fv(const char *name,const Matrix3f &m){return SetUniformMatrix3fv(name,(const float *)&m);}
|
||||
bool SetUniformMatrix4fv(const char *name,const Matrix4f &m){return SetUniformMatrix4fv(name,(const float *)&m);}
|
||||
|
||||
bool SetUniformMatrix2x3fv(const char *,const float *);
|
||||
bool SetUniformMatrix3x2fv(const char *,const float *);
|
||||
bool SetUniformMatrix2x4fv(const char *,const float *);
|
||||
bool SetUniformMatrix4x2fv(const char *,const float *);
|
||||
bool SetUniformMatrix3x4fv(const char *,const float *);
|
||||
bool SetUniformMatrix4x3fv(const char *,const float *);
|
||||
|
||||
// public: //Uniform Block
|
||||
//
|
||||
// UBO *GetUniformBlock(const char *,uint=HGL_DYNAMIC_DRAW);
|
||||
// SSBO *GetShaderStorage(const char *,uint=HGL_DYNAMIC_DRAW);
|
||||
};//class Shader
|
||||
}//namespace hgl
|
||||
#endif//HGL_SHADER_INCLUDE
|
@ -1,4 +1,4 @@
|
||||
#ifndef HGL_THREAD_MUTEX_INCLUDE
|
||||
#ifndef HGL_THREAD_MUTEX_INCLUDE
|
||||
#define HGL_THREAD_MUTEX_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
@ -11,14 +11,14 @@ namespace hgl
|
||||
*/
|
||||
class ThreadMutex ///排斥访问类(仅当前进程)
|
||||
{
|
||||
cm_thread_mutex ptr;
|
||||
hgl_thread_mutex ptr;
|
||||
|
||||
public:
|
||||
|
||||
ThreadMutex(); ///<本类构造函数
|
||||
virtual ~ThreadMutex(); ///<本类析构函数
|
||||
|
||||
cm_thread_mutex *GetThreadMutex(){return &ptr;}
|
||||
hgl_thread_mutex *GetThreadMutex(){return &ptr;}
|
||||
|
||||
virtual void Lock(); ///<取得的控制权(如果对象处于排斥状态,则等待)
|
||||
virtual bool TryLock(); ///<尝试取得控制权
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define HGL_LIST_CPP
|
||||
|
||||
#include<string.h>
|
||||
#include<hgl/LogInfo.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// 代码中的部分memcpy可替换为memmove,但这样会引起CodeGuard/Valgrind之类的内存调试器报错
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -11,7 +12,10 @@ namespace hgl
|
||||
bool List<T>::Get(int index,T &ti)const
|
||||
{
|
||||
if(!items||index<0||index>=count)
|
||||
{
|
||||
LOG_ERROR(OS_TEXT("List<>::Get(index=")+OSString(index)+OS_TEXT(") error,DataCount=")+OSString(count));
|
||||
return(false);
|
||||
}
|
||||
|
||||
memcpy(&ti,items+index,sizeof(T));
|
||||
return(true);
|
||||
@ -48,14 +52,34 @@ namespace hgl
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool List<T>::Set(int index,const T &val)
|
||||
T &List<T>::operator[](int index)const ///<操作符重载取得指定索引处的数据
|
||||
{
|
||||
if(!items||index<0||index>=count)
|
||||
return(false);
|
||||
if(!items||index<0||index>=count)
|
||||
{
|
||||
static T *null_ptr=nullptr;
|
||||
|
||||
memcpy(items+index,&val,sizeof(T));//items[index]=val;
|
||||
LOG_ERROR(OS_TEXT("List<>::operator(index=")+OSString(index)+OS_TEXT(") error,DataCount=")+OSString(count));
|
||||
|
||||
return(true);
|
||||
return(*null_ptr);
|
||||
}
|
||||
|
||||
return items[index];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void List<T>::Set(int index,const T &val)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(!items||index<0||index>=count)
|
||||
{
|
||||
LOG_ERROR(OS_TEXT("List<>::Set(index=")+OSString(index)+OS_TEXT(",T &) error,DataCount=")+OSString(count));
|
||||
}
|
||||
else
|
||||
memcpy(items+index,&val,sizeof(T));//items[index]=val;
|
||||
#else
|
||||
if(index>=0&&index<count)
|
||||
memcpy(items+index,&val,sizeof(T));//items[index]=val;
|
||||
#endif//_DEBUG
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,18 +230,18 @@ namespace hgl
|
||||
template<typename T>
|
||||
void List<T>::DeleteClear()
|
||||
{
|
||||
if(count<=0)
|
||||
return;
|
||||
if(count)
|
||||
{
|
||||
T *p=items;
|
||||
|
||||
T *p=items;
|
||||
while(count--)
|
||||
{
|
||||
delete *p;
|
||||
++p;
|
||||
}
|
||||
|
||||
while(count--)
|
||||
{
|
||||
delete *p;
|
||||
++p;
|
||||
}
|
||||
|
||||
count=0;
|
||||
count=0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,15 +270,17 @@ namespace hgl
|
||||
template<typename T>
|
||||
bool List<T>::Delete(int index)
|
||||
{
|
||||
if(!items||count<=0||index<0||index>=count)
|
||||
return(false);
|
||||
if(count>0&&index>=0&&index<count)
|
||||
{
|
||||
--count;
|
||||
|
||||
--count;
|
||||
if(index<count)
|
||||
memcpy(items+index,items+count,sizeof(T)); //将最后一个数据移到当前位置
|
||||
|
||||
if(index<count)
|
||||
memcpy(items+index,items+count,sizeof(T)); //将最后一个数据移到当前位置
|
||||
|
||||
return(true);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -265,15 +291,17 @@ namespace hgl
|
||||
template<typename T>
|
||||
bool List<T>::DeleteMove(int index)
|
||||
{
|
||||
if(!items||count<=0||index<0||index>=count)
|
||||
return(false);
|
||||
if(count>0&&index>=0&&index<count)
|
||||
{
|
||||
--count;
|
||||
|
||||
--count;
|
||||
if(index<count)
|
||||
memmove(items+index,items+index+1,(count-index)*sizeof(T));
|
||||
|
||||
if(index<count)
|
||||
memmove(items+index,items+index+1,(count-index)*sizeof(T));
|
||||
|
||||
return(true);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,13 +342,15 @@ namespace hgl
|
||||
template<typename T>
|
||||
bool List<T>::DeleteByValue(const T &dat)
|
||||
{
|
||||
const int index=Find(dat);
|
||||
int index=Find(dat);
|
||||
|
||||
if(index==-1)
|
||||
return(false);
|
||||
|
||||
Delete(index);
|
||||
return(true);
|
||||
if(index!=-1)
|
||||
{
|
||||
Delete(index);
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef HGL_LIST_INCLUDE
|
||||
#define HGL_LIST_INCLUDE
|
||||
|
||||
#include<hgl/LogInfo.h>
|
||||
#include<stdlib.h>
|
||||
#include<initializer_list>
|
||||
|
||||
@ -63,12 +64,13 @@ namespace hgl
|
||||
|
||||
virtual void operator += (const T &obj){Add(obj);} ///<操作符重载添加一个数据
|
||||
virtual void operator << (const T &obj){Add(obj);} ///<操作符重载添加一个数据
|
||||
virtual void operator -= (const T &obj){DeleteByValue(obj);} ///<操作符重载删除一个数据
|
||||
virtual void operator -= (const T &obj){DeleteByValue(obj);} ///<操作符重载删除一个数据
|
||||
|
||||
bool Get(int,T &)const; ///<取得指定索引处的数据
|
||||
bool Set(int,const T &); ///<设置指定索引处的数据
|
||||
void Set(int,const T &); ///<设置指定索引处的数据
|
||||
bool Rand(T &)const; ///<随机取得一个数据
|
||||
|
||||
virtual T &operator[](int n)const; ///<操作符重载取得指定索引处的数据
|
||||
virtual bool Begin(T &)const; ///<取第一个数据
|
||||
virtual bool End(T &)const; ///<取最后一个数据
|
||||
|
||||
|
582
inc/hgl/type/Map.cpp
Normal file
582
inc/hgl/type/Map.cpp
Normal file
@ -0,0 +1,582 @@
|
||||
#ifndef HGL_MAP_CPP
|
||||
#define HGL_MAP_CPP
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 查找数据是否存在
|
||||
* @param flag 数据标识
|
||||
* @return 数据所在索引,-1表示不存在
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
int _Map<F,T,DataPair>::Find(const F &flag)const
|
||||
{
|
||||
int left=0,right=data_list.GetCount()-1; //使用left,right而不使用min,max是为了让代码能够更好的阅读。
|
||||
int mid;
|
||||
|
||||
DataPair **data_array=data_list.GetData();
|
||||
|
||||
while(left<=right)
|
||||
{
|
||||
if(data_array[left ]->left==flag)return(left);
|
||||
if(data_array[right]->left==flag)return(right);
|
||||
|
||||
mid=(right+left)>>1;
|
||||
|
||||
if(data_array[mid]->left==flag)return(mid);
|
||||
|
||||
if(data_array[mid]->left>flag)
|
||||
{
|
||||
++left;
|
||||
right=mid-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
--right;
|
||||
left=mid+1;
|
||||
}
|
||||
}
|
||||
|
||||
// LOG_PROBLEM(OS_TEXT("Map::Find,no result."));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::FindPos(const F &flag,int &pos)const
|
||||
{
|
||||
int left=0,right=data_list.GetCount()-1;
|
||||
int mid;
|
||||
|
||||
DataPair **data_array=data_list.GetData();
|
||||
|
||||
while(left<=right)
|
||||
{
|
||||
if(data_array[left ]->left>flag)
|
||||
{
|
||||
pos=left;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[left ]->left==flag)
|
||||
{
|
||||
pos=left;
|
||||
return(true);
|
||||
}
|
||||
|
||||
if(data_array[right]->left<flag)
|
||||
{
|
||||
pos=right+1;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[right]->left==flag)
|
||||
{
|
||||
pos=right;
|
||||
return(true);
|
||||
}
|
||||
|
||||
mid=(right+left)>>1;
|
||||
|
||||
if(data_array[mid]->left==flag)
|
||||
{
|
||||
pos=mid;
|
||||
return(true);
|
||||
}
|
||||
|
||||
if(data_array[mid]->left>flag)
|
||||
{
|
||||
if(data_array[mid-1]->left<flag)
|
||||
{
|
||||
pos=mid;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[mid-1]->left==flag)
|
||||
{
|
||||
pos=mid-1;
|
||||
return(true);
|
||||
}
|
||||
|
||||
++left;
|
||||
right=mid-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(data_array[mid+1]->left>flag)
|
||||
{
|
||||
pos=mid+1;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[mid+1]->left==flag)
|
||||
{
|
||||
pos=mid+1;
|
||||
return(true);
|
||||
}
|
||||
|
||||
--right;
|
||||
left=mid+1;
|
||||
}
|
||||
}
|
||||
|
||||
// LOG_PROBLEM(OS_TEXT("Map::FindPos,no result."));
|
||||
pos=-1;
|
||||
return(false);
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
int _Map<F,T,DataPair>::FindByValue(const T &data)const
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
DataPair **data_array=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if((*data_array)->right==data)
|
||||
return(i);
|
||||
|
||||
++data_array;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个数据
|
||||
* @param flag 数据标识
|
||||
* @param data 数据
|
||||
* @return 新创建好的数据结构
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
DataPair *_Map<F,T,DataPair>::Add(const F &flag,const T &data)
|
||||
{
|
||||
DataPair *ds=data_pool.Acquire();
|
||||
|
||||
ds->left=flag;
|
||||
ds->right=data;
|
||||
|
||||
int pos;
|
||||
|
||||
if(FindPos(flag,pos))
|
||||
return(nullptr);
|
||||
|
||||
data_list.Insert(pos,ds);
|
||||
|
||||
return(ds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个数据
|
||||
* @param flag 数据标识
|
||||
* @return 创建好的数据
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
T &_Map<F,T,DataPair>::Add(const F &flag)
|
||||
{
|
||||
DataPair *ds=data_pool.Acquire();
|
||||
|
||||
ds->left=flag;
|
||||
|
||||
int pos;
|
||||
|
||||
FindPos(flag,pos);
|
||||
|
||||
data_list.Insert(pos,ds);
|
||||
|
||||
return ds->right;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个数据
|
||||
* @param obj 数据
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::Add(DataPair *obj)
|
||||
{
|
||||
data_list.Insert(FindPos(obj->left),obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引取得数据
|
||||
* @param flag 数据索引
|
||||
* @param data 数据存放处
|
||||
* @return 是否取得成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::Get(const F &flag,T &data) const
|
||||
{
|
||||
int index=Find(flag);
|
||||
|
||||
if(index==-1)return(false);
|
||||
|
||||
data=data_list[index]->right;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据序号取得数据
|
||||
* @param index 序号
|
||||
* @param f 数据索引存放处
|
||||
* @param t 数据存放处
|
||||
* @return 是否取得成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::Get(int index,F &f,T &t) const
|
||||
{
|
||||
if(index<0||index>=data_list.GetCount())return(false);
|
||||
|
||||
DataPair *ds=data_list[index];
|
||||
|
||||
f=ds->left;
|
||||
t=ds->right;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据序号取得索引
|
||||
* @param index 序号
|
||||
* @param f 数据索引存放处
|
||||
* @return 是否取得成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::GetKey(int index,F &f) const
|
||||
{
|
||||
if(index<0||index>=data_list.GetCount())return(false);
|
||||
|
||||
DataPair *ds=data_list[index];
|
||||
|
||||
f=ds->left;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据序号取得数据
|
||||
* @param index 序号
|
||||
* @param t 数据存放处
|
||||
* @return 是否取得成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::GetValue(int index,T &t) const
|
||||
{
|
||||
if(index<0||index>=data_list.GetCount())return(false);
|
||||
|
||||
DataPair *ds=data_list[index];
|
||||
|
||||
if(!ds)return(false);
|
||||
|
||||
t=ds->right;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据序号设置数据
|
||||
* @param index 数据序号
|
||||
* @param t 数据
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::SetValueBySerial(int index,T &t)
|
||||
{
|
||||
if(index<0||index>=data_list.GetCount())return(false);
|
||||
|
||||
data_list[index]->right=t;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定数据从列表中移除同时取得这个数据
|
||||
* @param flag 数据标识
|
||||
* @param data 数据存放位处
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::Delete(const F &flag,T &data)
|
||||
{
|
||||
int index=Find(flag);
|
||||
|
||||
if(index==-1)return(false);
|
||||
|
||||
DataPair *dp=data_list[index];
|
||||
|
||||
data=dp->right;
|
||||
|
||||
data_pool.Release(dp);
|
||||
data_list.DeleteMove(index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引将指定数据从列表中移除
|
||||
* @param flag 索引
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::DeleteByKey(const F &flag)
|
||||
{
|
||||
int index=Find(flag);
|
||||
|
||||
if(index==-1)return(false);
|
||||
|
||||
data_pool.Release(data_list[index]);
|
||||
data_list.DeleteMove(index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据索引将指定数据从列表中批量移除
|
||||
* @param fp 索引列表
|
||||
* @param count 索引数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
int _Map<F,T,DataPair>::DeleteByKey(const F *fp,const int count)
|
||||
{
|
||||
if(!fp||count<=0)return(0);
|
||||
|
||||
int total=0;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
int index=Find(*fp);
|
||||
|
||||
if(index!=-1)
|
||||
{
|
||||
data_pool.Release(data_list[index]);
|
||||
data_list.DeleteMove(index);
|
||||
|
||||
++total;
|
||||
}
|
||||
|
||||
++fp;
|
||||
}
|
||||
|
||||
return(total);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据数据将指定数据从列表中移除
|
||||
* @param data 数据
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::DeleteByValue(const T &data)
|
||||
{
|
||||
int index=FindByValue(data);
|
||||
|
||||
if(index==-1)return(false);
|
||||
|
||||
data_pool.Release(data_list[index]);
|
||||
data_list.DeleteMove(index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据序号将指定数据从列表中移除
|
||||
* @param index 序号
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::DeleteBySerial(int index)
|
||||
{
|
||||
if(index<0
|
||||
||index>=data_list.GetCount())return(false);
|
||||
|
||||
data_pool.Release(data_list[index]);
|
||||
data_list.DeleteMove(index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据序号将指定数据从列表中移除
|
||||
* @param start 起始序号
|
||||
* @param number 数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::DeleteBySerial(int start,int number)
|
||||
{
|
||||
DataPair **dp=data_list.GetData()+start;
|
||||
|
||||
for(int i=0;i<number;i++)
|
||||
{
|
||||
data_pool.Release(*dp);
|
||||
++dp;
|
||||
}
|
||||
|
||||
return data_list.Delete(start,number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新一个数据,如果这个数据不存在,就添加一个新的
|
||||
* @param flag 数据标识
|
||||
* @param data 新的数据内容
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::Update(const F &flag,const T &data)
|
||||
{
|
||||
int result;
|
||||
|
||||
if(FindPos(flag,result))
|
||||
data_list[result]->right=data;
|
||||
else
|
||||
{
|
||||
DataPair *ds=data_pool.Acquire();
|
||||
|
||||
ds->left=flag;
|
||||
ds->right=data;
|
||||
|
||||
data_list.Insert(result,ds);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改数据,这个更改和Set不同,它要求指定标识的数据必须存在,则否就会更改失败
|
||||
* @param flag 数据标识
|
||||
* @param data 新的数据内容
|
||||
* @param return 是否更改成功
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
bool _Map<F,T,DataPair>::Change(const F &flag,const T &data)
|
||||
{
|
||||
int result=Find(flag);
|
||||
|
||||
if(result==-1)
|
||||
return(false);
|
||||
|
||||
data_list[result]->right=data;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有数据
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::Clear()
|
||||
{
|
||||
data_pool.ClearAll();
|
||||
data_list.Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有数据,但不释放内存
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::ClearData()
|
||||
{
|
||||
data_pool.ReleaseAll();
|
||||
data_list.ClearData();
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::operator=(const _Map<F,T,DataPair> &ftd)
|
||||
{
|
||||
Clear();
|
||||
|
||||
data_pool.ClearAll();
|
||||
data_list.ClearData();
|
||||
|
||||
const int count=ftd.data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return;
|
||||
|
||||
IDItem **obj=ftd.data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
IDItem *new_obj=data_pool.Acquire();
|
||||
|
||||
new_obj->left=(*obj)->left;
|
||||
new_obj->right=(*obj)->right;
|
||||
|
||||
data_list.Add(new_obj);
|
||||
|
||||
++obj;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::Enum(void (*enum_func)(const F &,T))
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return;
|
||||
|
||||
IDItem **idp=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
enum_func((*idp)->left,(*idp)->right);
|
||||
|
||||
++idp;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::EnumKey(void (*enum_func)(const F &))const
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return;
|
||||
|
||||
IDItem **idp=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
enum_func((*idp)->left);
|
||||
|
||||
++idp;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::EnumValue(void (*enum_func)(T))
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return;
|
||||
|
||||
IDItem **idp=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
enum_func((*idp)->right);
|
||||
|
||||
++idp;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair>
|
||||
void _Map<F,T,DataPair>::EnumValue(bool (*enum_func)(T))
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return;
|
||||
|
||||
IDItem **idp=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(!enum_func((*idp)->right))
|
||||
return;
|
||||
|
||||
++idp;
|
||||
}
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_MAP_CPP
|
325
inc/hgl/type/Map.h
Normal file
325
inc/hgl/type/Map.h
Normal file
@ -0,0 +1,325 @@
|
||||
#ifndef HGL_MAP_INCLUDE
|
||||
#define HGL_MAP_INCLUDE
|
||||
|
||||
#include<hgl/type/List.h>
|
||||
#include<hgl/type/Pair.h>
|
||||
#include<hgl/type/Pool.h>
|
||||
#include<hgl/LogInfo.h>
|
||||
#include<hgl/thread/RWLock.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 索引数据模板
|
||||
*/
|
||||
template<typename F,typename T,typename DataPair> class _Map
|
||||
{
|
||||
public:
|
||||
|
||||
using IDItem=DataPair;
|
||||
|
||||
protected:
|
||||
|
||||
ObjectPool<IDItem> data_pool;
|
||||
List<IDItem *> data_list;
|
||||
|
||||
using this_calss=_Map<F,T,IDItem>;
|
||||
|
||||
public: //方法
|
||||
|
||||
_Map()=default;
|
||||
virtual ~_Map()=default;
|
||||
|
||||
const int GetCount()const{return data_list.GetCount();} ///<取得数据总量
|
||||
|
||||
IDItem * Add(const F &,const T &); ///<添加一个数据,数果索引已存在,返回nullptr
|
||||
T & Add(const F &); ///<添加一个数据
|
||||
void Add(IDItem *); ///<添加一个数据
|
||||
bool FindPos(const F &,int &)const; ///<查找数据如果插入后,会所在的位置,返回是否存在这个数据
|
||||
int FindPos(const F &flag)const{int pos;FindPos(flag,pos);return(pos);} ///<查找数据如果插入后,会所在的位置
|
||||
int Find(const F &)const; ///<查找数据是否存在,返回-1表示数据不存在
|
||||
int FindByValue(const T &)const; ///<查找数据是否存在,返回-1表示数据不存在
|
||||
bool KeyExist(const F &key)const{return(Find(key)!=-1);} ///<确认这个数据是否存在
|
||||
bool ValueExist(const T &value)const{return(FindByValue(value)!=-1);} ///<确认这个数据是否存在
|
||||
virtual bool Get(const F &,T &)const; ///<取得数据
|
||||
virtual bool Delete(const F &,T &); ///<将指定数据从列表中移除,并获得这个数据
|
||||
virtual bool DeleteByKey(const F &); ///<根据索引将指定数据从列表中移除
|
||||
virtual int DeleteByKey(const F *,const int); ///<根据索引将指定数据从列表中批量移除
|
||||
virtual bool DeleteByValue(const T &); ///<根据数据将指定数据从列表中移除
|
||||
virtual bool DeleteBySerial(int); ///<根据序号将指定数据从列表中移除
|
||||
virtual bool DeleteBySerial(int,int); ///<根据序号将指定数据从列表中移除
|
||||
virtual void Update(const F &,const T &); ///<更新一个数据的内容(如不存在则添加)
|
||||
virtual bool Change(const F &,const T &); ///<更改一个数据的内容(如不存在则更改失效)
|
||||
virtual void Clear(); ///<清除所有数据
|
||||
virtual void ClearData(); ///<清除所有数据,但不释放内存
|
||||
|
||||
List<IDItem *> &GetList(){return data_list;} ///<取得线性列表
|
||||
IDItem ** GetDataList()const{return data_list.GetData();} ///<取得纯数据线性列表
|
||||
|
||||
template<typename IT>
|
||||
int GetKey(IT &il_list) ///<取得所有索引合集
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return count;
|
||||
|
||||
IDItem **idp=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
il_list.Add((*idp)->left);
|
||||
++idp;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename IT>
|
||||
int GetValue(IT &il_list) ///<取得所有数值合集
|
||||
{
|
||||
const int count=data_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
return count;
|
||||
|
||||
IDItem **idp=data_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
il_list.Add((*idp)->right);
|
||||
++idp;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
IDItem *GetItem(int n)const{return data_list[n];} ///<取指定序号的数据
|
||||
bool Get(int,F &,T &)const; ///<取指定序号的数据
|
||||
bool GetKey(int,F &)const; ///<取指定序号的索引
|
||||
bool GetValue(int,T &)const; ///<取指定序号的数据
|
||||
|
||||
bool SetValueBySerial(int,T &); ///<根据序号设置数据
|
||||
|
||||
void operator=(const _Map<F,T,IDItem> &); ///<操作符重载,复制一个列表
|
||||
|
||||
void Enum(void (*enum_func)(const F &,T)); ///<枚举所有数据项
|
||||
void EnumKey(void (*enum_func)(const F &))const; ///<枚举所有索引
|
||||
void EnumValue(void (*enum_func)(T)); ///<枚举所有数值
|
||||
|
||||
void EnumValue(bool (*enum_func)(T)); ///<枚举所有数值
|
||||
};//class _Map
|
||||
|
||||
template<typename F,typename T> class Map:public _Map<F,T,Pair<F,T> >
|
||||
{
|
||||
public:
|
||||
|
||||
Map()=default;
|
||||
virtual ~Map()=default;
|
||||
};//class Map
|
||||
|
||||
template<typename T_ID,typename T_U> T_U *GetObject(Map<T_ID,T_U *> &list,const T_ID &id)
|
||||
{
|
||||
T_U *result;
|
||||
|
||||
if(!list.Get(id,result))
|
||||
return(nullptr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename F,typename T,typename DataPair> class _MapObject:public _Map<F,T *,DataPair>
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef _Map<F,T *,DataPair> SuperClass;
|
||||
|
||||
virtual void DeleteObject(const F &,T *)=0; ///<删除一个数据
|
||||
void DeleteObject(DataPair *ds){DeleteObject(ds->left,ds->right);}
|
||||
void DeleteObject(int index){DeleteObject(this->data_list[index]);}
|
||||
|
||||
public:
|
||||
|
||||
_MapObject()=default;
|
||||
virtual ~_MapObject()
|
||||
{
|
||||
if(SuperClass::GetCount()>0)
|
||||
{
|
||||
//LOG_ERROR(u"这是一个严重的程序设计错误,会产生纯虚函数调用,请在派生类的析构函数中调用Clear函数以清除数据。");
|
||||
LOG_ERROR(OS_TEXT("This is a serious design errors, will produce the pure virtual function call, please call in the destructor of the derived class the <Clear> function to clear the data."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开一个数据
|
||||
* @param flag 要断开的数据标识
|
||||
* @return 是否断开成功
|
||||
*/
|
||||
bool UnlinkByKey(const F &flag)
|
||||
{
|
||||
return UnlinkBySerial(SuperClass::Find(flag));
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开一个数据
|
||||
* @param tp 要断开的数据
|
||||
* @return 是否断开成功
|
||||
*/
|
||||
bool UnlinkByValue(T *tp)
|
||||
{
|
||||
return UnlinkBySerial(this->FindByValue(tp));
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开一个数据关联
|
||||
* @param index 要断开的数据的序列号
|
||||
* @return 是否断开成功
|
||||
*/
|
||||
bool UnlinkBySerial(int index)
|
||||
{
|
||||
if(index<0||index>=this->data_list.GetCount())return(false);
|
||||
|
||||
SuperClass::DeleteBySerial(index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开所有数据关联
|
||||
*/
|
||||
void UnlinkAll()
|
||||
{
|
||||
SuperClass::Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个数据
|
||||
* @param flag 要删除的数据标识
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
bool DeleteByKey(const F &flag)
|
||||
{
|
||||
return DeleteBySerial(SuperClass::Find(flag));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个数据
|
||||
* @param tp 要删除的数据
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
bool DeleteByValue(T *tp)
|
||||
{
|
||||
return DeleteBySerial(this->FindByValue(tp));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个数据
|
||||
* @param index 要删除的数据的序列号
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
bool DeleteBySerial(int index)
|
||||
{
|
||||
if(index<0||index>=this->data_list.GetCount())return(false);
|
||||
|
||||
DeleteObject(index);
|
||||
SuperClass::DeleteBySerial(index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有数据
|
||||
*/
|
||||
void DeleteAll()
|
||||
{
|
||||
int n=this->data_list.GetCount();
|
||||
|
||||
while(n--)
|
||||
DeleteObject(n);
|
||||
|
||||
_Map<F,T *,DataPair>::Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据,如果数据不存在就添加一个新的
|
||||
* @param flag 数据标识
|
||||
* @param data 新的数据内容
|
||||
*/
|
||||
void Update(const F &flag,T *data)
|
||||
{
|
||||
int index=this->Find(flag);
|
||||
|
||||
if(index!=-1)
|
||||
{
|
||||
DeleteObject(index);
|
||||
|
||||
this->data_list[index]->second=data;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Add(flag,data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更改数据,这个更改和Set不同,它要求指定标识的数据必须存在,则否就会更改失败
|
||||
* @param flag 数据标识
|
||||
* @param data 新的数据内容
|
||||
* @param return 是否更改成功
|
||||
*/
|
||||
bool Change(const F &flag,T *data)
|
||||
{
|
||||
int index=this->Find(flag);
|
||||
|
||||
if(index!=-1)
|
||||
{
|
||||
DeleteObject(index);
|
||||
|
||||
this->data_list[index]->second=data;
|
||||
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
void Clear(){DeleteAll();}
|
||||
};//class _MapObject
|
||||
|
||||
template<typename F,typename T,typename DataPair> class CusMapObject:public _MapObject<F,T,DataPair>
|
||||
{
|
||||
protected:
|
||||
|
||||
//virtual T * CreateObject(const F &){return(new T);} ///<创建一个数据
|
||||
virtual void DeleteObject(const F &,T *obj){delete obj;} ///<删除一个数据
|
||||
|
||||
public:
|
||||
|
||||
CusMapObject()=default;
|
||||
virtual ~CusMapObject()
|
||||
{
|
||||
_MapObject<F,T,DataPair>::Clear();
|
||||
}
|
||||
};//class CusMapObject
|
||||
|
||||
template<typename F,typename T> class MapObject:public CusMapObject<F,T,Pair<F,T *> >
|
||||
{
|
||||
public:
|
||||
|
||||
MapObject()=default;
|
||||
virtual ~MapObject()
|
||||
{
|
||||
CusMapObject<F,T,Pair<F,T *> >::Clear();
|
||||
}
|
||||
|
||||
T *operator[](const F &index)const
|
||||
{
|
||||
const int pos=this->Find(index);
|
||||
|
||||
if(pos==-1)return(nullptr);
|
||||
|
||||
return this->data_list[pos]->right;
|
||||
};
|
||||
};//class MapObject
|
||||
}//namespace hgl
|
||||
#include<hgl/type/Map.cpp>
|
||||
#endif//HGL_MAP_INCLUDE
|
82
inc/hgl/type/Pair.h
Normal file
82
inc/hgl/type/Pair.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef HGL_TYPE_PAIR_INCLUDE
|
||||
#define HGL_TYPE_PAIR_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
#include<hgl/CompOperator.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 成对数据模板
|
||||
*/
|
||||
template<typename L,typename R> struct Pair ///成对数据模板
|
||||
{
|
||||
L left;
|
||||
R right;
|
||||
|
||||
using SelfClass=Pair<L,R>;
|
||||
|
||||
public:
|
||||
|
||||
Pair()=default;
|
||||
|
||||
Pair(const L &l,const R &r)
|
||||
{
|
||||
left=l;
|
||||
right=r;
|
||||
}
|
||||
|
||||
Pair(const SelfClass &p)
|
||||
{
|
||||
operator=(p);
|
||||
}
|
||||
|
||||
Pair(const SelfClass *p)
|
||||
{
|
||||
operator=(p);
|
||||
}
|
||||
|
||||
virtual ~Pair()=default;
|
||||
|
||||
SelfClass &operator=(const SelfClass &p)
|
||||
{
|
||||
left=p.left;
|
||||
right=p.right;
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
SelfClass &operator=(const SelfClass *p)
|
||||
{
|
||||
if(!p)return(*this);
|
||||
|
||||
left=p->left;
|
||||
right=p->right;
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
void Swap(Pair<R,L> &p)
|
||||
{
|
||||
p.left=right;
|
||||
p.right=left;
|
||||
}
|
||||
|
||||
//不使用CompOperator是因为某些类型无法做+-处理
|
||||
|
||||
const bool operator == (const SelfClass &p)const
|
||||
{
|
||||
if(this->left!=p.left)return(false);
|
||||
|
||||
return this->right==p.right;
|
||||
}
|
||||
|
||||
const bool operator != (const SelfClass &p)const
|
||||
{
|
||||
if(this->left==p.left)return(false);
|
||||
|
||||
return this->right!=p.right;
|
||||
}
|
||||
};//template<typename L,typename R> struct Pair
|
||||
}//namespace hgl
|
||||
#endif//HGL_TYPE_PAIR_INCLUDE
|
139
inc/hgl/type/Pool.cpp
Normal file
139
inc/hgl/type/Pool.cpp
Normal file
@ -0,0 +1,139 @@
|
||||
#ifndef HGL_POOL_CPP
|
||||
#define HGL_POOL_CPP
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/type/Pool.h>
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T>
|
||||
void Pool<T>::PreMalloc(int num)
|
||||
{
|
||||
if(num<=0)return;
|
||||
|
||||
for(int i=0;i<num;i++)
|
||||
Inactive.Push(Create());
|
||||
|
||||
count+=num;
|
||||
if(count>history_max)
|
||||
history_max=count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Pool<T>::Acquire()
|
||||
{
|
||||
T result;
|
||||
|
||||
if(!Inactive.Pop(result))
|
||||
{
|
||||
result=Create();
|
||||
|
||||
count++;
|
||||
|
||||
if(count>history_max)
|
||||
history_max=count;
|
||||
}
|
||||
|
||||
Active.Add(result);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::Append(T value)
|
||||
{
|
||||
T result;
|
||||
|
||||
if(!Inactive.Pop(result))
|
||||
{
|
||||
count++;
|
||||
|
||||
if(count>history_max)
|
||||
history_max=count;
|
||||
}
|
||||
|
||||
Active.Add(result);
|
||||
|
||||
result=value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Pool<T>::Release(T value)
|
||||
{
|
||||
int index=Active.Find(value);
|
||||
|
||||
if(index!=-1)
|
||||
{
|
||||
Active.Delete(index);
|
||||
|
||||
Inactive.Push(value);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Pool<T>::Release(T *vl,int count)
|
||||
{
|
||||
int total=0;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(Release(*vl))
|
||||
++total;
|
||||
|
||||
++vl;
|
||||
}
|
||||
|
||||
return(total);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Pool<T>::ReleaseAll()
|
||||
{
|
||||
int count=Active.GetCount();
|
||||
T *p=Active.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
Inactive.Push(*p++);
|
||||
|
||||
Active.ClearData();
|
||||
return(count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::ClearInactive()
|
||||
{
|
||||
T result;
|
||||
|
||||
count-=Inactive.GetCount();
|
||||
|
||||
while(Inactive.Pop(result))
|
||||
Clear(result);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Pool<T>::ClearAll()
|
||||
{
|
||||
{ //不能直接调ClearInactive
|
||||
T result;
|
||||
|
||||
count-=Inactive.GetCount();
|
||||
|
||||
while(Inactive.Pop(result))
|
||||
Clear(result);
|
||||
}
|
||||
|
||||
{
|
||||
int n=Active.GetCount();
|
||||
while(n--)
|
||||
Clear(Active[n]);
|
||||
|
||||
Active.Clear();
|
||||
}
|
||||
|
||||
count=0;
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_POOL_CPP
|
262
inc/hgl/type/Pool.h
Normal file
262
inc/hgl/type/Pool.h
Normal file
@ -0,0 +1,262 @@
|
||||
#ifndef HGL_POOL_INCLUDE
|
||||
#define HGL_POOL_INCLUDE
|
||||
|
||||
#include<hgl/type/List.h>
|
||||
#include<hgl/type/Queue.h>
|
||||
#include<hgl/thread/RWLock.h>
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/type/Set.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 数据池模板用于管于两个队列,一个在用的,一个空闲的
|
||||
*/
|
||||
template<typename T> class Pool ///数据池
|
||||
{
|
||||
protected:
|
||||
|
||||
List<T> Active;
|
||||
Queue<T> Inactive;
|
||||
|
||||
int count;
|
||||
int history_max;
|
||||
|
||||
protected:
|
||||
|
||||
virtual T Create()=0; ///<创建数据
|
||||
virtual void Clear(T)=0; ///<清除数据
|
||||
|
||||
public: //属性
|
||||
|
||||
virtual int GetActiveCount() const{return Active.GetCount();} ///<取得活动数据数量
|
||||
virtual int GetInactiveCount() const{return Inactive.GetCount();} ///<取得非活动数据数量
|
||||
virtual int GetHistoryMaxCount()const{return history_max;} ///<取得历史性最大数据数量
|
||||
|
||||
public:
|
||||
|
||||
Pool(){count=0;history_max=0;}
|
||||
virtual ~Pool()=default;
|
||||
|
||||
virtual void PreMalloc(int); ///<预分配空间
|
||||
|
||||
virtual T Acquire(); ///<申请一个数据
|
||||
virtual void Append(T); ///<添加一个数据
|
||||
virtual bool Release(T); ///<释放一个数据
|
||||
virtual int Release(T *,int); ///<释放一批数据
|
||||
virtual int ReleaseAll(); ///<释放所有数据
|
||||
|
||||
virtual void ClearInactive(); ///<清除所有空闲的
|
||||
virtual void ClearAll(); ///<清除所有的
|
||||
|
||||
virtual T operator[](int n){return Active[n];}
|
||||
};//template<typename T> class Pool
|
||||
|
||||
template<typename T> class MTPool:public Pool<T> ///多线程数据池
|
||||
{
|
||||
RWLock lock;
|
||||
|
||||
protected:
|
||||
|
||||
virtual T Create()=0; ///<创建数据
|
||||
virtual void Clear(T)=0; ///<清除数据
|
||||
|
||||
public:
|
||||
|
||||
virtual int GetActiveCount() {OnlyReadLock rl(lock);return Pool<T>::Active.GetCount(); }
|
||||
virtual int GetInactiveCount() {OnlyReadLock rl(lock);return Pool<T>::Inactive.GetCount(); }
|
||||
virtual int GetHistoryMaxCount(){OnlyReadLock rl(lock);return Pool<T>::history_max; }
|
||||
|
||||
public:
|
||||
|
||||
virtual ~MTPool()=default;
|
||||
|
||||
virtual T *ReadLock(int &c) ///<读列表锁定(用于访问整个列表)
|
||||
{
|
||||
lock.ReadLock();
|
||||
|
||||
c=Pool<T>::GetActiveCount();
|
||||
return(Pool<T>::Active.GetData());
|
||||
}
|
||||
|
||||
virtual T *WriteLock(int &c) ///<写列表锁定(用于访问整个列表)
|
||||
{
|
||||
lock.WriteLock();
|
||||
|
||||
c=Pool<T>::GetActiveCount();
|
||||
return(Pool<T>::Active.GetData());
|
||||
}
|
||||
|
||||
virtual T *TryReadLock(int &c) ///<尝试读列表锁定(用于访问整个列表)
|
||||
{
|
||||
if(!lock.TryReadLock())
|
||||
return(nullptr);
|
||||
|
||||
c=Pool<T>::GetActiveCount();
|
||||
return(Pool<T>::Active.GetData());
|
||||
}
|
||||
|
||||
virtual T *TryWriteLock(int &c) ///<尝试写列表锁定(用于访问整个列表)
|
||||
{
|
||||
if(!lock.TryWriteLock())
|
||||
return(nullptr);
|
||||
|
||||
c=Pool<T>::GetActiveCount();
|
||||
return(Pool<T>::Active.GetData());
|
||||
}
|
||||
|
||||
virtual void ReadLock(){lock.ReadLock();}
|
||||
virtual void WriteLock(){lock.WriteLock();}
|
||||
virtual bool TryReadLock(){return lock.TryReadLock();}
|
||||
virtual bool TryWriteLock(){return lock.TryWriteLock();}
|
||||
|
||||
virtual void ReadUnlock(){lock.ReadUnlock();} ///<读访问解锁(用于访问整个列表)
|
||||
virtual void WriteUnlock(){lock.WriteUnlock();} ///<写访问解锁(用于访问整个列表)
|
||||
|
||||
virtual T SafeAcquire() ///<安全申请一个数据
|
||||
{
|
||||
T tmp;
|
||||
|
||||
lock.WriteLock();
|
||||
tmp=Pool<T>::Acquire();
|
||||
lock.WriteUnlock();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
virtual void SafeAppend(T tmp) ///<安全添加一个数据
|
||||
{
|
||||
lock.WriteLock();
|
||||
Pool<T>::Append(tmp);
|
||||
lock.WriteUnlock();
|
||||
}
|
||||
|
||||
virtual bool SafeRelease(T tmp) ///<安全释放一个数据
|
||||
{
|
||||
bool result;
|
||||
|
||||
lock.WriteLock();
|
||||
result=Pool<T>::Release(tmp);
|
||||
lock.WriteUnlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual int SafeRelease(T *tmp,int num) ///<安全释放一批数据
|
||||
{
|
||||
int result;
|
||||
|
||||
lock.WriteLock();
|
||||
result=Pool<T>::Release(tmp,num);
|
||||
lock.WriteUnlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual int SafeReleaseAll() ///<安全释放所有数据
|
||||
{
|
||||
int result;
|
||||
|
||||
lock.WriteLock();
|
||||
result=Pool<T>::ReleaseAll();
|
||||
lock.WriteUnlock();
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
virtual void SafeClearInactive() ///<安全清除所有空闲数据
|
||||
{
|
||||
lock.WriteLock();
|
||||
Pool<T>::ClearInactive();
|
||||
lock.WriteUnlock();
|
||||
}
|
||||
|
||||
virtual void SafeClearAll() ///<安全清除所有的
|
||||
{
|
||||
lock.WriteLock();
|
||||
Pool<T>::ClearAll();
|
||||
lock.WriteUnlock();
|
||||
}
|
||||
};//template<typename T> class MTPool
|
||||
|
||||
template<typename T> class _ObjectPool:public Pool<T *> ///对象池
|
||||
{
|
||||
virtual T *Create()=0;
|
||||
|
||||
virtual void Clear(T *obj) { if(obj)delete obj; }
|
||||
|
||||
public:
|
||||
|
||||
using Pool<T *>::Pool;
|
||||
virtual ~_ObjectPool(){Pool<T *>::ClearAll();}
|
||||
};//template<typename T> class _ObjectPool
|
||||
|
||||
template<typename T> class ObjectPool:public _ObjectPool<T> ///对象池
|
||||
{
|
||||
virtual T *Create()override{return(new T());}
|
||||
|
||||
public:
|
||||
|
||||
using _ObjectPool<T>::_ObjectPool;
|
||||
virtual ~ObjectPool(){_ObjectPool<T>::ClearAll();}
|
||||
};//template<typename T> class ObjectPool
|
||||
|
||||
template<typename T> class _MTObjectPool:public MTPool<T *> ///多线程对象池
|
||||
{
|
||||
virtual T *Create() override=0;
|
||||
|
||||
virtual void Clear(T *obj) override { if(obj)delete obj; }
|
||||
|
||||
public:
|
||||
|
||||
using MTPool<T *>::MTPool;
|
||||
virtual ~_MTObjectPool(){MTPool<T *>::ClearAll();}
|
||||
};//template<typename T> class MTObjectPool
|
||||
|
||||
template<typename T> class MTObjectPool:public _MTObjectPool<T> ///多线程对象池
|
||||
{
|
||||
virtual T *Create() override {return(new T());}
|
||||
|
||||
virtual void Clear(T *obj) override { if(obj)delete obj; }
|
||||
|
||||
public:
|
||||
|
||||
using _MTObjectPool<T>::_MTObjectPool;
|
||||
virtual ~MTObjectPool(){_MTObjectPool<T>::ClearAll();}
|
||||
};//template<typename T> class MTObjectPool
|
||||
|
||||
template<typename T> class MemBlockPool:public Pool<T *> ///内存块池
|
||||
{
|
||||
int memblock_size;
|
||||
|
||||
T *Create() { return(new T[memblock_size]); }
|
||||
|
||||
void Clear(T *obj) { if(obj)delete[] obj; }
|
||||
|
||||
public:
|
||||
|
||||
MemBlockPool(int size){SetSize(size);}
|
||||
virtual ~MemBlockPool(){Pool<T *>::ClearAll();}
|
||||
|
||||
void SetSize(int size){memblock_size=size;}
|
||||
int GetSize(){return memblock_size;}
|
||||
};//template<typename T> class MemBlockPool
|
||||
|
||||
template<typename T> class MTMemBlockPool:public MTPool<T *> ///多线程内存块池
|
||||
{
|
||||
int memblock_size;
|
||||
|
||||
T *Create() { return(new T[memblock_size]); }
|
||||
|
||||
void Clear(T *obj) { if(obj)delete[] obj; }
|
||||
|
||||
public:
|
||||
|
||||
MTMemBlockPool(int size){SetSize(size);}
|
||||
virtual ~MTMemBlockPool(){MTPool<T *>::ClearAll();}
|
||||
|
||||
void SetSize(int size){memblock_size=size;}
|
||||
int GetSize(){return memblock_size;}
|
||||
};//template<typename T> class MTMemBlockPool
|
||||
}//namespace hgl
|
||||
#include<hgl/type/Pool.cpp>
|
||||
#endif//HGL_POOL_INCLUDE
|
239
inc/hgl/type/Queue.cpp
Normal file
239
inc/hgl/type/Queue.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
#ifndef HGL_QUEUE_CPP
|
||||
#define HGL_QUEUE_CPP
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 本类构造函数
|
||||
* @param m 如果m的值不为0,则表示使用固定的队列大小。固定大小的队列会在一开始即分配好内存。
|
||||
*/
|
||||
template<typename T>
|
||||
Queue<T>::Queue(int m)
|
||||
{
|
||||
count=0;
|
||||
|
||||
if(m)
|
||||
{
|
||||
max_count=m;
|
||||
|
||||
items=hgl_aligned_malloc<T>(max_count);
|
||||
}
|
||||
else max_count=0;
|
||||
|
||||
mem_count=max_count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Queue<T>::~Queue()
|
||||
{
|
||||
if(count||max_count)hgl_free(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改队列的最大值
|
||||
*/
|
||||
template<typename T>
|
||||
void Queue<T>::SetMax(int m)
|
||||
{
|
||||
if(max_count||(!max_count&&count))
|
||||
items=(T *)hgl_realloc(items,m*sizeof(T));
|
||||
else
|
||||
items=hgl_aligned_malloc<T>(m);
|
||||
|
||||
max_count=m;
|
||||
mem_count=m;
|
||||
|
||||
if(count>=max_count)count=max_count-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除队列中的所有数据
|
||||
*/
|
||||
template<typename T>
|
||||
void Queue<T>::Clear()
|
||||
{
|
||||
if(max_count==0)
|
||||
if(count)
|
||||
{
|
||||
hgl_free(items);
|
||||
mem_count=0;
|
||||
}
|
||||
|
||||
count=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除队列中的所有数据,但不释放内存
|
||||
*/
|
||||
template<typename T>
|
||||
void Queue<T>::ClearData()
|
||||
{
|
||||
count=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问队列中的一个数据,但不清除它
|
||||
* @param t 取出的数据保存地
|
||||
* @return 是否成功取出数据
|
||||
*/
|
||||
template<typename T>
|
||||
bool Queue<T>::Peek(T &t)
|
||||
{
|
||||
if(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>=count)
|
||||
return(false);
|
||||
|
||||
count--;
|
||||
|
||||
if(count)
|
||||
{
|
||||
if(index<count)
|
||||
memmove(items+index,items+index+1,(count-index)*sizeof(T));
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从队列中取出一个数据
|
||||
* @param t 取出的数据保存地
|
||||
* @return 是否成功取出数据
|
||||
*/
|
||||
template<typename T>
|
||||
bool Queue<T>::Pop(T &t)
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
// t=items[0];
|
||||
memcpy(&t,items,sizeof(T));
|
||||
|
||||
count--;
|
||||
|
||||
if(max_count==0)
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
//memcpy(items,items+1,count*sizeof(T));
|
||||
memmove(items,items+1,count*sizeof(T));
|
||||
// items=(T *)hgl_realloc(items,count*sizeof(T));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(items,items+1,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(max_count)
|
||||
{
|
||||
if(count>=max_count)return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
if(count+1>mem_count)
|
||||
{
|
||||
mem_count=power_to_2(count+1);
|
||||
|
||||
items=(T *)hgl_realloc(items,mem_count*sizeof(T));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
items=hgl_aligned_malloc<T>(1);
|
||||
|
||||
mem_count=1;
|
||||
}
|
||||
}
|
||||
|
||||
// items[count++]=data;
|
||||
memcpy(items+count,&data,sizeof(T));
|
||||
count++;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Queue<T>::Find(const T &data)
|
||||
{
|
||||
if(count<=0)
|
||||
return(-1);
|
||||
|
||||
T *p=items;
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(*p==data)
|
||||
return(i);
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Queue<T>::operator =(const Queue<T> &ori)
|
||||
{
|
||||
if(ori.count==0)return;
|
||||
|
||||
Clear();
|
||||
|
||||
max_count=ori.count;
|
||||
count=ori.count;
|
||||
|
||||
if(max_count==0)
|
||||
mem_count=count;
|
||||
else
|
||||
mem_count=max_count;
|
||||
|
||||
items=hgl_aligned_malloc<T>(mem_count);
|
||||
|
||||
memcpy(items,ori.items,mem_count*sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T>
|
||||
void QueueObject<T>::Clear()
|
||||
{
|
||||
int n=Queue<T *>::count;
|
||||
|
||||
while(n--)
|
||||
delete Queue<T *>::items[n];
|
||||
|
||||
Queue<T *>::Clear();
|
||||
}
|
||||
}
|
||||
#endif//HGL_QUEUE_CPP
|
75
inc/hgl/type/Queue.h
Normal file
75
inc/hgl/type/Queue.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef HGL_QUEUE_INCLUDE
|
||||
#define HGL_QUEUE_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* Queue模板类用于保存一个先进先出、后进后出的数据队列
|
||||
*
|
||||
* 注:这个类还在测试中,请不要修改这个类的源代码,如有修改意见,请致电作者。
|
||||
*/
|
||||
template<typename T> class Queue ///队列顺序数据访问类
|
||||
{
|
||||
protected:
|
||||
|
||||
int max_count;
|
||||
int mem_count;
|
||||
int count;
|
||||
T *items;
|
||||
|
||||
public: //属性
|
||||
|
||||
T *GetData()const{return items;} ///<取得原始数据
|
||||
int GetCount()const{return count;} ///<取得数据数量
|
||||
|
||||
int GetMax()const{return max_count;} ///<取得最大数量
|
||||
void SetMax(int); ///<设置最大数量
|
||||
|
||||
T *GetData(){return items;} ///<取得原始数据
|
||||
|
||||
public: //方法
|
||||
|
||||
Queue(int=0);
|
||||
virtual ~Queue();
|
||||
|
||||
bool Peek(T &); ///<尝试访问一个数据
|
||||
bool Pop(T &); ///<弹出一个数据
|
||||
bool Push(const T &); ///<压入一个数据
|
||||
|
||||
int Find(const T &); ///<查找队列中这个数据的编号
|
||||
bool Delete(int); ///<删除队列中指定编号的数据
|
||||
|
||||
void Clear(); ///<清除所有数据
|
||||
void ClearData(); ///<清除所有数据,但不释放内存
|
||||
|
||||
bool GetItem(int n,T &ti) ///<取得指定项数据
|
||||
{
|
||||
if(n<0||n>=count)return(false);
|
||||
|
||||
ti=items[n];
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual void operator =(const Queue<T> &);
|
||||
};//template<typename T> class Queue
|
||||
|
||||
template<typename T> class QueueObject:public Queue<T *> ///堆栈对象
|
||||
{
|
||||
public:
|
||||
|
||||
using Queue<T *>::Queue;
|
||||
virtual ~QueueObject(){Clear();}
|
||||
|
||||
void Clear();
|
||||
|
||||
T *operator[](int n)const
|
||||
{
|
||||
if(n<0||n>=Queue<T *>::count)return(nullptr);
|
||||
|
||||
return Queue<T *>::items[n];
|
||||
}
|
||||
};//template<typename T> class QueueObject
|
||||
}//namespace hgl
|
||||
#include<hgl/type/Queue.cpp>
|
||||
#endif//HGL_QUEUE_INCLUDE
|
134
inc/hgl/type/ResManage.cpp
Normal file
134
inc/hgl/type/ResManage.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
#ifndef HGL_RES_MANAGE_CPP
|
||||
#define HGL_RES_MANAGE_CPP
|
||||
|
||||
#include<hgl/type/ResManage.h>
|
||||
namespace hgl
|
||||
{
|
||||
template<typename F,typename T>
|
||||
ResManage<F,T>::~ResManage()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
void ResManage<F,T>::Clear()
|
||||
{
|
||||
int n=items.GetCount();
|
||||
|
||||
while(n--)
|
||||
{
|
||||
ResItem *obj=items.GetItem(n);
|
||||
|
||||
Clear(obj->right);
|
||||
}
|
||||
|
||||
items.Clear();
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
void ResManage<F,T>::ClearZero()
|
||||
{
|
||||
int n=items.GetCount();
|
||||
|
||||
while(n--)
|
||||
{
|
||||
ResItem *obj=items.GetItem(n);
|
||||
|
||||
if(obj->count<=0)
|
||||
{
|
||||
Clear(obj->right);
|
||||
items.DeleteBySerial(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
bool ResManage<F,T>::Add(const F &flag,T *obj)
|
||||
{
|
||||
if(!obj)return(false);
|
||||
|
||||
if(items.KeyExist(flag))
|
||||
return(false);
|
||||
|
||||
items.Add(flag,obj);
|
||||
return(true);
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
T *ResManage<F,T>::Find(const F &flag)
|
||||
{
|
||||
int index=items.Find(flag);
|
||||
|
||||
if(index==-1)
|
||||
return(nullptr);
|
||||
|
||||
T *result;
|
||||
|
||||
if(items.Get(flag,result))
|
||||
return(result);
|
||||
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
T *ResManage<F,T>::Get(const F &flag)
|
||||
{
|
||||
int index=items.Find(flag);
|
||||
|
||||
if(index!=-1)
|
||||
{
|
||||
ResItem *obj=items.GetItem(index);
|
||||
|
||||
//items[index]->count++;
|
||||
obj->count++;
|
||||
|
||||
// return(items[index]->data);
|
||||
return obj->right;
|
||||
}
|
||||
|
||||
T *data=Create(flag);
|
||||
|
||||
if(data)
|
||||
{
|
||||
items.Add(flag,data);
|
||||
|
||||
return(data);
|
||||
}
|
||||
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
void ResManage<F,T>::ReleaseBySerial(int index,bool zero_clear)
|
||||
{
|
||||
if(index==-1)
|
||||
{
|
||||
// ErrorHint(u"所释放的资源不存在");
|
||||
return;
|
||||
}
|
||||
|
||||
ResItem *obj=items.GetItem(index);
|
||||
|
||||
--obj->count;
|
||||
|
||||
if(zero_clear&&obj->count==0)
|
||||
{
|
||||
Clear(obj->right);
|
||||
|
||||
items.DeleteBySerial(index);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
void ResManage<F,T>::Release(const F &flag,bool zero_clear)
|
||||
{
|
||||
ReleaseBySerial(items.Find(flag),zero_clear);
|
||||
}
|
||||
|
||||
template<typename F,typename T>
|
||||
void ResManage<F,T>::Release(T *td,bool zero_clear)
|
||||
{
|
||||
ReleaseBySerial(items.FindByValue(td),zero_clear);
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_RES_MANAGE_CPP
|
55
inc/hgl/type/ResManage.h
Normal file
55
inc/hgl/type/ResManage.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef HGL_RES_MANAGE_INCLUDE
|
||||
#define HGL_RES_MANAGE_INCLUDE
|
||||
|
||||
#include<hgl/type/Map.h>
|
||||
namespace hgl
|
||||
{
|
||||
template<typename F,typename T> struct RefFlagData:public Pair<F,T *>
|
||||
{
|
||||
uint count;
|
||||
|
||||
public:
|
||||
|
||||
RefFlagData():Pair<F,T *>()
|
||||
{
|
||||
count=1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 资源管理器,它没有缓冲管理,仅仅是管理数据,并保证不会被重复加载
|
||||
*/
|
||||
template<typename F,typename T> class ResManage
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef RefFlagData<F,T> ResItem;
|
||||
|
||||
_Map<F,T *,ResItem> items;
|
||||
|
||||
void ReleaseBySerial(int,bool);
|
||||
|
||||
protected:
|
||||
|
||||
virtual T *Create(const F &)=0; ///<资源创建虚拟函数无实现,请特例化实现
|
||||
virtual void Clear(T *obj){delete obj;} ///<资源释放虚拟函数(缺省为直接delete对象)
|
||||
|
||||
public:
|
||||
|
||||
virtual ~ResManage();
|
||||
|
||||
virtual void Clear(); ///<清除所有数据
|
||||
virtual void ClearZero(); ///<清除所有没有用到的数据
|
||||
|
||||
const int GetCount()const{return items.GetCount();} ///<取得数据数量
|
||||
|
||||
virtual bool Add(const F &,T *); ///<添加一个数据
|
||||
virtual T * Find(const F &); ///<查找一个数据
|
||||
virtual T * Get(const F &); ///<取得一个数据,如不存在则创建
|
||||
|
||||
virtual void Release(const F &,bool zero_clear=false); ///<释放一个数据
|
||||
virtual void Release(T *,bool zero_clear=false); ///<释放一个数据
|
||||
};//template<typename F,typename T> class ResManage
|
||||
}//namespace hgl
|
||||
#include<hgl/type/ResManage.cpp>
|
||||
#endif//HGL_RES_MANAGE_INCLUDE
|
34
inc/hgl/type/ResPoolManage.h
Normal file
34
inc/hgl/type/ResPoolManage.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef HGL_RES_POOL_MANAGE_INCLUDE
|
||||
#define HGL_RES_POOL_MANAGE_INCLUDE
|
||||
|
||||
#include<hgl/type/Pool.h>
|
||||
#include<hgl/type/ResManage.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 资源池是Pool/ResManage两个模板的组合应用
|
||||
*/
|
||||
template <typename I,typename T> class ResPoolManage:public ResManage<I,T>
|
||||
{
|
||||
protected:
|
||||
|
||||
ObjectPool<T> data_pool;
|
||||
|
||||
public:
|
||||
|
||||
virtual T *Create(const I &flag){return data_pool.Acquire();}
|
||||
virtual void Clear(T *obj){data_pool.Release(obj);}
|
||||
|
||||
public:
|
||||
|
||||
virtual ~ResPoolManage()=default;
|
||||
|
||||
virtual void Clear()
|
||||
{
|
||||
this->items.Clear();
|
||||
data_pool.ClearAll();
|
||||
}
|
||||
};//template <typename I,typename T> class ResPoolManage<I,T>:public ResManage<I,T>
|
||||
}//namespace hgl
|
||||
#endif//HGL_RES_POOL_MANAGE_INCLUDE
|
365
inc/hgl/type/Set.cpp
Normal file
365
inc/hgl/type/Set.cpp
Normal file
@ -0,0 +1,365 @@
|
||||
#ifndef HGL_TYPE_SET_CPP
|
||||
#define HGL_TYPE_SET_CPP
|
||||
|
||||
#include<hgl/type/Set.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 查找数据是否存在
|
||||
* @param flag 数据
|
||||
* @return 数据所在索引,-1表示不存在
|
||||
*/
|
||||
template<typename T>
|
||||
const int Set<T>::Find(const T &flag)const
|
||||
{
|
||||
int left=0,right=data_list.GetCount()-1; //使用left,right而不使用min,max是为了让代码能够更好的阅读。
|
||||
int mid;
|
||||
|
||||
T *data_array=data_list.GetData();
|
||||
|
||||
while(left<=right)
|
||||
{
|
||||
if(data_array[left ]==flag)return(left);
|
||||
if(data_array[right]==flag)return(right);
|
||||
|
||||
mid=(right+left)>>1;
|
||||
|
||||
if(data_array[mid]==flag)return(mid);
|
||||
|
||||
if(data_array[mid]>flag)
|
||||
{
|
||||
left++;
|
||||
right=mid-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
right--;
|
||||
left=mid+1;
|
||||
}
|
||||
}
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Set<T>::FindPos(const T &flag,int &pos)const
|
||||
{
|
||||
int left=0,right=data_list.GetCount()-1;
|
||||
int mid;
|
||||
|
||||
T *data_array=data_list.GetData();
|
||||
|
||||
while(left<=right)
|
||||
{
|
||||
if(data_array[left]>flag)
|
||||
{
|
||||
pos=left;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[left]==flag)
|
||||
{
|
||||
pos=left;
|
||||
return(true);
|
||||
}
|
||||
|
||||
if(data_array[right]<flag)
|
||||
{
|
||||
pos=right+1;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[right]==flag)
|
||||
{
|
||||
pos=right;
|
||||
return(true);
|
||||
}
|
||||
|
||||
mid=(right+left)>>1;
|
||||
|
||||
if(data_array[mid]==flag)
|
||||
{
|
||||
pos=mid;
|
||||
return(true);
|
||||
}
|
||||
|
||||
if(data_array[mid]>flag)
|
||||
{
|
||||
if(data_array[mid-1]<flag)
|
||||
{
|
||||
pos=mid;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[mid-1]==flag)
|
||||
{
|
||||
pos=mid-1;
|
||||
return(true);
|
||||
}
|
||||
|
||||
++left;
|
||||
right=mid-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(data_array[mid+1]>flag)
|
||||
{
|
||||
pos=mid+1;
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
if(data_array[mid+1]==flag)
|
||||
{
|
||||
pos=mid+1;
|
||||
return(true);
|
||||
}
|
||||
|
||||
--right;
|
||||
left=mid+1;
|
||||
}
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个数据
|
||||
* @param data 数据
|
||||
* @return 位置
|
||||
*/
|
||||
template<typename T>
|
||||
int Set<T>::Add(const T &data)
|
||||
{
|
||||
if(data_list.GetCount()<=0)
|
||||
{
|
||||
data_list.Add(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos;
|
||||
|
||||
if(FindPos(data,pos))
|
||||
return(-1); //数据已存在
|
||||
|
||||
data_list.Insert(pos,data);
|
||||
|
||||
return(pos);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一批数据
|
||||
* @param dp 数据指针
|
||||
* @param count 数据个数
|
||||
* @return 成功加入的数据个数
|
||||
*/
|
||||
template<typename T>
|
||||
int Set<T>::Add(const T *dp,const int count)
|
||||
{
|
||||
int total=0;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(Add(*dp)!=-1)
|
||||
++total;
|
||||
|
||||
++dp;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新一个数据
|
||||
* @param data 数据
|
||||
* @return 是否成功
|
||||
*/
|
||||
template<typename T>
|
||||
bool Set<T>::Update(const T &data)
|
||||
{
|
||||
if(data_list.GetCount()<=0)
|
||||
return(false);
|
||||
|
||||
int pos;
|
||||
|
||||
if(!FindPos(data,pos))
|
||||
return(false);
|
||||
|
||||
data_list.Set(pos,data);
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个数据
|
||||
* @param pos 索引编号
|
||||
*/
|
||||
template<typename T>
|
||||
bool Set<T>::DeleteBySerial(int pos)
|
||||
{
|
||||
if(pos<0||pos>=data_list.GetCount())return(false);
|
||||
|
||||
return data_list.DeleteMove(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个数据
|
||||
* @param data 数据
|
||||
*/
|
||||
template<typename T>
|
||||
bool Set<T>::Delete(const T &data)
|
||||
{
|
||||
int pos=Find(data);
|
||||
|
||||
if(pos==-1)return(false);
|
||||
|
||||
return DeleteBySerial(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一批数据
|
||||
* @param dp 数据指针
|
||||
* @param count 数据个数
|
||||
* @return 成功删除的数据个数
|
||||
*/
|
||||
template<typename T>
|
||||
int Set<T>::Delete(T *dp,const int count)
|
||||
{
|
||||
int total=0;
|
||||
int pos;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
pos=Find(*dp);
|
||||
if(pos!=-1)
|
||||
{
|
||||
DeleteBySerial(pos);
|
||||
++total;
|
||||
}
|
||||
|
||||
++dp;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有数据
|
||||
*/
|
||||
template<typename T>
|
||||
void Set<T>::Clear()
|
||||
{
|
||||
data_list.Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有数据,但不释放内存
|
||||
*/
|
||||
template<typename T>
|
||||
void Set<T>::ClearData()
|
||||
{
|
||||
data_list.ClearData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机取得一个数据
|
||||
*/
|
||||
template<typename T>
|
||||
bool Set<T>::Rand(T &result)const
|
||||
{
|
||||
return data_list.Rand(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 求当前合集与另一个数据集的交集
|
||||
* @param result 结果存放合集
|
||||
* @param list 要计算交集的数据集
|
||||
* @return 交集数量
|
||||
*/
|
||||
template<typename T>
|
||||
int Set<T>::Intersection(Set<T> &result,const Set<T> &list)
|
||||
{
|
||||
if(data_list.GetCount()<=0)
|
||||
return(0);
|
||||
|
||||
if(list.GetCount()<=0)
|
||||
return(0);
|
||||
|
||||
data_list.Enum([&](T &obj)
|
||||
{
|
||||
if(list->IsMember(obj))
|
||||
result.Add(obj);
|
||||
});
|
||||
|
||||
return result.GetCount();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Set<T>::Intersection(const Set<T> &list)
|
||||
{
|
||||
if(data_list.GetCount()<=0)
|
||||
return(0);
|
||||
|
||||
if(list.GetCount()<=0)
|
||||
return(0);
|
||||
|
||||
int count=0;
|
||||
|
||||
T *obj=data_list.GetData();
|
||||
for(int i=0;i<data_list.GetCount();i++)
|
||||
{
|
||||
if(list.IsMember(*obj))
|
||||
++count;
|
||||
|
||||
++obj;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Set<T>::Intersection(Set<T> &result,const Set<T> &il,const Set<T> &cl)
|
||||
{
|
||||
if(data_list.GetCount()<=0)
|
||||
return(0);
|
||||
|
||||
if(il.GetCount()<=0)
|
||||
return(0);
|
||||
|
||||
T *obj=data_list.GetData();
|
||||
for(int i=0;i<data_list.GetCount();i++)
|
||||
{
|
||||
if(il.IsMember(*obj))
|
||||
if(!cl.IsMember(*obj))
|
||||
result.Add(*obj);
|
||||
++obj;
|
||||
}
|
||||
|
||||
return result.GetCount();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int Set<T>::Difference(const Set<T> &is)
|
||||
{
|
||||
if(data_list.GetCount()<=0)
|
||||
return(is.GetCount());
|
||||
|
||||
if(is.GetCount()<=0)
|
||||
return(data_list.GetCount());
|
||||
|
||||
int count=0;
|
||||
|
||||
T *obj=data_list.GetData();
|
||||
for(int i=0;i<data_list.GetCount();i++)
|
||||
{
|
||||
if(!is.IsMember(*obj))
|
||||
++count;
|
||||
|
||||
++obj;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_TYPE_SET_CPP
|
77
inc/hgl/type/Set.h
Normal file
77
inc/hgl/type/Set.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef HGL_TYPE_SET_INCLUDE
|
||||
#define HGL_TYPE_SET_INCLUDE
|
||||
|
||||
#include<hgl/type/List.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 集合数据列表中不允许数据出现重复性,同时它会将数据排序,所以也可以当做有序列表使用
|
||||
*/
|
||||
template<typename T> class Set
|
||||
{
|
||||
protected:
|
||||
|
||||
List<T> data_list;
|
||||
|
||||
bool FindPos(const T &,int &)const; ///<查找数据如果插入后,会所在的位置,返回是否存在这个数据
|
||||
int FindPos(const T &flag)const{int pos;FindPos(flag,pos);return(pos);} ///<查找数据如果插入后,会所在的位置
|
||||
|
||||
public: //属性
|
||||
|
||||
List<T> & GetList ()const{return data_list;} ///<取得数据原始列表
|
||||
T * GetData ()const{return data_list.GetData();} ///<取得数据指针
|
||||
int GetCount ()const{return data_list.GetCount();} ///<取得数据总量
|
||||
|
||||
public:
|
||||
|
||||
Set()=default;
|
||||
virtual ~Set()=default;
|
||||
|
||||
void SetCount (int count){data_list.SetCount(count);} ///<指定数据数量,一般用于批量加载前的处理
|
||||
void PreMalloc (int count){data_list.PreMalloc(count);} ///<预分配指定数量的数据空间
|
||||
|
||||
const int Find (const T &)const; ///<查找数据位置,不存在返回-1
|
||||
const bool IsMember (const T &v)const{return(Find(v)!=-1);} ///<确认是否成员
|
||||
int Add (const T &); ///<添加一个数据,返回索引号,返回-1表示数据已存在
|
||||
int Add (const T *,const int); ///<添加一批数据
|
||||
int Add (const Set<T> &s){return Add(s.GetData(),s.GetCount());} ///<添加一批数据
|
||||
bool Update (const T &); ///<更新一个数据
|
||||
bool Delete (const T &); ///<删除一个数据
|
||||
int Delete (T *,const int); ///<删除一批数据
|
||||
bool DeleteBySerial (int); ///<删除一个数据,使用序号
|
||||
void Clear (); ///<清除数据
|
||||
void ClearData (); ///<清除数据,但不释放内存
|
||||
void DeleteClear (){data_list.DeleteClear();} ///<清除所有数据并全部调用delete
|
||||
|
||||
bool Get (const int index,T &data)
|
||||
{
|
||||
if(index<0||index>=data_list.GetCount())
|
||||
return(false);
|
||||
|
||||
data=*(data_list.GetData()+index);
|
||||
return(true);
|
||||
}
|
||||
|
||||
int Intersection (Set<T> &result,const Set<T> &set); ///<取得与指定合集的交集
|
||||
int Intersection (const Set<T> &set); ///<取得与指定合集的交集数量
|
||||
|
||||
/**
|
||||
* 取得与指定交集is的合集,但排斥cs合集中的数据
|
||||
* @param result 结果合集
|
||||
* @param is 求交集的合集
|
||||
* @param cs 求排斥的合集
|
||||
* @return 结果数量
|
||||
*/
|
||||
int Intersection (Set<T> &result,const Set<T> &is,const Set<T> &cs);
|
||||
|
||||
int Difference (const Set<T> &is); ///<求差集数量
|
||||
|
||||
void operator =(const Set<T> &set){data_list=set.data_list;} ///<等号操作符重载
|
||||
|
||||
bool Rand (T &)const; ///<随机取得一个
|
||||
|
||||
virtual void Enum (void (*enum_func)(T &)){data_list.Enum(enum_func);} ///<枚举所有数据成员
|
||||
};//template<typename T> class Set
|
||||
}//namespace hgl
|
||||
#include<hgl/type/Set.cpp>
|
||||
#endif//HGL_TYPE_SET_INCLUDE
|
@ -2,7 +2,6 @@
|
||||
#define HGL_SMART_INCLUDE
|
||||
|
||||
#include<hgl/TypeFunc.h>
|
||||
#include<hgl/Macro.h>
|
||||
#include<hgl/thread/Atomic.h>
|
||||
namespace hgl
|
||||
{
|
||||
|
261
inc/hgl/type/Stack.cpp
Normal file
261
inc/hgl/type/Stack.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
#ifndef HGL_STACK_CPP
|
||||
#define HGL_STACK_CPP
|
||||
|
||||
#include<hgl/LogInfo.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 本类构造函数
|
||||
* @param m 如果m的值不为0,则表示使用固定的堆栈大小。固定大小的堆栈会在一开始即分配好内存。
|
||||
*/
|
||||
template<typename T>
|
||||
Stack<T>::Stack(int m)
|
||||
{
|
||||
count=0;
|
||||
|
||||
if(m)
|
||||
{
|
||||
max_count=m;
|
||||
|
||||
items=hgl_aligned_malloc<T>(max_count);
|
||||
}
|
||||
else
|
||||
max_count=0;
|
||||
|
||||
mem_count=max_count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Stack<T>::~Stack()
|
||||
{
|
||||
if(count||max_count)hgl_free(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改堆栈的最大值
|
||||
*/
|
||||
template<typename T>
|
||||
void Stack<T>::SetMax(int m)
|
||||
{
|
||||
if(m<=0)return;
|
||||
|
||||
if(mem_count==0)
|
||||
{
|
||||
mem_count=power_to_2(m);
|
||||
items=hgl_aligned_malloc<T>(mem_count);
|
||||
}
|
||||
else
|
||||
if(mem_count<m)
|
||||
{
|
||||
mem_count=power_to_2(m);
|
||||
items=(T *)hgl_realloc(items,mem_count*sizeof(T));
|
||||
}
|
||||
|
||||
max_count=m;
|
||||
|
||||
if(count>=max_count)count=max_count-1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Stack<T>::SetCount(int c)
|
||||
{
|
||||
if(c<0)return(false);
|
||||
|
||||
if(c>max_count)
|
||||
return(false);
|
||||
|
||||
count=c;
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除堆栈中的所有数据
|
||||
*/
|
||||
template<typename T>
|
||||
void Stack<T>::Clear()
|
||||
{
|
||||
if(max_count==0)
|
||||
if(count)
|
||||
{
|
||||
hgl_free(items);
|
||||
mem_count=0;
|
||||
}
|
||||
|
||||
count=0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Stack<T>::GetItem(int n,T &data)
|
||||
{
|
||||
if(n<0||n>=count)
|
||||
{
|
||||
LOG_ERROR(OS_TEXT("从堆栈中按索引<") + OSString(n) + OS_TEXT(">取数据,超出正常范围<")+OSString(count) + OS_TEXT(">"));
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
data=items[n];
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 访问堆栈中的一个数据,但不清除它
|
||||
* @param t 取出的数据保存地
|
||||
* @return 是否成功取出数据
|
||||
*/
|
||||
template<typename T>
|
||||
bool Stack<T>::Peek(T &t)
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
memcpy(&t,items+(count-1),sizeof(T));
|
||||
// t=items[count-1];
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从堆栈中取出一个数据
|
||||
* @param t 取出的数据保存地
|
||||
* @return 是否成功取出数据
|
||||
*/
|
||||
template<typename T>
|
||||
bool Stack<T>::Pop(T &t)
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
// t=items[--count];
|
||||
count--;
|
||||
memcpy(&t,items+count,sizeof(T));
|
||||
|
||||
if(max_count==0)
|
||||
{
|
||||
if(count==0)
|
||||
{
|
||||
hgl_free(items);
|
||||
|
||||
mem_count=0;
|
||||
}
|
||||
//else
|
||||
//items=(T *)hgl_realloc(items,count*sizeof(T));
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
return(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向堆栈中放入一个数据
|
||||
* @param data 要放入的数据指针
|
||||
* @return true 放入数据成功
|
||||
* @return false 放入数据失败
|
||||
*/
|
||||
template<typename T>
|
||||
bool Stack<T>::Push(T &data)
|
||||
{
|
||||
if(max_count)
|
||||
{
|
||||
if(count>=max_count)return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
if(count+1>mem_count)
|
||||
{
|
||||
mem_count=power_to_2(count+1);
|
||||
|
||||
items=(T *)hgl_realloc(items,mem_count*sizeof(T));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
items=hgl_aligned_malloc<T>(1);
|
||||
|
||||
mem_count=1;
|
||||
}
|
||||
}
|
||||
|
||||
// items[count++]=data;
|
||||
memcpy(items+count,&data,sizeof(T));
|
||||
count++;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向堆栈中放入多个数据
|
||||
* @param data 要放入的数据
|
||||
* @param data_count 要放入的数据个数
|
||||
* @return true 放入数据成功
|
||||
* @return false 放入数据失败
|
||||
*/
|
||||
template<typename T>
|
||||
bool Stack<T>::MultiPush(T *data,int data_count)
|
||||
{
|
||||
if(max_count)
|
||||
{
|
||||
if(count>=max_count)return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(count)
|
||||
{
|
||||
if(count+data_count>mem_count)
|
||||
{
|
||||
mem_count=power_to_2(count+data_count);
|
||||
|
||||
items=(T *)hgl_realloc(items,mem_count*sizeof(T));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
items=hgl_aligned_malloc<T>(data_count);
|
||||
|
||||
mem_count=data_count;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(items+count,data,data_count*sizeof(T));
|
||||
count+=data_count;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Stack<T>::operator =(const Stack<T> &ori)
|
||||
{
|
||||
if(ori.count==0)return;
|
||||
|
||||
Clear();
|
||||
|
||||
max_count=ori.count;
|
||||
count=ori.count;
|
||||
|
||||
if(max_count==0)
|
||||
mem_count=count;
|
||||
else
|
||||
mem_count=max_count;
|
||||
|
||||
items=hgl_aligned_malloc<T>(mem_count);
|
||||
|
||||
memcpy(items,ori.items,mem_count*sizeof(T));
|
||||
}
|
||||
}//namespace hgl
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T>
|
||||
void StackObject<T>::Clear()
|
||||
{
|
||||
for(int i=0;i<this->count;i++)
|
||||
delete this->items[i];
|
||||
|
||||
Stack<T *>::Clear();
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_STACK_CPP
|
59
inc/hgl/type/Stack.h
Normal file
59
inc/hgl/type/Stack.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef HGL_STACK_INCLUDE
|
||||
#define HGL_STACK_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* Stack模板类用于保存一个先进后出、后进先出的数据堆栈
|
||||
*
|
||||
* 注:这个类还在测试中,请不要修改这个类的源代码,如有修改意见,请致电作者。
|
||||
*/
|
||||
template<typename T> class Stack ///堆栈顺序数据访问类
|
||||
{
|
||||
protected:
|
||||
|
||||
int max_count;
|
||||
int mem_count;
|
||||
int count;
|
||||
T *items;
|
||||
|
||||
public: //属性
|
||||
|
||||
int GetCount() const{return count;} ///<取得堆栈中数据的个数
|
||||
bool SetCount(int c); ///<直接设置堆栈中数据的个数
|
||||
|
||||
int GetMax () const{return max_count;} ///<取得堆栈中的最大数据个数
|
||||
void SetMax (int); ///<设置堆栈中的最大数据个数
|
||||
|
||||
T * GetData () {return items;} ///<取得原始数据
|
||||
|
||||
public: //方法
|
||||
|
||||
Stack(int=0);
|
||||
virtual ~Stack();
|
||||
|
||||
bool Peek(T &); ///<尝试访问一个数据
|
||||
virtual bool Pop(T &); ///<弹出一个数据
|
||||
bool Push(T &); ///<压入一个数据
|
||||
bool MultiPush(T *,int); ///<放入多个数据
|
||||
|
||||
virtual void Clear(); ///<清除所有数据
|
||||
|
||||
bool GetItem(int,T &);
|
||||
|
||||
virtual void operator =(const Stack<T> &);
|
||||
};//template<typename T> class Stack
|
||||
|
||||
template<typename T> class StackObject:public Stack<T *> ///堆栈对象
|
||||
{
|
||||
public:
|
||||
|
||||
using Stack<T *>::Stack;
|
||||
virtual ~StackObject(){Clear();};
|
||||
|
||||
void Clear();
|
||||
};//template<typename T> class StackObject
|
||||
}//namespace hgl
|
||||
#include<hgl/type/Stack.cpp>
|
||||
#endif//HGL_STACK_INCLUDE
|
@ -1,2 +1,2 @@
|
||||
add_subdirectory(RenderDevice)
|
||||
# add_subdirectory(RenderDriver)
|
||||
add_subdirectory(RenderDriver)
|
||||
|
@ -1,2 +1,3 @@
|
||||
add_library(ULRE.RenderDriver STATIC GLCore/)
|
||||
add_library(ULRE.RenderDriver STATIC GLSL.cpp
|
||||
Shader.cpp)
|
||||
|
||||
|
392
src/RenderDriver/GLSL.cpp
Normal file
392
src/RenderDriver/GLSL.cpp
Normal file
@ -0,0 +1,392 @@
|
||||
#include<hgl/render/Shader.h>
|
||||
#include<hgl/LogInfo.h>
|
||||
#include<hgl/type/Smart.h>
|
||||
#include<malloc.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace
|
||||
{
|
||||
constexpr uint OpenGLShaderType[ShaderType::stEnd]=
|
||||
{
|
||||
GL_VERTEX_SHADER, ///<顶点着色程序
|
||||
GL_TESS_CONTROL_SHADER, ///<镶嵌控制着色程序(需OpenGL 4.0或ARB_tessellation_shader)
|
||||
GL_TESS_EVALUATION_SHADER, ///<镶嵌评估着色程序(需OpenGL 4.0或ARB_tessellation_shader)
|
||||
GL_GEOMETRY_SHADER, ///<几何着色程序
|
||||
GL_FRAGMENT_SHADER, ///<片断着色程序
|
||||
GL_COMPUTE_SHADER ///<计算着色程序(需OpenGL 4.3或ARB_compute_shader)
|
||||
};
|
||||
}
|
||||
|
||||
const char ShaderTypeName[ShaderType::stEnd][32]=
|
||||
{
|
||||
"Vertex",
|
||||
"TessControl",
|
||||
"TessEvaluation",
|
||||
"Geometry",
|
||||
"Fragment",
|
||||
"Compute"
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
/**
|
||||
* 编译一段shader
|
||||
* @param type 类型
|
||||
* @param name 名称
|
||||
* @param shader_source 代码
|
||||
* @return 编译成功的shader句柄
|
||||
* @return 0 编译失败
|
||||
*/
|
||||
GLuint CompileShader(GLenum type,const char *name,const char *shader_source)
|
||||
{
|
||||
if(!shader_source)return(0);
|
||||
|
||||
GLuint shader=glCreateShader(type);
|
||||
|
||||
glShaderSource(shader,1,&shader_source,0);
|
||||
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint compiled,log_length;
|
||||
|
||||
glGetShaderiv(shader,GL_COMPILE_STATUS,&compiled);
|
||||
|
||||
if(compiled)
|
||||
return(shader);
|
||||
|
||||
glGetShaderiv(shader,GL_INFO_LOG_LENGTH,&log_length);
|
||||
|
||||
GLint char_writen;
|
||||
char *log=new char[log_length];
|
||||
|
||||
glGetShaderInfoLog(shader,log_length,&char_writen,log);
|
||||
|
||||
LOG_HINT(UTF8String(name)+U8_TEXT(" shader compile error\n\n")+ UTF8String(log));
|
||||
|
||||
delete[] log;
|
||||
|
||||
LOG_ERROR(shader_source);
|
||||
|
||||
glDeleteShader(shader);
|
||||
|
||||
return(0);
|
||||
}
|
||||
}//namespace
|
||||
|
||||
void Shader::Clear()
|
||||
{
|
||||
for(int i=0;i<ShaderType::stEnd;i++)
|
||||
if(shader_index[i])
|
||||
{
|
||||
glDeleteShader(shader_index[i]);
|
||||
shader_index[i]=0;
|
||||
}
|
||||
|
||||
if(program)
|
||||
{
|
||||
glDeleteProgram(program);
|
||||
program=0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编译一个glsl着色程序
|
||||
* @param shader_type 着色程序类型
|
||||
* @param shader_codes 着色程序代码
|
||||
* @return 是否添加编程成功
|
||||
*/
|
||||
bool Shader::AddShader(const int shader_type,const char *shader_codes)
|
||||
{
|
||||
if(shader_type<0||shader_type>=ShaderType::stEnd)return(false);
|
||||
if(shader_index[shader_type])return(false);
|
||||
|
||||
if(!shader_codes
|
||||
||!(*shader_codes))return(false);
|
||||
|
||||
shader_index[shader_type]=CompileShader(OpenGLShaderType[shader_type],ShaderName[shader_type],shader_codes);
|
||||
|
||||
if(!shader_index[shader_type])
|
||||
return(false);
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Shader::Build()
|
||||
{
|
||||
program=glCreateProgram();
|
||||
|
||||
for(int i=0;i<ShaderType::stEnd;i++)
|
||||
if(shader_index[i])
|
||||
glAttachShader(program,shader_index[i]);
|
||||
|
||||
return(Link());
|
||||
}
|
||||
|
||||
bool Shader::Link()
|
||||
{
|
||||
if(!program)return(false);
|
||||
|
||||
glLinkProgram(program);
|
||||
|
||||
GLint linked;
|
||||
|
||||
glGetProgramiv(program,GL_LINK_STATUS,&linked);
|
||||
|
||||
if(linked)
|
||||
return(true);
|
||||
|
||||
GLint log_length,char_written;
|
||||
char *log;
|
||||
|
||||
glGetProgramiv(program,GL_INFO_LOG_LENGTH,&log_length);
|
||||
|
||||
log=new char[log_length];
|
||||
|
||||
glGetProgramInfoLog(program,log_length,&char_written,log);
|
||||
|
||||
LOG_ERROR(u8"Shader program link error\n\n"+UTF8String(log));
|
||||
|
||||
delete[] log;
|
||||
|
||||
Clear();
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool Shader::Use() ///<使用当前着色程序
|
||||
{
|
||||
if(!program)
|
||||
return(false);
|
||||
|
||||
glUseProgram(program);
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得属性索引地址
|
||||
* @param name 属性名称
|
||||
* @return 索引地址
|
||||
* @return -1 出错
|
||||
*/
|
||||
int Shader::_GetAttribLocation(const char *name)
|
||||
{
|
||||
if(!program)
|
||||
{
|
||||
LOG_ERROR(u8"GetAttribLocation("+UTF8String(name)+u8"),program=0");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return glGetAttribLocation(program,name);
|
||||
}
|
||||
|
||||
//bool Shader::SetAttrib1f(int location,float value)
|
||||
//{
|
||||
// if(!program)
|
||||
// return(false);
|
||||
|
||||
// glVertexAttrib1f(location,value);
|
||||
|
||||
// return(true);
|
||||
//}
|
||||
|
||||
//bool Shader::GetAttrib1f(int location,float &value)
|
||||
//{
|
||||
// if(!program)
|
||||
// return(false);
|
||||
|
||||
// glGetVertexAttribfv(location,GL_CURRENT_VERTEX_ATTRIB,&value);
|
||||
|
||||
// return(true);
|
||||
//}
|
||||
|
||||
/**
|
||||
* 取得一个变量的地址
|
||||
* @param name 变量名称
|
||||
* @return 地址
|
||||
* @return -1 出错
|
||||
*/
|
||||
int Shader::_GetUniformLocation(const char *name) ///<取得一个变量的地址
|
||||
{
|
||||
if(!program)
|
||||
{
|
||||
LOG_ERROR(u8"GetUniformLocation("+UTF8String(name)+u8"),program=0");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
const int result=glGetUniformLocation(program,name);
|
||||
|
||||
if(result==-1)
|
||||
{
|
||||
const int gl_error=glGetError();
|
||||
|
||||
LOG_ERROR(u8"GetUniformLocation("+UTF8String(name)+u8"),program="+UTF8String(program)+u8",result=-1,gl_error="+UTF8String(gl_error));
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define HGL_GLSL_CHECK_PROGRAM_AND_LOCATION(func) if(!program) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniform" #func ",program=0"); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
if(location<0) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniform" #func ",location="+UTF8String(location)); \
|
||||
return(false); \
|
||||
}
|
||||
|
||||
#define HGL_GLSL_SetUniform1234(func,type) bool Shader::SetUniform1##func(int location,type v0) \
|
||||
{ \
|
||||
HGL_GLSL_CHECK_PROGRAM_AND_LOCATION(1##func) \
|
||||
\
|
||||
glProgramUniform1##func(program,location,v0); \
|
||||
return(true); \
|
||||
} \
|
||||
\
|
||||
bool Shader::SetUniform2##func(int location,type v0,type v1) \
|
||||
{ \
|
||||
HGL_GLSL_CHECK_PROGRAM_AND_LOCATION(2##func) \
|
||||
\
|
||||
glProgramUniform2##func(program,location,v0,v1); \
|
||||
return(true); \
|
||||
} \
|
||||
\
|
||||
bool Shader::SetUniform3##func(int location,type v0,type v1,type v2) \
|
||||
{ \
|
||||
HGL_GLSL_CHECK_PROGRAM_AND_LOCATION(3##func) \
|
||||
\
|
||||
glProgramUniform3##func(program,location,v0,v1,v2); \
|
||||
return(true); \
|
||||
} \
|
||||
\
|
||||
bool Shader::SetUniform4##func(int location,type v0,type v1,type v2,type v3) \
|
||||
{ \
|
||||
HGL_GLSL_CHECK_PROGRAM_AND_LOCATION(4##func) \
|
||||
\
|
||||
glProgramUniform4##func(program,location,v0,v1,v2,v3); \
|
||||
return(true); \
|
||||
}
|
||||
HGL_GLSL_SetUniform1234(f,float);
|
||||
HGL_GLSL_SetUniform1234(i,int);
|
||||
HGL_GLSL_SetUniform1234(ui,unsigned int);
|
||||
|
||||
#undef HGL_GLSL_SetUniform1234
|
||||
|
||||
#define HGL_GLSL_SetUniformPointer(func,type) bool Shader::SetUniform##func(int location,const type *value) \
|
||||
{ \
|
||||
if(!program) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniform" #func ",program=0"); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
if(location<0) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniform" #func ",location="+UTF8String(location)); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
if(!value) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniform" #func ",value=nullptr"); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
glProgramUniform##func(program,location,1,value); \
|
||||
return(true); \
|
||||
}
|
||||
|
||||
HGL_GLSL_SetUniformPointer(1fv,float);
|
||||
HGL_GLSL_SetUniformPointer(2fv,float);
|
||||
HGL_GLSL_SetUniformPointer(3fv,float);
|
||||
HGL_GLSL_SetUniformPointer(4fv,float);
|
||||
|
||||
HGL_GLSL_SetUniformPointer(1iv,int);
|
||||
HGL_GLSL_SetUniformPointer(2iv,int);
|
||||
HGL_GLSL_SetUniformPointer(3iv,int);
|
||||
HGL_GLSL_SetUniformPointer(4iv,int);
|
||||
|
||||
HGL_GLSL_SetUniformPointer(1uiv,unsigned int);
|
||||
HGL_GLSL_SetUniformPointer(2uiv,unsigned int);
|
||||
HGL_GLSL_SetUniformPointer(3uiv,unsigned int);
|
||||
HGL_GLSL_SetUniformPointer(4uiv,unsigned int);
|
||||
|
||||
#undef HGL_GLSL_SetUniformPointer
|
||||
|
||||
#define HGL_GLSL_SetUniformMatrixPointer(func) bool Shader::SetUniformMatrix##func(int location,const float *mat) \
|
||||
{ \
|
||||
if(!program) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniformMatrix" #func ",program=0"); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
if(location<0) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniformMatrix" #func ",location="+UTF8String(location)); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
if(!mat) \
|
||||
{ \
|
||||
LOG_ERROR(u8"Shader::SetUniformMatrix" #func ",mat=nullptr"); \
|
||||
return(false); \
|
||||
} \
|
||||
\
|
||||
glProgramUniformMatrix##func(program,location,1,GL_FALSE,mat); \
|
||||
return(true); \
|
||||
}
|
||||
|
||||
HGL_GLSL_SetUniformMatrixPointer(2fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(3fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(4fv);
|
||||
|
||||
HGL_GLSL_SetUniformMatrixPointer(2x3fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(3x2fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(2x4fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(4x2fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(3x4fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(4x3fv);
|
||||
|
||||
#undef HGL_GLSL_SetUniformMatrixPointer
|
||||
|
||||
int Shader::_GetUniformBlockIndex(const char *uniform_block_name)
|
||||
{
|
||||
if(!program)
|
||||
{
|
||||
LOG_ERROR(u8"Shader::_GetUniformBlockIndex("+UTF8String(uniform_block_name)+") program=0");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
const int index=glGetUniformBlockIndex(program,uniform_block_name);
|
||||
|
||||
if(index<0)
|
||||
{
|
||||
LOG_ERROR(u8"Shader::_GetUniformBlockIndex("+UTF8String(uniform_block_name)+") block_index error");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int Shader::_GetShaderStorageIndex(const char *ssbo_name)
|
||||
{
|
||||
if(!program)
|
||||
{
|
||||
LOG_ERROR(u8"Shader::_GetShaderStorageIndex("+UTF8String(ssbo_name)+") program=0");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
const int index=glGetProgramResourceIndex(program,GL_SHADER_STORAGE_BLOCK,ssbo_name);
|
||||
|
||||
if(index<0)
|
||||
{
|
||||
LOG_ERROR(u8"Shader::_GetShaderStorageIndex("+UTF8String(ssbo_name)+") block_index error");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}//namespace hgl
|
250
src/RenderDriver/Shader.cpp
Normal file
250
src/RenderDriver/Shader.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
#include<hgl/render/Shader.h>
|
||||
//#include<hgl/render/UBO.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 取得属性索引地址
|
||||
* @param name 属性名称
|
||||
* @return 索引地址
|
||||
* @return -1 出错
|
||||
*/
|
||||
int Shader::GetAttribLocation(const char *name)
|
||||
{
|
||||
if(!name||!(*name))return(-1);
|
||||
|
||||
int result;
|
||||
|
||||
if(!attrib_location.Get(name,result))
|
||||
{
|
||||
result=_GetAttribLocation(name);
|
||||
|
||||
attrib_location.Add(name,result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得一个变量的地址
|
||||
* @param name 变量名称
|
||||
* @return 地址
|
||||
* @return -1 出错
|
||||
*/
|
||||
int Shader::GetUniformLocation(const char *name) ///<取得一个变量的地址
|
||||
{
|
||||
if(!name||!(*name))return(-1);
|
||||
|
||||
int result;
|
||||
|
||||
if(!uniform_location.Get(name,result))
|
||||
{
|
||||
result=_GetUniformLocation(name);
|
||||
|
||||
uniform_location.Add(name,result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得一个Shader只读数据区索引
|
||||
* @param name 数据区名称
|
||||
* @return 数据区索引
|
||||
* @return -1 出错
|
||||
*/
|
||||
int Shader::GetUniformBlockIndex(const char *name)
|
||||
{
|
||||
if(!name||!(*name))return(-1);
|
||||
|
||||
int result;
|
||||
|
||||
if(!uniform_block_index.Get(name,result))
|
||||
{
|
||||
result=_GetUniformBlockIndex(name);
|
||||
|
||||
uniform_block_index.Add(name,result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得一个Shader数据存储区索引
|
||||
* @param name 数据存储区名称
|
||||
* @return 数据存储区索引
|
||||
* @return -1 出错
|
||||
*/
|
||||
int Shader::GetShaderStorageIndex(const char *name)
|
||||
{
|
||||
if(!name||!(*name))return(-1);
|
||||
|
||||
int result;
|
||||
|
||||
if(!ssbo_index.Get(name,result))
|
||||
{
|
||||
result=_GetShaderStorageIndex(name);
|
||||
|
||||
ssbo_index.Add(name,result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define HGL_GLSL_SetUniform1234(func,type) bool Shader::SetUniform1##func(const char *uniform_name,type v0) \
|
||||
{ \
|
||||
const int location=GetUniformLocation(uniform_name); \
|
||||
\
|
||||
if(location==-1)return(false); \
|
||||
\
|
||||
return SetUniform1##func(location,v0); \
|
||||
} \
|
||||
\
|
||||
bool Shader::SetUniform2##func(const char *uniform_name,type v0,type v1) \
|
||||
{ \
|
||||
const int location=GetUniformLocation(uniform_name); \
|
||||
\
|
||||
if(location==-1)return(false); \
|
||||
\
|
||||
return SetUniform2##func(location,v0,v1); \
|
||||
} \
|
||||
\
|
||||
bool Shader::SetUniform3##func(const char *uniform_name,type v0,type v1,type v2) \
|
||||
{ \
|
||||
const int location=GetUniformLocation(uniform_name); \
|
||||
\
|
||||
if(location==-1)return(false); \
|
||||
\
|
||||
return SetUniform3##func(location,v0,v1,v2); \
|
||||
} \
|
||||
\
|
||||
bool Shader::SetUniform4##func(const char *uniform_name,type v0,type v1,type v2,type v3) \
|
||||
{ \
|
||||
const int location=GetUniformLocation(uniform_name); \
|
||||
\
|
||||
if(location==-1)return(false); \
|
||||
\
|
||||
return SetUniform4##func(location,v0,v1,v2,v3); \
|
||||
}
|
||||
HGL_GLSL_SetUniform1234(f,float);
|
||||
HGL_GLSL_SetUniform1234(i,int);
|
||||
HGL_GLSL_SetUniform1234(ui,unsigned int);
|
||||
|
||||
#undef HGL_GLSL_SetUniform1234
|
||||
|
||||
#define HGL_GLSL_SetUniformPointer(func,type) bool Shader::SetUniform##func(const char *uniform_name,const type *value) \
|
||||
{ \
|
||||
const int location=GetUniformLocation(uniform_name); \
|
||||
\
|
||||
if(location==-1)return(false); \
|
||||
\
|
||||
return SetUniform##func(location,value); \
|
||||
}
|
||||
|
||||
HGL_GLSL_SetUniformPointer(1fv,float);
|
||||
HGL_GLSL_SetUniformPointer(2fv,float);
|
||||
HGL_GLSL_SetUniformPointer(3fv,float);
|
||||
HGL_GLSL_SetUniformPointer(4fv,float);
|
||||
|
||||
HGL_GLSL_SetUniformPointer(1iv,int);
|
||||
HGL_GLSL_SetUniformPointer(2iv,int);
|
||||
HGL_GLSL_SetUniformPointer(3iv,int);
|
||||
HGL_GLSL_SetUniformPointer(4iv,int);
|
||||
|
||||
HGL_GLSL_SetUniformPointer(1uiv,unsigned int);
|
||||
HGL_GLSL_SetUniformPointer(2uiv,unsigned int);
|
||||
HGL_GLSL_SetUniformPointer(3uiv,unsigned int);
|
||||
HGL_GLSL_SetUniformPointer(4uiv,unsigned int);
|
||||
|
||||
#undef HGL_GLSL_SetUniformPointer
|
||||
|
||||
#define HGL_GLSL_SetUniformMatrixPointer(func) bool Shader::SetUniformMatrix##func(const char *uniform_name,const float *mat) \
|
||||
{ \
|
||||
const int location=GetUniformLocation(uniform_name); \
|
||||
\
|
||||
if(location==-1)return(false); \
|
||||
\
|
||||
return SetUniformMatrix##func(location,mat); \
|
||||
}
|
||||
|
||||
HGL_GLSL_SetUniformMatrixPointer(2fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(3fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(4fv);
|
||||
|
||||
HGL_GLSL_SetUniformMatrixPointer(2x3fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(3x2fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(2x4fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(4x2fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(3x4fv);
|
||||
HGL_GLSL_SetUniformMatrixPointer(4x3fv);
|
||||
|
||||
#undef HGL_GLSL_SetUniformMatrixPointer
|
||||
|
||||
// /**
|
||||
// * 取得一个Shader只读数据区的访问对象
|
||||
// * @param name 对象名称
|
||||
// * @param level 访问级别
|
||||
// * @return 对象指针
|
||||
// */
|
||||
// UBO *Shader::GetUniformBlock(const char *name,uint level)
|
||||
// {
|
||||
// if(!name||!(*name))
|
||||
// {
|
||||
// LOG_ERROR(U8_TEXT("UBO name error:"));
|
||||
// return(nullptr);
|
||||
// }
|
||||
//
|
||||
// UBO *ubo=uniform_block_object[name];
|
||||
//
|
||||
// if(ubo)
|
||||
// return ubo;
|
||||
//
|
||||
// const int index=GetUniformBlockIndex(name);
|
||||
//
|
||||
// if(index<0)
|
||||
// {
|
||||
// LOG_ERROR(U8_TEXT("UBO name error:")+UTF8String(name));
|
||||
// return(nullptr);
|
||||
// }
|
||||
//
|
||||
// ubo=new UBO(name,program,index,level);
|
||||
//
|
||||
// uniform_block_object.Add(name,ubo);
|
||||
//
|
||||
// return ubo;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 取得一个Shader数据存储区的访问对象
|
||||
// * @param name 对象名称
|
||||
// * @param level 访问级别
|
||||
// * @return 对象指针
|
||||
// */
|
||||
// SSBO *Shader::GetShaderStorage(const char *name,uint level)
|
||||
// {
|
||||
// if(!name||!(*name))
|
||||
// {
|
||||
// LOG_ERROR(U8_TEXT("SSBO name error:"));
|
||||
// return(nullptr);
|
||||
// }
|
||||
//
|
||||
// SSBO *ssbo=ssbo_object[name];
|
||||
//
|
||||
// if(ssbo)
|
||||
// return ssbo;
|
||||
//
|
||||
// const int index=GetShaderStorageIndex(name);
|
||||
//
|
||||
// if(index<0)
|
||||
// {
|
||||
// LOG_ERROR(U8_TEXT("SSBO name error:")+UTF8String(name));
|
||||
// return(nullptr);
|
||||
// }
|
||||
//
|
||||
// ssbo=new SSBO(name,program,index,level);
|
||||
//
|
||||
// ssbo_object.Add(name,ssbo);
|
||||
//
|
||||
// return ssbo;
|
||||
// }
|
||||
}//namespace hgl
|
Loading…
x
Reference in New Issue
Block a user