List删除不合理设计的[]操作符重载

This commit is contained in:
hyzboy 2018-11-28 20:56:55 +08:00
parent 52fb2eed7e
commit 5c3caf4111
25 changed files with 3606 additions and 48 deletions

View File

@ -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) { \

View File

@ -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
View 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

View File

@ -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(); ///<尝试取得控制权

View File

@ -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);
}
/**

View File

@ -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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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

View File

@ -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
View 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
View 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

View File

@ -1,2 +1,2 @@
add_subdirectory(RenderDevice)
# add_subdirectory(RenderDriver)
add_subdirectory(RenderDriver)

View File

@ -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
View 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
View 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