增加部分基础库头文件
This commit is contained in:
parent
3ece9c2df0
commit
c57b441070
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
PROJECT(ULRE)
|
||||
|
||||
@ -14,4 +14,9 @@ check_system_version()
|
||||
set_compiler_param()
|
||||
set_output_directory()
|
||||
|
||||
include_directories(3rdpty/MathGeoLib/src)
|
||||
include_directories(inc)
|
||||
|
||||
add_subdirectory(3rdpty/MathGeoLib)
|
||||
|
||||
add_subdirectory(example)
|
||||
|
1
example/CMakeLists.txt
Normal file
1
example/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
add_subdirectory(NullWindow)
|
3
example/NullWindow/CMakeLists.txt
Normal file
3
example/NullWindow/CMakeLists.txt
Normal file
@ -0,0 +1,3 @@
|
||||
add_executable(NullWindow main.cpp)
|
||||
|
||||
target_link_libraries(NullWindow PRIVATE MathGeoLib)
|
7
example/NullWindow/main.cpp
Normal file
7
example/NullWindow/main.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include<iostream>
|
||||
|
||||
int main(int,char **)
|
||||
{
|
||||
std::cout<<"hello,world!"<<std::endl;
|
||||
return 0;
|
||||
}
|
16
inc/hgl/CompOperator.h
Normal file
16
inc/hgl/CompOperator.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef HGL_COMP_OPERATOR_INCLUDE
|
||||
#define HGL_COMP_OPERATOR_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
#define CompOperator(name,compfunc) const bool operator > (name i)const {return compfunc(i)>0;} \
|
||||
const bool operator < (name i)const {return compfunc(i)<0;} \
|
||||
const bool operator >=(name i)const {return compfunc(i)>=0;}\
|
||||
const bool operator <=(name i)const {return compfunc(i)<=0;}\
|
||||
const bool operator ==(name i)const {return compfunc(i)==0;}\
|
||||
const bool operator !=(name i)const {return compfunc(i)!=0;}
|
||||
|
||||
#define CompOperatorMemcmp(name) int _Comp(name data)const{return memcmp(this,&data,sizeof(name));} \
|
||||
CompOperator(name,_Comp)
|
||||
}//namespace hgl
|
||||
#endif//HGL_COMP_OPERATOR_INCLUDE
|
120
inc/hgl/Macro.h
Normal file
120
inc/hgl/Macro.h
Normal file
@ -0,0 +1,120 @@
|
||||
#ifndef HGL_MACRO_INCLUDE
|
||||
#define HGL_MACRO_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
#define RETURN_OBJECT_OF_ARRAY(array,index,max_count) return (index<0||index>=max_count)?nullptr:array[index];
|
||||
|
||||
#define NEW_NULL_ARRAY(name,type,count) { \
|
||||
name=new type[count]; \
|
||||
\
|
||||
memset(name,0,sizeof(type)*count); \
|
||||
}
|
||||
|
||||
#define SAFE_CLEAR(name) { \
|
||||
if(name) \
|
||||
{ \
|
||||
delete name; \
|
||||
name=nullptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SAFE_CLEAR_ARRAY(name) { \
|
||||
if(name) \
|
||||
{ \
|
||||
delete[] name; \
|
||||
name=nullptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SAFE_CLEAR_OBJECT_ARRAY(name,num) { \
|
||||
if(name&&num>=0) \
|
||||
{ \
|
||||
int safe_clear_object_array_number=num; \
|
||||
\
|
||||
while(safe_clear_object_array_number--) \
|
||||
if(name[safe_clear_object_array_number]) \
|
||||
delete name[safe_clear_object_array_number]; \
|
||||
\
|
||||
delete[] name; \
|
||||
name=nullptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FREE_OBJECT_ARRAY(name,num) { \
|
||||
if(name&&num>=0) \
|
||||
{ \
|
||||
int free_object_array_number=num; \
|
||||
\
|
||||
while(free_object_array_number--) \
|
||||
if(name[free_object_array_number]) \
|
||||
delete name[free_object_array_number]; \
|
||||
\
|
||||
cm_free(name); \
|
||||
name=nullptr; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SAFE_FREE_OBJECT_ARRAY(name,num) { \
|
||||
if(name) \
|
||||
FREE_OBJECT_ARRAY(name,num); \
|
||||
}
|
||||
|
||||
#define SAFE_FREE(name) { \
|
||||
if(name) \
|
||||
cm_free(name); \
|
||||
}
|
||||
|
||||
#define SAFE_RECREATE(name,code) { \
|
||||
if(name) \
|
||||
delete name; \
|
||||
\
|
||||
name=code; \
|
||||
}
|
||||
|
||||
#define ARRAY_CALL(name,num,code) { \
|
||||
int array_call_number=num; \
|
||||
\
|
||||
while(array_call_number--) \
|
||||
name[array_call_number]->code; \
|
||||
}
|
||||
|
||||
#define LOAD_FUNC(type,func) type func(void *buf,int buf_size) \
|
||||
{ \
|
||||
if(!buf||buf_size<=0)return 0; \
|
||||
\
|
||||
MemoryInputStream ms(buf,buf_size); \
|
||||
\
|
||||
return(func(&ms)); \
|
||||
} \
|
||||
\
|
||||
type func(const UTF16String &filename) \
|
||||
{ \
|
||||
FileInputStream fs; \
|
||||
\
|
||||
if(fs.Open(filename)) \
|
||||
return(func(&fs)); \
|
||||
else \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#define SAVE_FUNC(type,func) bool func(type data,void *buf,int buf_size) \
|
||||
{ \
|
||||
if(!buf||buf_size<=0)return(false); \
|
||||
\
|
||||
MemoryOutputStream ms(buf,buf_size); \
|
||||
\
|
||||
return(func(data,&ms)); \
|
||||
} \
|
||||
\
|
||||
bool func(type data,const UTF16String &filename) \
|
||||
{ \
|
||||
FileOutputStream fs; \
|
||||
\
|
||||
if(fs.CreateTrunc(filename)) \
|
||||
return(func(data,&fs)); \
|
||||
else \
|
||||
return(false); \
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_MACRO_INCLUDE
|
2370
inc/hgl/Str.h
Normal file
2370
inc/hgl/Str.h
Normal file
File diff suppressed because it is too large
Load Diff
611
inc/hgl/TypeFunc.h
Normal file
611
inc/hgl/TypeFunc.h
Normal file
@ -0,0 +1,611 @@
|
||||
#ifndef HGL_TYPE_FUNC_INCLUDE
|
||||
#define HGL_TYPE_FUNC_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
#include<math.h>
|
||||
namespace hgl
|
||||
{
|
||||
#define HGL_CONVER_TO_MEM_ALIGN(x) ((((x)+HGL_MEM_ALIGN-1)/HGL_MEM_ALIGN)*HGL_MEM_ALIGN) //内存对齐转换宏
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif//
|
||||
|
||||
template<typename T>
|
||||
inline T *zero_new(const int count)
|
||||
{
|
||||
T *result=new T[count];
|
||||
|
||||
if(!result)
|
||||
return(nullptr);
|
||||
|
||||
memset(result,0,count*sizeof(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T *zero_malloc(const int count)
|
||||
{
|
||||
T *result=hgl_malloc(count*sizeof(T));
|
||||
|
||||
if(!result)
|
||||
return(nullptr);
|
||||
|
||||
memset(result,0,count*sizeof(T));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void hgl_call_construct(T *obj) //呼叫构造函数
|
||||
{
|
||||
new (static_cast<void *>(obj)) T();
|
||||
}
|
||||
|
||||
#define HGL_BIT(n) (1<<(n))
|
||||
#define HGL_64BIT(n) (1L<<(n))
|
||||
|
||||
template<typename T>
|
||||
inline bool hgl_is_one(const T value,int off)
|
||||
{
|
||||
return value&(1<<off);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool hgl_is_zero(const T value,int off)
|
||||
{
|
||||
return !(value&(1<<off));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void hgl_set_one(T &value,int off)
|
||||
{
|
||||
value|=(1<<off);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void hgl_set_zero(T &value,int off)
|
||||
{
|
||||
value&=~T(1<<off);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void hgl_set_bit(T &value,int off,bool b)
|
||||
{
|
||||
if(b)
|
||||
hgl_set_one(value,off);
|
||||
else
|
||||
hgl_set_zero(value,off);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline int hgl_bit_count(const T value)
|
||||
{
|
||||
int count=0;
|
||||
T bit=1;
|
||||
|
||||
for(int i=0;i<sizeof(T);i++)
|
||||
{
|
||||
if(value&bit)
|
||||
++count;
|
||||
|
||||
bit<<=1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline int hgl_bit_count(const T value,int size)
|
||||
{
|
||||
int count=0;
|
||||
T bit=1;
|
||||
|
||||
for(int i=0;i<size;i++)
|
||||
{
|
||||
if(value&bit)
|
||||
++count;
|
||||
|
||||
bit<<=1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#define DEF_RGB_U8_TO_F(r,g,b) {float(r)/255.0f,float(g)/255.0f,float(b)/255.0f}
|
||||
#define DEF_RGBA_U8_TO_F(r,g,b,a) {float(r)/255.0f,float(g)/255.0f,float(b)/255.0f,float(a)/255.0f}
|
||||
|
||||
constexpr uint HGL_SIZE_1KB =1024;
|
||||
constexpr uint HGL_SIZE_1MB =HGL_SIZE_1KB*1024;
|
||||
constexpr uint HGL_SIZE_1GB =HGL_SIZE_1MB*1024;
|
||||
constexpr uint64 HGL_SIZE_1TB =HGL_SIZE_1GB*1024ULL;
|
||||
constexpr uint64 HGL_SIZE_1PB =HGL_SIZE_1TB*1024ULL;
|
||||
constexpr uint64 HGL_SIZE_1EB =HGL_SIZE_1PB*1024ULL;
|
||||
// constexpr uint128 HGL_SIZE_1ZB =HGL_SIZE_1EB*1024ULL;
|
||||
// constexpr uint128 HGL_SIZE_1YB =HGL_SIZE_1ZB*1024ULL;
|
||||
|
||||
constexpr uint8 HGL_U8_MAX =0xFF;
|
||||
constexpr uint16 HGL_U16_MAX =0xFFFF;
|
||||
constexpr uint32 HGL_U32_MAX =0xFFFFFFFF;
|
||||
constexpr uint64 HGL_U64_MAX =0xFFFFFFFFFFFFFFFFULL;
|
||||
|
||||
constexpr int8 HGL_S8_MAX =0x7F;
|
||||
constexpr int16 HGL_S16_MAX =0x7FFF;
|
||||
constexpr int32 HGL_S32_MAX =0x7FFFFFFF;
|
||||
constexpr int64 HGL_S64_MAX =0x7FFFFFFFFFFFFFFFLL;
|
||||
|
||||
constexpr int8 HGL_S8_MIN =(-0x80);
|
||||
constexpr int16 HGL_S16_MIN =(-0x8000);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
constexpr int32 HGL_S32_MIN =(-0x80000000i32);
|
||||
constexpr int64 HGL_S64_MIN =(-0x8000000000000000i64);
|
||||
#else
|
||||
constexpr int32 HGL_S32_MIN =(-0x80000000L);
|
||||
constexpr int64 HGL_S64_MIN =(-0x8000000000000000LL);
|
||||
#endif//_MSC_VER
|
||||
|
||||
template<typename T> T HGL_INTEGER_MAX();
|
||||
template<typename T> T HGL_INTEGER_MIN();
|
||||
|
||||
template<> inline uint8 HGL_INTEGER_MAX<uint8 >() { return HGL_U8_MAX; }
|
||||
template<> inline uint16 HGL_INTEGER_MAX<uint16 >() { return HGL_U16_MAX; }
|
||||
template<> inline uint32 HGL_INTEGER_MAX<uint32 >() { return HGL_U32_MAX; }
|
||||
template<> inline uint64 HGL_INTEGER_MAX<uint64 >() { return HGL_U64_MAX; }
|
||||
|
||||
template<> inline int8 HGL_INTEGER_MAX<int8 >() { return HGL_S8_MAX; }
|
||||
template<> inline int16 HGL_INTEGER_MAX<int16 >() { return HGL_S16_MAX; }
|
||||
template<> inline int32 HGL_INTEGER_MAX<int32 >() { return HGL_S32_MAX; }
|
||||
template<> inline int64 HGL_INTEGER_MAX<int64 >() { return HGL_S64_MAX; }
|
||||
|
||||
template<> inline int8 HGL_INTEGER_MIN<int8 >() { return HGL_S8_MIN; }
|
||||
template<> inline int16 HGL_INTEGER_MIN<int16 >() { return HGL_S16_MIN; }
|
||||
template<> inline int32 HGL_INTEGER_MIN<int32 >() { return HGL_S32_MIN; }
|
||||
template<> inline int64 HGL_INTEGER_MIN<int64 >() { return HGL_S64_MIN; }
|
||||
|
||||
/**
|
||||
* 星期每天枚举
|
||||
*/
|
||||
enum WeekDay
|
||||
{
|
||||
weekNone=-1,
|
||||
|
||||
weekSunday, ///<星期天
|
||||
weekMonday, ///<星期一
|
||||
weekTuesday, ///<星期二
|
||||
weekWednesday, ///<星期三
|
||||
weekThursday, ///<星期四
|
||||
weekFriday, ///<星期五
|
||||
weekSaturday, ///<星期六
|
||||
|
||||
weekEnd
|
||||
};
|
||||
|
||||
/**
|
||||
* 月份枚举
|
||||
*/
|
||||
enum Month
|
||||
{
|
||||
monthNone=0,
|
||||
|
||||
monthJanuary, ///<一月
|
||||
monthFebruary, ///<二月
|
||||
monthMarch, ///<三月
|
||||
monthApril, ///<四月
|
||||
monthMay, ///<五月
|
||||
monthJune, ///<六月
|
||||
monthJuly, ///<七月
|
||||
monthAugust, ///<八月
|
||||
monthSeptember, ///<九月
|
||||
monthOctober, ///<十月
|
||||
monthNovember, ///<十一月
|
||||
monthDecember, ///<十二月
|
||||
|
||||
monthEnd
|
||||
};
|
||||
|
||||
constexpr uint HGL_TIME_ONE_SECOND =1;
|
||||
constexpr uint HGL_TIME_HALF_MINUTE =30;
|
||||
constexpr uint HGL_TIME_ONE_MINUTE =60;
|
||||
constexpr uint HGL_TIME_HALF_HOUR =30*HGL_TIME_ONE_MINUTE;
|
||||
constexpr uint HGL_TIME_ONE_HOUR =60*HGL_TIME_ONE_MINUTE;
|
||||
constexpr uint HGL_TIME_HALF_DAY =12*HGL_TIME_ONE_HOUR;
|
||||
constexpr uint HGL_TIME_ONE_DAY =24*HGL_TIME_ONE_HOUR;
|
||||
constexpr uint HGL_TIME_ONE_WEEK =7*HGL_TIME_ONE_DAY;
|
||||
constexpr uint HGL_TIME_ONE_YEAR =365*HGL_TIME_ONE_DAY;
|
||||
|
||||
constexpr uint HGL_HOUR_HALF_DAY =12;
|
||||
constexpr uint HGL_HOUR_ONE_DAY =24;
|
||||
|
||||
constexpr uint HGL_DAY_ONE_WEEK =7;
|
||||
constexpr uint HGL_DAY_ONE_YEAR =365;
|
||||
|
||||
constexpr uint HGL_MONTH_ONE_YEAR =12;
|
||||
|
||||
constexpr uint HGL_MILLI_SEC_PRE_SEC =1000; //毫秒
|
||||
constexpr uint HGL_MICRO_SEC_PER_SEC =1000*1000; //微秒
|
||||
constexpr uint HGL_NANO_SEC_PER_SEC =1000*1000*1000; //纳秒
|
||||
|
||||
constexpr char LowerHexChar[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; ///<小写16进制字符
|
||||
constexpr char UpperHexChar[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; ///<大写16进制字符
|
||||
|
||||
constexpr double HGL_E =2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274; //欧拉数(自然对数的底数)
|
||||
constexpr double HGL_LOG2E =1.44269504088896340736;
|
||||
constexpr double HGL_LOG10E =0.434294481903251827651;
|
||||
constexpr double HGL_LN2 =0.693147180559945309417;
|
||||
constexpr double HGL_LN10 =2.30258509299404568402;
|
||||
constexpr double HGL_PI =3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068;
|
||||
constexpr double HGL_PI_2 =1.57079632679489661923;
|
||||
constexpr double HGL_PI_4 =0.785398163397448309616;
|
||||
constexpr double HGL_PI_3_4 =2.356194490192344928938;
|
||||
constexpr double HGL_1_PI =0.318309886183790671538;
|
||||
constexpr double HGL_2_PI =0.636619772367581343076;
|
||||
constexpr double HGL_2_SQRTPI =1.12837916709551257390;
|
||||
constexpr double HGL_SQRT2 =1.41421356237309504880168872420969807;
|
||||
constexpr double HGL_SQRT1_2 =0.707106781186547524401;
|
||||
|
||||
constexpr double HGL_COS_ANG_0 =1;
|
||||
constexpr double HGL_COS_ANG_45 =0.707106781187;
|
||||
constexpr double HGL_COS_ANG_90 =0;
|
||||
constexpr double HGL_COS_ANG_135=-0.707106781187;
|
||||
constexpr double HGL_COS_ANG_180=-1;
|
||||
constexpr double HGL_COS_ANG_225=-0.707106781187;
|
||||
constexpr double HGL_COS_ANG_270=0;
|
||||
constexpr double HGL_COS_ANG_315=0.707106781187;
|
||||
|
||||
constexpr double HGL_GOLDEN_RATIO =0.61803398874989484820458683436563811772030917980576;//黄金比例
|
||||
constexpr double HGL_SILVER_RATIO =2.4142135623730950488; //白银比例
|
||||
|
||||
constexpr double HGL_SPEED_OF_SOUND =331.3f; //音速(米/秒)
|
||||
constexpr double HGL_SPEED_OF_LIGHT =299792458; //光速(米/秒)
|
||||
|
||||
constexpr double HGL_ABSOLUTE_ZERO =-273.15f; //绝对零度
|
||||
|
||||
constexpr double HGL_UNIVERSAL_GRAVITATION =6.67384e-11; //万有引力常数
|
||||
|
||||
constexpr double HGL_EARTH_GRAVITATIONAL_ACCELERATION =9.80665; //地球上的重力加速度(牛顿)
|
||||
constexpr double HGL_EARTH_MASS =5.9722e+24; //地球质量
|
||||
constexpr double HGL_EARTH_RADIUS =6371000; //地球半径(米)
|
||||
|
||||
/**
|
||||
* 物体万有引力计算
|
||||
* @param m1 星球质量
|
||||
* @param m2 物体质量
|
||||
* @param length 到星球中心的距离
|
||||
*/
|
||||
template<typename T>
|
||||
inline T UniversalGravitation(const T m1,const T m2,const T length)
|
||||
{
|
||||
return HGL_UNIVERSAL_GRAVITATION*((m1*m2)/(length*length));
|
||||
}
|
||||
|
||||
/**
|
||||
* 星球重力加速度计算<br>
|
||||
* 理论上: (地球质量*万有引力常数)/(地球半径的平方)=地球上的重力加速度
|
||||
* @param m 星球质量
|
||||
* @param raidus 星球半径
|
||||
* @return 星球的重力加速度(牛顿)
|
||||
*/
|
||||
template<typename T>
|
||||
inline T UniversalGravitation(const T m,const T radius)
|
||||
{
|
||||
return (HGL_UNIVERSAL_GRAVITATION*m)/(radius*radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向心力计算
|
||||
* @param m 质量
|
||||
* @param v 速度
|
||||
* @param r 距离
|
||||
*/
|
||||
template<typename T>
|
||||
inline T CentripetalForce(const T m,const T v,const T r)
|
||||
{
|
||||
return (m*v*v)/r;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加速度计算
|
||||
* @param power 推力
|
||||
* @param weight 质量
|
||||
*/
|
||||
template<typename T>
|
||||
inline T AddSpeed(const T &power,const T &weight)
|
||||
{
|
||||
return power/weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 物体运动质量计算(物体运动越快,质量越大)
|
||||
* @param m0 静止质量
|
||||
* @param v 运动速度
|
||||
*/
|
||||
template<typename T>
|
||||
inline T RunWeight(const T &m0,const T &v)
|
||||
{
|
||||
return m0/sqrt(1-(v*v)/(HGL_SPEED_OF_LIGHT*HGL_SPEED_OF_LIGHT));
|
||||
}
|
||||
|
||||
inline float half_to_float(const uint16 &h)
|
||||
{
|
||||
return ((h&0x8000)<<16) | (((h&0x7c00)+0x1C000)<<13) | ((h&0x03FF)<<13);
|
||||
}
|
||||
|
||||
inline uint16 float_to_half(const float &f)
|
||||
{
|
||||
const uint32 x = *((uint32 *)&f);
|
||||
|
||||
return ((x>>16)&0x8000)|((((x&0x7f800000)-0x38000000)>>13)&0x7c00)|((x>>13)&0x03ff);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正圆面积计算
|
||||
* @param radius 半径
|
||||
*/
|
||||
inline double CircleArea(const double radius)
|
||||
{
|
||||
return(radius*radius*HGL_PI);
|
||||
}
|
||||
|
||||
/**
|
||||
* 椭圆面积计算
|
||||
* @param l_radius 长半径
|
||||
* @param s_radius 短半径
|
||||
*/
|
||||
inline double ElipseArea(const double l_radius,const double s_radius)
|
||||
{
|
||||
return(l_radius*s_radius*HGL_PI);
|
||||
}
|
||||
|
||||
/**
|
||||
* 球体积计算
|
||||
* @param radius 球半径
|
||||
*/
|
||||
inline double SphereVolume(const double radius)
|
||||
{
|
||||
return(radius*radius*radius*(HGL_PI*4.0f))/3.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* 椭球体积计算
|
||||
* @param x_radius x半径
|
||||
* @param y_radius y半径
|
||||
* @param z_radius z半径
|
||||
*/
|
||||
inline double EllipsoidVolume(const double x_radius,const double y_radius,const double z_radius)
|
||||
{
|
||||
return(x_radius*y_radius*z_radius*(HGL_PI*4.0f))/3.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取适合正巧大于当前数的2次幂值
|
||||
*/
|
||||
template<typename T>
|
||||
inline T power_to_2(T value)
|
||||
{
|
||||
T result=1;
|
||||
|
||||
while(result<value)
|
||||
result<<=1;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
template<typename T> inline void hgl_swap(T &x,T &y)
|
||||
{
|
||||
T t;
|
||||
|
||||
memcpy(&t,&x,sizeof(T));
|
||||
memcpy(&x,&y,sizeof(T));
|
||||
memcpy(&y,&t,sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T> inline T hgl_abs(const T &v){return (v>=0?v:-v);}
|
||||
|
||||
template<typename T> inline T hgl_min(const T &a,const T &b){return (a>b?b:a);}
|
||||
template<typename T> inline T hgl_max(const T &a,const T &b){return (a>b?a:b);}
|
||||
|
||||
template<typename T> inline T hgl_min(const T *data,int count,T min_value)
|
||||
{
|
||||
T value=min_value;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(*data<value)
|
||||
value=*data;
|
||||
|
||||
++data;
|
||||
}
|
||||
|
||||
return(value);
|
||||
}
|
||||
|
||||
template<typename T> inline T hgl_max(const T *data,int count,T max_value)
|
||||
{
|
||||
T value=max_value;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if(*data>value)
|
||||
value=*data;
|
||||
|
||||
++data;
|
||||
}
|
||||
|
||||
return(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角度转弧度
|
||||
*/
|
||||
inline double hgl_ang2rad(const double ang)
|
||||
{
|
||||
return ang*(HGL_PI/180.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 弧度转角度
|
||||
*/
|
||||
inline double hgl_rad2ang(const double rad)
|
||||
{
|
||||
return rad*(180.0f/HGL_PI);
|
||||
}
|
||||
|
||||
/**
|
||||
* 浮点数截取小数点后指定位度
|
||||
* @param value 要截取的浮点数
|
||||
* @param num 要截取的位数
|
||||
*/
|
||||
template<typename T>
|
||||
inline T hgl_clip_float(const T value,const int num)
|
||||
{
|
||||
if(num<=0)
|
||||
return int64(value);
|
||||
|
||||
if(value==0)return(0);
|
||||
|
||||
double per=pow(10,num);
|
||||
|
||||
return double(floor(value*per))/per;
|
||||
}
|
||||
|
||||
/**
|
||||
* 等值类型复制
|
||||
*/
|
||||
template<typename T>
|
||||
inline void hgl_cpy(T &dst,const T &src)
|
||||
{
|
||||
memcpy(&dst,&src,sizeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* 不同类型数据块复制
|
||||
*/
|
||||
template<typename S,typename D>
|
||||
inline void hgl_cpy(D *dst,const S *src,const size_t count)
|
||||
{
|
||||
for(size_t i=0;i<count;i++)
|
||||
{
|
||||
*dst=D(*src);
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同类型数据块复制
|
||||
*/
|
||||
template<typename T>
|
||||
inline void hgl_typecpy(T *dst,const T *src,const size_t count)
|
||||
{
|
||||
memcpy(dst,src,count*sizeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* 同类型数据块移动
|
||||
*/
|
||||
template<typename T>
|
||||
inline void hgl_typemove(T *dst,const T *src,const size_t count)
|
||||
{
|
||||
memmove(dst,src,count*sizeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定类型数据块赋值
|
||||
*/
|
||||
template<typename T>
|
||||
inline void hgl_set(T *data,const T value,const size_t count)
|
||||
{
|
||||
for(size_t i=0;i<count;i++)
|
||||
{
|
||||
*data=value;
|
||||
++data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定类型数据块清0
|
||||
*/
|
||||
template<typename T>
|
||||
inline void hgl_zero(T *data,const size_t count)
|
||||
{
|
||||
memset(data,0,count*sizeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定类型数据清0
|
||||
*/
|
||||
template<typename T>
|
||||
inline void hgl_zero(T &data)
|
||||
{
|
||||
memset(&data,0,sizeof(T));
|
||||
}
|
||||
}//namespace hgl
|
||||
|
||||
/**
|
||||
* 比较处理模板基类
|
||||
*/
|
||||
template<typename T> class Comparator ///比较处理模板基类
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 比较函数,需被特例化或派生实现
|
||||
*/
|
||||
virtual int compare(const T &a,const T &b)const
|
||||
{
|
||||
return 0; // 如 return(a-b); ,但这个函数正确情况下不应该会被调用
|
||||
}
|
||||
|
||||
/**
|
||||
* 交换函数
|
||||
*/
|
||||
virtual void exchange(T &a,T &b)
|
||||
{
|
||||
T t;
|
||||
|
||||
memcpy(&t,&a,sizeof(T));
|
||||
memcpy(&a,&b,sizeof(T));
|
||||
memcpy(&b,&t,sizeof(T));
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制数据
|
||||
*/
|
||||
virtual void cpy(T *t,T *s)
|
||||
{
|
||||
memcpy(t,s,sizeof(T));
|
||||
}
|
||||
};//class Comparator
|
||||
|
||||
//针对原生类型的特例化版本,做适当加速
|
||||
#define COMPARATOR_ORIGIN_TYPE(type) template<> class Comparator<type> \
|
||||
{ \
|
||||
public: \
|
||||
int compare(const type &a,const type &b)const{return a-b;} \
|
||||
void exchange(type &a,type &b){type t;t=a;a=b;b=t;} \
|
||||
void cpy(type *t,type *s){*t=*s;} \
|
||||
};
|
||||
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::int8)
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::int16)
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::int32)
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::int64)
|
||||
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::uint8)
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::uint16)
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::uint32)
|
||||
COMPARATOR_ORIGIN_TYPE(hgl::uint64)
|
||||
|
||||
COMPARATOR_ORIGIN_TYPE(float)
|
||||
COMPARATOR_ORIGIN_TYPE(double)
|
||||
|
||||
COMPARATOR_ORIGIN_TYPE(char)
|
||||
COMPARATOR_ORIGIN_TYPE(wchar_t)
|
||||
|
||||
#if HGL_OS != HGL_OS_Windows
|
||||
COMPARATOR_ORIGIN_TYPE(u16char)
|
||||
#endif//HGL_OS != HGL_OS_Windows
|
||||
|
||||
COMPARATOR_ORIGIN_TYPE(char32_t)
|
||||
#undef COMPARATOR_ORIGIN_TYPE
|
||||
#endif//HGL_TYPE_FUNC_INCLUDE
|
155
inc/hgl/algorithm/Math.h
Normal file
155
inc/hgl/algorithm/Math.h
Normal file
@ -0,0 +1,155 @@
|
||||
#ifndef HGL_ALGORITHM_VECTOR_MATH_INCLUDE
|
||||
#define HGL_ALGORITHM_VECTOR_MATH_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
|
||||
//注:GLM/CML(OpenGLMode)是列矩阵,计算坐标matrix*pos
|
||||
// 而MGL是行矩阵,需要反过来pos*matrix
|
||||
|
||||
#include<hgl/algorithm/MathMGL.h> // Game Math and Geometry Library
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace algorithm
|
||||
{
|
||||
double Lsin(int angle); ///<低精度sin计算,注意传入的参数为角度而非弧度
|
||||
double Lcos(int angle); ///<低精度cos计算,注意传入的参数为角度而非弧度
|
||||
void Lsincos(int angle, double &s, double &c); ///<低精度sin+cos计算,注意传入的参数为角度而非弧度
|
||||
|
||||
/**
|
||||
* 低精度atan函数
|
||||
*/
|
||||
double inline Latan(double z)
|
||||
{
|
||||
constexpr double n1 = 0.97239411f;
|
||||
constexpr double n2 = -0.19194795f;
|
||||
|
||||
return (n1 + n2 * z * z) * z;
|
||||
}
|
||||
|
||||
double Latan2(double y, double x); ///<低精度atan2函数
|
||||
|
||||
inline float length_squared(const Vector2f &v)
|
||||
{
|
||||
return (v.x*v.x) + (v.y*v.y);
|
||||
}
|
||||
|
||||
inline float length_squared_2d(const Vector3f &v)
|
||||
{
|
||||
return (v.x*v.x) + (v.y*v.y);
|
||||
}
|
||||
|
||||
inline float length_squared(const Vector3f &v)
|
||||
{
|
||||
return (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
|
||||
}
|
||||
|
||||
inline float length_squared(const Vector4f &v)
|
||||
{
|
||||
return (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline float length(const T &v)
|
||||
{
|
||||
return sqrt(length_squared(v));
|
||||
}
|
||||
|
||||
inline float length_2d(const Vector3f &v)
|
||||
{
|
||||
return sqrt(length_squared_2d(v));
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
inline float length_squared(const T1 &v1, const T2 &v2)
|
||||
{
|
||||
const float x = (v1.x - v2.x);
|
||||
const float y = (v1.y - v2.y);
|
||||
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
inline float length(const T1 &v1, const T2 &v2)
|
||||
{
|
||||
return sqrt(length_squared(v1, v2));
|
||||
}
|
||||
|
||||
inline float length_squared(const Vector3f &v1, const Vector3f &v2)
|
||||
{
|
||||
const float x = (v1.x - v2.x);
|
||||
const float y = (v1.y - v2.y);
|
||||
const float z = (v1.z - v2.z);
|
||||
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
inline float length_squared_2d(const T1 &v1, const T2 &v2)
|
||||
{
|
||||
const float x = (v1.x - v2.x);
|
||||
const float y = (v1.y - v2.y);
|
||||
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
inline float length(const Vector3f &v1, const Vector3f &v2)
|
||||
{
|
||||
return sqrt(length_squared(v1, v2));
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
inline float length_2d(const T1 &v1, const T2 &v2)
|
||||
{
|
||||
return sqrt(length_squared_2d(v1, v2));
|
||||
}
|
||||
|
||||
inline Vector2f to(const Vector2f &start, const Vector2f &end, float pos)
|
||||
{
|
||||
return Vector2f(start.x + (end.x - start.x)*pos,
|
||||
start.y + (end.y - start.y)*pos);
|
||||
}
|
||||
|
||||
inline Vector3f to(const Vector3f &start, const Vector3f &end, float pos)
|
||||
{
|
||||
return Vector3f(start.x + (end.x - start.x)*pos,
|
||||
start.y + (end.y - start.y)*pos,
|
||||
start.z + (end.z - start.z)*pos);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void to_2d(T &result, const T &start, const T &end, float pos)
|
||||
{
|
||||
result.x = start.x + (end.x - start.x)*pos;
|
||||
result.y = start.y + (end.y - start.y)*pos;
|
||||
}
|
||||
|
||||
inline float ray_angle_cos(const Vector3f &ray_dir, const Vector3f &ray_pos, const Vector3f &pos)
|
||||
{
|
||||
return dot(ray_dir, normalized(pos - ray_pos));
|
||||
}
|
||||
|
||||
/**
|
||||
* 做一个2D旋转计算
|
||||
* @param result 结果
|
||||
* @param source 原始点坐标
|
||||
* @param center 圆心坐标
|
||||
* @param ang 旋转角度
|
||||
*/
|
||||
template<typename T1, typename T2, typename T3>
|
||||
inline void rotate2d(T1 &result, const T2 &source, const T3 ¢er, const double ang)
|
||||
{
|
||||
double as, ac;
|
||||
// double nx,ny;
|
||||
|
||||
// as=sin(ang*(HGL_PI/180.0f));
|
||||
// ac=cos(ang*(HGL_PI/180.0f));
|
||||
//sincos(ang*(HGL_PI/180.0f),&as,&ac); //在80x87指令上,sin/cos是一个指令同时得出sin和cos,所以可以这样做
|
||||
Lsincos(ang, as, ac); //低精度sin/cos计算
|
||||
|
||||
result.x = center.x + ((source.x - center.x)*ac - (source.y - center.y)*as);
|
||||
result.y = center.y + ((source.x - center.x)*as + (source.y - center.y)*ac);
|
||||
}
|
||||
}//namespace algorithm
|
||||
}//namespace hgl
|
||||
#endif//HGL_ALGORITHM_VECTOR_MATH_INCLUDE
|
205
inc/hgl/algorithm/MathMGL.h
Normal file
205
inc/hgl/algorithm/MathMGL.h
Normal file
@ -0,0 +1,205 @@
|
||||
#ifndef HGL_ALGORITHM_VECTOR_MATH_MGL_INCLUDE
|
||||
#define HGL_ALGORITHM_VECTOR_MATH_MGL_INCLUDE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244) // double -> int 精度丢失警告
|
||||
#endif//_MSC_VER
|
||||
|
||||
#include<MathGeoLib.h>
|
||||
|
||||
/**
|
||||
* MathGeoLib
|
||||
* Game Math and Geometry Library
|
||||
*
|
||||
* My C++ library for 3D mathematics and geometry manipulation.
|
||||
* Jukka Jylänki
|
||||
*
|
||||
* offical web: http://clb.demon.fi/MathGeoLib/nightly/
|
||||
*
|
||||
* License:
|
||||
*
|
||||
* This library is licensed under the Apache 2 license. I am not a lawyer, but to me that
|
||||
* license means that you can use this code for any purpose, both commercial and closed source.
|
||||
* You are however restricted from claiming you wrote it yourself, and cannot hold me liable
|
||||
* for anything over this code.
|
||||
* I acknowledge that most of the non-trivial math routines are taken off a book or a
|
||||
* research paper. In all places, I have tried to be diligent to properly attribute the original
|
||||
* source. Please contact me if you feel I have misattributed something.
|
||||
*/
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
using namespace math;
|
||||
|
||||
typedef float2 Vector2f;
|
||||
typedef float3 Vector3f;
|
||||
typedef float4 Vector4f;
|
||||
|
||||
typedef float3x3 Matrix3f;
|
||||
typedef float4x4 Matrix4f;
|
||||
|
||||
inline bool operator == (const Vector2f &lhs,const Vector2f &rhs)
|
||||
{
|
||||
if(lhs.x!=rhs.x)return(false);
|
||||
if(lhs.y!=rhs.y)return(false);
|
||||
return(true);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector2f &lhs,const Vector2f &rhs)
|
||||
{
|
||||
if(lhs.x!=rhs.x)return(true);
|
||||
if(lhs.y!=rhs.y)return(true);
|
||||
return(false);
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector3f &lhs,const Vector3f &rhs)
|
||||
{
|
||||
if(lhs.x!=rhs.x)return(false);
|
||||
if(lhs.y!=rhs.y)return(false);
|
||||
if(lhs.z!=rhs.z)return(false);
|
||||
return(true);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector3f &lhs,const Vector3f &rhs)
|
||||
{
|
||||
if(lhs.x!=rhs.x)return(true);
|
||||
if(lhs.y!=rhs.y)return(true);
|
||||
if(lhs.z!=rhs.z)return(true);
|
||||
return(false);
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector4f &lhs,const Vector4f &rhs)
|
||||
{
|
||||
if(lhs.x!=rhs.x)return(false);
|
||||
if(lhs.y!=rhs.y)return(false);
|
||||
if(lhs.z!=rhs.z)return(false);
|
||||
if(lhs.w!=rhs.w)return(false);
|
||||
return(true);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector4f &lhs,const Vector4f &rhs)
|
||||
{
|
||||
if(lhs.x!=rhs.x)return(true);
|
||||
if(lhs.y!=rhs.y)return(true);
|
||||
if(lhs.z!=rhs.z)return(true);
|
||||
if(lhs.w!=rhs.w)return(true);
|
||||
return(false);
|
||||
}
|
||||
|
||||
inline void vec3to2(Vector2f &dst,const Vector3f &src)
|
||||
{
|
||||
dst.x=src.x;
|
||||
dst.y=src.y;
|
||||
}
|
||||
|
||||
inline Vector2f vec3to2(const Vector3f &src)
|
||||
{
|
||||
return Vector2f(src.x,src.y);
|
||||
}
|
||||
|
||||
inline void vec2to3(Vector3f &dst,const Vector2f &src,const float z)
|
||||
{
|
||||
dst.x=src.x;
|
||||
dst.y=src.y;
|
||||
dst.z=z;
|
||||
}
|
||||
|
||||
inline Vector3f vec2to3(const Vector2f &src,const float z)
|
||||
{
|
||||
return Vector3f(src.x,src.y,z);
|
||||
}
|
||||
|
||||
inline Matrix4f identity()
|
||||
{
|
||||
return Matrix4f::identity;
|
||||
}
|
||||
|
||||
inline Matrix4f inverse(const Matrix4f &m)
|
||||
{
|
||||
return m.Inverted();
|
||||
}
|
||||
|
||||
inline Matrix4f ortho2d(float width,float height,float znear=0,float zfar=1)
|
||||
{
|
||||
//MathGeoLib生成的2D正交矩阵中心是0,0,所以需要偏移
|
||||
|
||||
return Matrix4f::OpenGLOrthoProjRH(znear,zfar,width,height)*Matrix4f::Scale(1,-1,1)*Matrix4f::Translate(-(width/2.0f),-(height/2.0f),0);
|
||||
}
|
||||
|
||||
inline Matrix4f translate(const Vector3f &v)
|
||||
{
|
||||
return Matrix4f::Translate(v);
|
||||
}
|
||||
|
||||
inline Matrix4f translate(float x,float y,float z)
|
||||
{
|
||||
return Matrix4f::Translate(x,y,z);
|
||||
}
|
||||
|
||||
inline Matrix4f scale(const Vector3f &v)
|
||||
{
|
||||
return Matrix4f::Scale(v,Vector3f::zero);
|
||||
}
|
||||
|
||||
inline Matrix4f scale(float x,float y,float z)
|
||||
{
|
||||
return Matrix4f::Scale(Vector3f(x,y,z),Vector3f::zero);
|
||||
}
|
||||
|
||||
inline Matrix4f scale(float s)
|
||||
{
|
||||
return Matrix4f::Scale(Vector3f(s,s,s),Vector3f::zero);
|
||||
}
|
||||
|
||||
inline Matrix4f rotate(float angle,const Vector3f &axis)
|
||||
{
|
||||
return Matrix4f::RotateAxisAngle(axis.Normalized(),angle);
|
||||
}
|
||||
|
||||
inline Matrix4f rotate(float angle,float x,float y,float z)
|
||||
{
|
||||
return rotate(angle,Vector3f(x,y,z));
|
||||
}
|
||||
|
||||
inline Matrix4f rotate(float angle,const Vector4f &axis)
|
||||
{
|
||||
return rotate(angle,Vector3f(axis.x,axis.y,axis.z));
|
||||
}
|
||||
|
||||
inline Vector3f rotate(const Vector3f &v3f,float angle,const Vector3f &axis)
|
||||
{
|
||||
Vector4f result=rotate(angle,axis)*Vector4f(v3f,1.0f);
|
||||
|
||||
return result.xyz();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T normalized(const T &v)
|
||||
{
|
||||
return v.Normalized();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void normalize(T &v)
|
||||
{
|
||||
v.Normalize();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T cross(const T &v1,const T &v2)
|
||||
{
|
||||
return v1.Cross(v2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline float dot(const T &v1,const T &v2)
|
||||
{
|
||||
return v1.Dot(v2);
|
||||
}
|
||||
|
||||
inline float ray_angle_cos(const Ray &ray,const vec &pos)
|
||||
{
|
||||
return ray.dir.Dot((pos-ray.pos).Normalized());
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_ALGORITHM_VECTOR_MATH_MGL_INCLUDE
|
275
inc/hgl/endian/Endian.h
Normal file
275
inc/hgl/endian/Endian.h
Normal file
@ -0,0 +1,275 @@
|
||||
#ifndef HGL_ENDIAN_INCLUDE
|
||||
#define HGL_ENDIAN_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h> // 平台定义
|
||||
namespace hgl
|
||||
{
|
||||
namespace endian
|
||||
{
|
||||
/**
|
||||
* Windows代码页枚举
|
||||
* 全部Windows所支持代码页请参见 http://msdn.microsoft.com/en-us/library/dd317756
|
||||
*/
|
||||
enum CharCodePage ///代码页枚举
|
||||
{
|
||||
ccpNone=0, ///<起始定义,无意义
|
||||
|
||||
//中文
|
||||
ccpGBK =936, ///<中国GBK标准中文
|
||||
ccpBig5 =950, ///<中国台湾Big5标准繁体中文
|
||||
ccpGB2312 =20936, ///<中国GB2312标准简体中文
|
||||
ccpGB18030 =54936, ///<中国GB18030-2000标准中文
|
||||
|
||||
//日文
|
||||
ccpShiftJIS =932, ///<日文ShiftJIS
|
||||
ccpJISX =50222, ///<日文JIS X/ISO 2022
|
||||
|
||||
//韩文
|
||||
ccpKorean =949, ///<韩文
|
||||
|
||||
//苹果编码
|
||||
ccpMacJanpan =10001, ///<日文
|
||||
ccpMacTraditionalChinese =10002, ///<繁体中文
|
||||
ccpMacSimplifiedChinese =10008, ///<简体中文
|
||||
|
||||
//unicode
|
||||
ccpUTF7 =65000, ///<utf-7
|
||||
ccpUTF8 =65001, ///<utf-8
|
||||
|
||||
ccpUTF16LE =1200,
|
||||
ccpUTF16BE =1201,
|
||||
ccpUTF32LE =12000,
|
||||
ccpUTF32BE =12001,
|
||||
|
||||
ccpEnd ///<结束定义,无意义
|
||||
};//enum CharCodePage
|
||||
|
||||
/**
|
||||
* 字节序类型枚举
|
||||
*/
|
||||
enum ByteOrderMask
|
||||
{
|
||||
bomNone=0,
|
||||
bomUTF8,
|
||||
bomUTF16LE,
|
||||
bomUTF16BE,
|
||||
bomUTF32LE,
|
||||
bomUTF32BE,
|
||||
bomEnd
|
||||
};
|
||||
|
||||
constexpr uint CharSetNameLength=32; ///<字符集名称长度
|
||||
using CharSetName=char[CharSetNameLength]; ///<字符集名称类型定义
|
||||
|
||||
template<int,char> const CharSetName &GetCurCharSet(); ///<取得当前程序编码字符集
|
||||
|
||||
constexpr CharSetName utf8_charset="utf8";
|
||||
constexpr CharSetName utf16le_charset="utf-16le";
|
||||
constexpr CharSetName utf16be_charset="utf-16be";
|
||||
constexpr CharSetName utf32le_charset="utf-32le";
|
||||
constexpr CharSetName utf32be_charset="utf-32be";
|
||||
|
||||
template<> inline const CharSetName &GetCurCharSet<2,HGL_LITTLE_ENDIAN >(){return utf16le_charset;}
|
||||
template<> inline const CharSetName &GetCurCharSet<2,HGL_BIG_ENDIAN >(){return utf16be_charset;}
|
||||
template<> inline const CharSetName &GetCurCharSet<4,HGL_LITTLE_ENDIAN >(){return utf32le_charset;}
|
||||
template<> inline const CharSetName &GetCurCharSet<4,HGL_BIG_ENDIAN >(){return utf32be_charset;}
|
||||
|
||||
template<typename T> inline const CharSetName &GetCharSet()
|
||||
{
|
||||
return GetCurCharSet<sizeof(T),HGL_ENDIAN>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 字节序文件头数据结构
|
||||
*/
|
||||
struct BOMFileHeader
|
||||
{
|
||||
int size; ///<字节序文件头长度
|
||||
unsigned char data[4]; ///<字节序数据
|
||||
|
||||
ByteOrderMask bom; ///<字节序枚举
|
||||
const CharSetName *char_set;///<字符集名称
|
||||
CharCodePage code_page; ///<代码页
|
||||
};
|
||||
|
||||
/**
|
||||
* 字节序文件头定义
|
||||
*/
|
||||
constexpr BOMFileHeader BOMData[bomEnd]=
|
||||
{
|
||||
{0,{} ,bomNone, nullptr ,ccpNone },
|
||||
{3,{0xEF,0xBB,0xBF} ,bomUTF8, &utf8_charset ,ccpUTF8 },
|
||||
{2,{0xFF,0xFE} ,bomUTF16LE,&utf16le_charset ,ccpUTF16LE },
|
||||
{2,{0xFE,0xFF} ,bomUTF16BE,&utf16be_charset ,ccpUTF16BE },
|
||||
{4,{0xFF,0xFE,0x00,0x00},bomUTF32LE,&utf32le_charset ,ccpUTF32LE },
|
||||
{4,{0x00,0x00,0xFE,0xFF},bomUTF32BE,&utf32be_charset ,ccpUTF32BE }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline T EndianSwap(const T value)
|
||||
{
|
||||
union
|
||||
{
|
||||
T v;
|
||||
uint8 bytes[sizeof(T)];
|
||||
}a,b;
|
||||
|
||||
a.v=value;
|
||||
|
||||
for(uint i=0;i<sizeof(T);i++)
|
||||
b.bytes[i]=a.bytes[sizeof(T)-1-i];
|
||||
|
||||
return b.v;
|
||||
}
|
||||
|
||||
template<> inline int8 EndianSwap< int8>(const int8 value){return value;}
|
||||
template<> inline uint8 EndianSwap<uint8>(const uint8 value){return value;}
|
||||
|
||||
template<> inline uint16 EndianSwap(const uint16 value)
|
||||
{
|
||||
return ((value&0xFF)<<8)
|
||||
|((value&0xFF00)>>8);
|
||||
}
|
||||
|
||||
template<> inline uint32 EndianSwap(const uint32 value)
|
||||
{
|
||||
return ((value&0xFF)<<24)
|
||||
|((value&0xFF00)<<8)
|
||||
|((value&0xFF0000)>>8)
|
||||
|((value&0xFF000000)>>24);
|
||||
}
|
||||
|
||||
template<> inline uint64 EndianSwap(const uint64 value)
|
||||
{
|
||||
return ((value&0xFF)<<56)
|
||||
|((value&0xFF00)<<40)
|
||||
|((value&0xFF0000)<<24)
|
||||
|((value&0xFF000000)<<8)
|
||||
|((value&0xFF00000000)>>8)
|
||||
|((value&0xFF0000000000)>>24)
|
||||
|((value&0xFF000000000000)>>40)
|
||||
|((value&0xFF00000000000000)>>56);
|
||||
}
|
||||
|
||||
template<> inline u16char EndianSwap(const u16char value){return EndianSwap(uint16(value));}
|
||||
|
||||
template<typename T>
|
||||
inline void EndianSwap(T *value,const int64 count)
|
||||
{
|
||||
for(int64 i=0;i<count;i++)
|
||||
{
|
||||
*value=EndianSwap(*value);
|
||||
++value;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void EndianSwap(T *dst,const T *src,const int64 count)
|
||||
{
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*dst=EndianSwap(*src);
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename D,typename S>
|
||||
inline void EndianSwap(D *dst,const S *src,const int64 count)
|
||||
{
|
||||
for(uint i=0;i<count;i++)
|
||||
{
|
||||
*dst=EndianSwap(D(*src)); //必须在ENDIAN SWAP前转换类型,否则在32转16位时,会将0000转出来。
|
||||
++dst;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
#if HGL_ENDIAN == HGL_BIG_ENDIAN
|
||||
|
||||
constexpr uint HGL_BOM_UTF16LE =0xfffe;
|
||||
constexpr uint HGL_BOM_UTF16BE =0xfeff;
|
||||
constexpr uint HGL_BOM_UTF32LE =0xfffe0000;
|
||||
constexpr uint HGL_BOM_UTF32BE =0x0000feff;
|
||||
|
||||
#define LittleToCurrentEndian EndianSwap
|
||||
#define BigToCurrentEndian ToBigEndian
|
||||
|
||||
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 T> T ToLittleEndian(T value){return EndianSwap(value);}
|
||||
|
||||
template<typename T> inline void ToLittleEndian(T *value,const int64 count){EndianSwap<T>(value,count);}
|
||||
template<typename D,typename S> inline void ToLittleEndian(D *dst,const S *src,const int64 count){EndianSwap<D,S>(dst,src,count);}
|
||||
|
||||
#else
|
||||
|
||||
constexpr uint HGL_BOM_UTF16LE =0xfeff;
|
||||
constexpr uint HGL_BOM_UTF16BE =0xfffe;
|
||||
constexpr uint HGL_BOM_UTF32LE =0x0000feff;
|
||||
constexpr uint HGL_BOM_UTF32BE =0xfffe0000;
|
||||
|
||||
#define LittleToCurrentEndian ToLittleEndian
|
||||
#define BigToCurrentEndian EndianSwap
|
||||
|
||||
template<typename T> T ToBigEndian(T value){return EndianSwap(value);}
|
||||
|
||||
template<typename T> inline void ToBigEndian(T *value,const int64 count){EndianSwap<T>(value,count);}
|
||||
template<typename D,typename S> inline void ToBigEndian(D *dst,const S *src,const int64 count){EndianSwap<D,S>(dst,src,count);}
|
||||
|
||||
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);}
|
||||
|
||||
#endif//HGL_BIG_ENDIAN
|
||||
|
||||
template<char> struct UTF16CharConvert;
|
||||
|
||||
template<> struct UTF16CharConvert<HGL_LITTLE_ENDIAN>
|
||||
{
|
||||
#if HGL_ENDIAN == HGL_BIG_ENDIAN
|
||||
static void convert(u16char *str,const int length)
|
||||
{
|
||||
EndianSwap<u16char>(str,length);
|
||||
}
|
||||
#else
|
||||
static void convert(const u16char *,const int){}
|
||||
#endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
|
||||
static void convert(u16char *out_str,const u16char *in_str,const int length)
|
||||
{
|
||||
#if HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
memcpy(out_str,in_str,length*sizeof(u16char));
|
||||
#else
|
||||
EndianSwap<u16char>(in_str,length);
|
||||
#endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
}
|
||||
};//template<> struct UTF16CharConvert<HGL_LITTLE_ENDIAN>
|
||||
|
||||
template<> struct UTF16CharConvert<HGL_BIG_ENDIAN>
|
||||
{
|
||||
static void convert(u16char *str,const int length)
|
||||
{
|
||||
#if HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
EndianSwap<u16char>(str,length);
|
||||
#endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
}
|
||||
|
||||
static void convert(u16char *out_str,const u16char *in_str,const int length)
|
||||
{
|
||||
#if HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
memcpy(out_str,in_str,length*sizeof(u16char));
|
||||
#else
|
||||
EndianSwap<u16char>(in_str,length);
|
||||
#endif//HGL_ENDIAN == HGL_LITTLE_ENDIAN
|
||||
}
|
||||
};//template<> struct UTF16ToWideChar<HGL_BIG_ENDIAN>
|
||||
}//namespace endian
|
||||
|
||||
using namespace endian;
|
||||
}//namespace hgl
|
||||
#endif//HGL_ENDIAN_INCLUDE
|
200
inc/hgl/platform/InputDevice.h
Normal file
200
inc/hgl/platform/InputDevice.h
Normal file
@ -0,0 +1,200 @@
|
||||
#ifndef HGL_INPUT_DEVICE_INCLUDE
|
||||
#define HGL_INPUT_DEVICE_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 鼠标按钮枚举
|
||||
*/
|
||||
enum MouseButton:int
|
||||
{
|
||||
mbLeft=0,
|
||||
mbRight,
|
||||
mbMiddle,
|
||||
|
||||
mbX1,
|
||||
mbX2,
|
||||
|
||||
mbEnd
|
||||
};//enum MouseButton
|
||||
|
||||
/**
|
||||
* 按键枚举定义
|
||||
*/
|
||||
enum KeyboardButton
|
||||
{
|
||||
kb_NONE=0, ///<起始定义,无意义
|
||||
|
||||
//主键盘区
|
||||
kbEsc, ///<ESC
|
||||
|
||||
//F功能键
|
||||
kbF1, ///<F1
|
||||
kbF2, ///<F2
|
||||
kbF3, ///<F3
|
||||
kbF4, ///<F4
|
||||
kbF5, ///<F5
|
||||
kbF6, ///<F6
|
||||
kbF7, ///<F7
|
||||
kbF8, ///<F8
|
||||
kbF9, ///<F9
|
||||
kbF10, ///<F10
|
||||
kbF11, ///<F11
|
||||
kbF12, ///<F12
|
||||
|
||||
kbGrave, //<`号(主键盘数字键1左边的按钮)
|
||||
|
||||
//10个数字
|
||||
kb0, ///<数字键0
|
||||
kb1, ///<数字键1
|
||||
kb2, ///<数字键2
|
||||
kb3, ///<数字键3
|
||||
kb4, ///<数字键4
|
||||
kb5, ///<数字键5
|
||||
kb6, ///<数字键6
|
||||
kb7, ///<数字键7
|
||||
kb8, ///<数字键8
|
||||
kb9, ///<数字键9
|
||||
|
||||
kbMinus, ///< - (减号)
|
||||
kbEquals, ///< = (等号)
|
||||
kbBackSlash, ///< \ (反斜杠)
|
||||
kbBackSpace, ///< 退格键
|
||||
|
||||
kbTab, ///<Tab键
|
||||
|
||||
kbA, ///<A
|
||||
kbB, ///<B
|
||||
kbC, ///<C
|
||||
kbD, ///<D
|
||||
kbE, ///<E
|
||||
kbF, ///<F
|
||||
kbG, ///<G
|
||||
kbH, ///<H
|
||||
kbI, ///<I
|
||||
kbJ, ///<J
|
||||
kbK, ///<K
|
||||
kbL, ///<L
|
||||
kbM, ///<M
|
||||
kbN, ///<N
|
||||
kbO, ///<O
|
||||
kbP, ///<P
|
||||
kbQ, ///<Q
|
||||
kbR, ///<R
|
||||
kbS, ///<S
|
||||
kbT, ///<T
|
||||
kbU, ///<U
|
||||
kbV, ///<V
|
||||
kbW, ///<W
|
||||
kbX, ///<X
|
||||
kbY, ///<Y
|
||||
kbZ, ///<Z
|
||||
|
||||
kbLeftBracket, ///<[
|
||||
kbRightBracket, ///<]
|
||||
|
||||
kbCapsLock, ///<大写锁定键
|
||||
|
||||
kbSemicolon, ///<; (分号)
|
||||
kbApostrophe, ///<' (单引号)
|
||||
kbEnter, ///<回车键
|
||||
|
||||
kbLeftShift, ///<左边的Shift键
|
||||
|
||||
kbComma, ///<, (逗号)
|
||||
kbPeriod, ///<. (句号)
|
||||
kbSlash, ///</ (除号)
|
||||
kbRightShift, ///<右边的Shift键
|
||||
|
||||
kbLeftCtrl, ///<左边的Ctrl键
|
||||
kbLeftOS, ///<左边的OS键(Win/Apple键)
|
||||
kbLeftAlt, ///<左边的Alt键
|
||||
kbSpace, ///<空格键
|
||||
kbRightAlt, ///<右边的Alt键
|
||||
kbRightOS, ///<右边的OS键(Win/Apple键)
|
||||
kbRightMenu, ///<右边的Menu键
|
||||
kbRightCtrl, ///<右边的Ctrl键
|
||||
|
||||
//中键盘区
|
||||
kbPrintScreen, ///<打印屏幕键
|
||||
kbScrollLock, ///<滚动锁定键
|
||||
kbPause, ///<暂停键
|
||||
|
||||
kbInsert, ///<插入键
|
||||
kbDelete, ///<删除键
|
||||
kbHome, ///<行首键
|
||||
kbEnd, ///<行尾键
|
||||
kbPageUp, ///<向前翻页键
|
||||
kbPageDown, ///<向后翻页键
|
||||
|
||||
kbUp, ///<↑光标键
|
||||
kbDown, ///<↓光标键
|
||||
kbLeft, ///<←光标键
|
||||
kbRight, ///<→光标键
|
||||
|
||||
//小键盘区
|
||||
kbNumLock, ///<小键盘 数字锁定键
|
||||
|
||||
kbNumAdd, ///<小键盘 +
|
||||
kbNumSubtract, ///<小键盘 -
|
||||
kbNumMultiply, ///<小键盘 *
|
||||
kbNumDivide, ///<小键盘 /
|
||||
|
||||
kbNum0, ///<小键盘 0
|
||||
kbNum1, ///<小键盘 1
|
||||
kbNum2, ///<小键盘 2
|
||||
kbNum3, ///<小键盘 3
|
||||
kbNum4, ///<小键盘 4
|
||||
kbNum5, ///<小键盘 5
|
||||
kbNum6, ///<小键盘 6
|
||||
kbNum7, ///<小键盘 7
|
||||
kbNum8, ///<小键盘 8
|
||||
kbNum9, ///<小键盘 9
|
||||
|
||||
kbNumDecimal, ///<小键盘 . (小数点/删除键)
|
||||
kbNumEnter, ///<小键盘 回车键
|
||||
|
||||
kb_END ///<结束定义,无意义
|
||||
};//enum KeyboardButton
|
||||
|
||||
/**
|
||||
* 手柄按键枚举
|
||||
*/
|
||||
enum JoystickButton
|
||||
{
|
||||
jbNone=0,
|
||||
|
||||
jbUp,
|
||||
jbDown,
|
||||
jbLeft,
|
||||
jbRight,
|
||||
|
||||
jb0, jb1, jb2, jb3, jb4, jb5, jb6, jb7,
|
||||
jb8, jb9, jb10, jb11, jb12, jb13, jb14, jb15,
|
||||
jb16, jb17, jb18, jb19, jb20, jb21, jb22, jb23,
|
||||
jb24, jb25, jb26, jb27, jb28, jb29, jb30, jb31,
|
||||
|
||||
jbEnd,
|
||||
|
||||
//DreamCast/XBOX
|
||||
/* jbX=jb2,
|
||||
jbY=jb3,
|
||||
jbA=jb0,
|
||||
jbB=jb1,
|
||||
jbL=jb4,
|
||||
jbR=jb5,*/
|
||||
|
||||
//PlayStation
|
||||
jbTriangle =jb0, // 三角
|
||||
jbCircle =jb1, // 圆
|
||||
jbFork =jb2, // 叉
|
||||
jbRectangle =jb3, // 方
|
||||
jbL1 =jb6, jbL2 =jb4,
|
||||
jbR1 =jb7, jbR2 =jb5,
|
||||
jbSelect =jb8, jbStart =jb9,
|
||||
|
||||
//XBOX/XBOX360
|
||||
jbXBOX, //西瓜键
|
||||
};
|
||||
}//namespace hgl
|
||||
#endif//HGL_INPUT_DEVICE_INCLUDE
|
334
inc/hgl/platform/Platform.h
Normal file
334
inc/hgl/platform/Platform.h
Normal file
@ -0,0 +1,334 @@
|
||||
#ifndef HGL_PLATFORM_INCLUDE
|
||||
#define HGL_PLATFORM_INCLUDE
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define HGL_LIB_DEBUG_NAME "Debug"
|
||||
#else
|
||||
#define HGL_LIB_DEBUG_NAME "Release"
|
||||
#endif//
|
||||
|
||||
#define HGL_MERGE32(a,b,c,d) (a|b<<8|c<<16|d<<24)
|
||||
|
||||
#define HGL_OS_Windows HGL_MERGE32('W','i','n',' ')
|
||||
#define HGL_OS_macOS HGL_MERGE32('m','a','c',' ')
|
||||
#define HGL_OS_iOS HGL_MERGE32('i','O','S',' ')
|
||||
#define HGL_OS_FreeBSD HGL_MERGE32('F','B','S','D')
|
||||
#define HGL_OS_NetBSD HGL_MERGE32('N','B','S','D')
|
||||
#define HGL_OS_OpenBSD HGL_MERGE32('O','B','S','D')
|
||||
#define HGL_OS_Linux HGL_MERGE32('L','i','n','u')
|
||||
#define HGL_OS_Cygwin HGL_MERGE32('C','y','g','w')
|
||||
#define HGL_OS_PSP2 HGL_MERGE32('P','S','P','2')
|
||||
#define HGL_OS_PS4 HGL_MERGE32('P','S','4',' ')
|
||||
#define HGL_OS_AIX HGL_MERGE32('A','I','X',' ')
|
||||
#define HGL_OS_Android HGL_MERGE32('A','n','d','r')
|
||||
#define HGL_OS_Wasm HGL_MERGE32('W','a','s','m')
|
||||
|
||||
#define HGL_CPU_X86_32 HGL_MERGE32('8','6','3','2')
|
||||
#define HGL_CPU_X86_64 HGL_MERGE32('8','6','6','4')
|
||||
#define HGL_CPU_MIPS HGL_MERGE32('M','I','P','S')
|
||||
#define HGL_CPU_MIPSel HGL_MERGE32('M','I','e','l')
|
||||
#define HGL_CPU_MIPS64 HGL_MERGE32('M','I','6','4')
|
||||
#define HGL_CPU_PowerPC HGL_MERGE32('P','P','C',' ')
|
||||
#define HGL_CPU_PowerPC64 HGL_MERGE32('P','P','6','4')
|
||||
#define HGL_CPU_Cell HGL_MERGE32('C','E','L','L')
|
||||
#define HGL_CPU_ARM7 HGL_MERGE32('A','R','M','7')
|
||||
#define HGL_CPU_ARM64 HGL_MERGE32('A','R','6','4')
|
||||
|
||||
#define HGL_COMPILER_Microsoft HGL_MERGE32('M','S','C',' ')
|
||||
#define HGL_COMPILER_GNU HGL_MERGE32('G','N','U',' ')
|
||||
#define HGL_COMPILER_MinGW32 HGL_MERGE32('M','G','3','2')
|
||||
#define HGL_COMPILER_Intel HGL_MERGE32('I','n','t','e')
|
||||
#define HGL_COMPILER_IBM HGL_MERGE32('I','B','M',' ')
|
||||
#define HGL_COMPILER_DigitalMars HGL_MERGE32('D','i','M','a')
|
||||
#define HGL_COMPILER_LLVM HGL_MERGE32('L','L','V','M')
|
||||
#define HGL_COMPILER_PGI HGL_MERGE32('P','G','I',' ')
|
||||
|
||||
#define HGL_BIG_ENDIAN 'B'
|
||||
#define HGL_LITTLE_ENDIAN 'L'
|
||||
|
||||
#if defined(__amd64__) ||defined(__amd64) || \
|
||||
defined(__x86_64__) ||defined(__x86_64) || \
|
||||
defined(_M_AMD64) ||defined(_M_X64)
|
||||
#define HGL_CPU HGL_CPU_X86_64
|
||||
#define HGL_CPU_NAME OS_TEXT("X86-64Bit")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("x64")
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 8
|
||||
#define HGL_ENDIAN HGL_LITTLE_ENDIAN
|
||||
#elif defined(i386) || defined(__i386__) || defined(__i386) ||defined(_M_IX86)
|
||||
#define HGL_CPU HGL_CPU_X86_32
|
||||
#define HGL_CPU_NAME OS_TEXT("X86-32Bit")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("x86")
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 4
|
||||
#define HGL_ENDIAN HGL_LITTLE_ENDIAN
|
||||
#elif defined(_M_MIPS)||defined(_MIPS_ARCH)||defined(__mips__)||defined(__mips)||defined(mips)||defined(__MIPS__)
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 4
|
||||
#ifdef __MIPSEL__
|
||||
#define HGL_CPU HGL_CPU_MIPSel
|
||||
#define HGL_CPU_NAME OS_TEXT("MIPSel")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("MIPSel")
|
||||
#define HGL_ENDIAN HGL_LITTLE_ENDIAN
|
||||
#else
|
||||
#define HGL_CPU HGL_CPU_MIPS
|
||||
#define HGL_CPU_NAME OS_TEXT("MIPS")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("MIPS")
|
||||
#define HGL_ENDIAN HGL_BIG_ENDIAN
|
||||
#endif//__MIPSEL__
|
||||
#elif defined(__mips64__)||defined(mips64)
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 8
|
||||
#define HGL_CPU HGL_CPU_MIPS64
|
||||
#define HGL_CPU_NAME OS_TEXT("MIPS64")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("MIPS64")
|
||||
#define HGL_ENDIAN HGL_BIG_ENDIAN
|
||||
#elif defined(__powerpc__) || defined(__powerpc) \
|
||||
||defined(__POWERPC__) \
|
||||
|| defined(__ppc__) || defined(__PPC__) || defined(__ppc) \
|
||||
|| defined(_M_PPC) ||defined(_M_MPPC) \
|
||||
|| defined(_ARCH_PPC) || defined(_ARCH_PWR)
|
||||
#ifdef __PPU__
|
||||
#define HGL_CPU HGL_CPU_Cell
|
||||
#define HGL_CPU_NAME OS_TEXT("Cell")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("Cell")
|
||||
#else
|
||||
#ifdef defined(__ppc64__)||defined(__PPC64__)||defined(__powerpc64__) \
|
||||
||defined(_ARCH_PPC64)||defined(__64BIT__)
|
||||
#define HGL_CPU HGL_CPU_PowerPC64
|
||||
#define HGL_CPU_NAME OS_TEXT("PowerPC64")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("PowerPC64")
|
||||
#else
|
||||
#define HGL_CPU HGL_CPU_PowerPC
|
||||
#define HGL_CPU_NAME OS_TEXT("PowerPC")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("PowerPC")
|
||||
#endif//PowerPC64
|
||||
#endif
|
||||
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 8
|
||||
#define HGL_ENDIAN HGL_BIG_ENDIAN
|
||||
#elif defined(__arm__)||defined(__arm) \
|
||||
||defined(_ARM) \
|
||||
||defined(_M_ARM) \
|
||||
||defined(__ARM_ARCH__7__) \
|
||||
||defined(__ARM_ARCH__7A__) \
|
||||
||defined(__ARM_ARCH__7R__) \
|
||||
||defined(__ARM_ARCH__7M__) \
|
||||
||defined(__ARM_ARCH__7S__)
|
||||
#define HGL_CPU HGL_CPU_ARM7
|
||||
#define HGL_CPU_NAME OS_TEXT("ARM7")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("ARM7")
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 4
|
||||
#define HGL_ENDIAN HGL_LITTLE_ENDIAN
|
||||
#elif defined(__aarch64__)
|
||||
#define HGL_CPU HGL_CPU_ARM64
|
||||
#define HGL_CPU_NAME OS_TEXT("ARM64")
|
||||
#define HGL_LIB_CPU_NAME OS_TEXT("ARM64")
|
||||
#define HGL_MIN_MEMORY_ALLOC_BYTES 4
|
||||
#define HGL_ENDIAN HGL_LITTLE_ENDIAN
|
||||
#elif defined(__wasm__)
|
||||
|
||||
#error Not support WebAssembly.please wait update......
|
||||
|
||||
#define HGL_OS HGL_OS_Wasm
|
||||
#define HGL_COMPILER HGL_COMPILER_LLVM
|
||||
#else
|
||||
#error Not support the cpu.
|
||||
#endif
|
||||
|
||||
#if HGL_ENDIAN == HGL_BIG_ENDIAN
|
||||
#define HGL_CPU_ENDIAN OS_TEXT("Big Endian")
|
||||
#else
|
||||
#define HGL_CPU_ENDIAN OS_TEXT("Little Endian")
|
||||
#endif//HGL_ENDIAN == HGL_BIG_ENDIAN
|
||||
|
||||
#if defined(__WIN32__)||defined(_WIN32)||defined(WIN32)||defined(__WINDOWS__)||defined(__WIN64__)||defined(_WIN64)||defined(WIN64)
|
||||
#define HGL_OS HGL_OS_Windows
|
||||
#elif defined(__APPLE__)||defined(__MAC__)||defined(macintosh)||defined(__APPLE_CC__)
|
||||
|
||||
#define HGL_OS_BSD 1
|
||||
|
||||
#include "TargetConditionals.h"
|
||||
#if TARGET_OS_IPHONE
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
#define HGL_OS HGL_OS_iOS_Simulator
|
||||
#else
|
||||
#define HGL_OS HGL_OS_iOS
|
||||
#endif//TARGET_IPHONE_SIMULATOR
|
||||
#elif TARGET_OS_MAC
|
||||
#define HGL_OS HGL_OS_macOS
|
||||
#endif//
|
||||
#elif defined(__ANDROID__)
|
||||
#define HGL_OS HGL_OS_Android
|
||||
#elif defined(__FreeBSD)||defined(__FreeBSD__)
|
||||
#define HGL_OS HGL_OS_FreeBSD
|
||||
#define HGL_OS_BSD 1
|
||||
#elif defined(__NetBSD)||defined(__NetBSD__)
|
||||
#define HGL_OS HGL_OS_NetBSD
|
||||
#define HGL_OS_BSD 1
|
||||
#elif defined(__OPENBSD)||defined(__OpenBSD__)
|
||||
#define HGL_OS HGL_OS_OpenBSD
|
||||
#define HGL_OS_BSD 1
|
||||
#elif defined(__linux__)||defined(__LINUX__)||defined(linux)||defined(__linux)
|
||||
#define HGL_OS HGL_OS_Linux
|
||||
#elif defined(__CYGWIN__)
|
||||
#define HGL_OS HGL_OS_Cygwin
|
||||
#elif defined(SN_TARGET_PSP2)||defined(__PSV__)||defined(__psv__)||defined(_PSV)||defined(__PSVita__)||defined(__PSVita)
|
||||
#define HGL_OS HGL_OS_PSP2
|
||||
#elif defined(SN_TARGET_ORBIS)
|
||||
#define HGL_OS HGL_OS_PS4
|
||||
#elif defined(_AIX)||defined(__AIX)||defined(__AIX__)||defined(__aix)||defined(__aix__)
|
||||
#define HGL_OS HGL_OS_AIX
|
||||
#endif//
|
||||
|
||||
#if defined(__clang__)
|
||||
#define HGL_COMPILER HGL_COMPILER_LLVM
|
||||
#elif defined(__INTEL_COMPILER)||defined(__ECL)||defined(__ICL)||defined(__ICC)
|
||||
#define HGL_COMPILER HGL_COMPILER_Intel
|
||||
#elif defined(__IBMC__)||defined(__IBMCPP__)
|
||||
#define HGL_COMPILER HGL_COMPILER_IBM
|
||||
#elif defined(__DMC__)||defined(__SC__)||defined(__ZTC__)
|
||||
#define HGL_COMPILER HGL_COMPILER_DigitalMars
|
||||
#elif defined(_MSC_VER)
|
||||
#define HGL_COMPILER HGL_COMPILER_Microsoft
|
||||
#elif defined(__PGI)
|
||||
#define HGL_COMPILER HGL_COMPILER_PGI
|
||||
#elif defined(__MINGW32__)
|
||||
#define HGL_COMPILER HGL_COMPILER_MinGW32
|
||||
#elif defined(__GNUC__)
|
||||
#define HGL_COMPILER HGL_COMPILER_GNU
|
||||
#else
|
||||
#error Can not support the Compiler.
|
||||
#endif//
|
||||
|
||||
#if defined(SetEventCall)||defined(SafeCallEvent)||defined(CallEvent)||defined(DefEvent)
|
||||
#error SetEventCall,SafeCallEvent,CallEvent,DefEvent 其中之一已经定义
|
||||
#endif//
|
||||
|
||||
#if defined(Property)||defined(PropertyRead)||defined(PropertyWrite)
|
||||
#error Property,PropertyRead,PropertyWrite 其中之一已经定义
|
||||
#endif//
|
||||
|
||||
// #ifndef UNICODE
|
||||
// #define UNICODE //定义使用UNICODE编码
|
||||
// #endif//UNICODE
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
|
||||
#include<hgl/platform/os/MSWindows.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_Microsoft
|
||||
#include<hgl/platform/compiler/Microsoft.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_Intel
|
||||
#include<hgl/platform/compiler/Intel.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_IBM
|
||||
#include<hgl/platform/compiler/IBM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_MINGW32
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif
|
||||
|
||||
#elif HGL_OS == HGL_OS_Cygwin
|
||||
|
||||
#include<hgl/platform/os/Cygwin.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_LLVM
|
||||
#include<hgl/platform/compiler/LLVM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif//GNU
|
||||
|
||||
#elif (HGL_OS == HGL_OS_FreeBSD)||(HGL_OS == HGL_OS_NetBSD)||(HGL_OS == HGL_OS_OpenBSD)
|
||||
|
||||
#include<hgl/platform/os/BSD.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_LLVM
|
||||
#include<hgl/platform/compiler/LLVM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif//GNU
|
||||
|
||||
#elif HGL_OS == HGL_OS_Linux
|
||||
|
||||
#include<hgl/platform/os/Linux.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_CBuilder
|
||||
#include<hgl/platform/compiler/CBuilder.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_Intel
|
||||
#include<hgl/platform/compiler/Intel.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_IBM
|
||||
#include<hgl/platform/compiler/IBM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_Watcom
|
||||
#include<hgl/platform/compiler/Watcom.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_LLVM
|
||||
#include<hgl/platform/compiler/LLVM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif
|
||||
|
||||
#elif HGL_OS == HGL_OS_macOS
|
||||
|
||||
#include<hgl/platform/os/MacOS.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_Intel
|
||||
#include<hgl/platform/compiler/Intel.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_LLVM
|
||||
#include<hgl/platform/compiler/LLVM.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif
|
||||
|
||||
#elif HGL_OS == HGL_OS_iOS
|
||||
|
||||
#include<hgl/platform/os/MacOS.h>
|
||||
#include<hgl/platform/compiler/LLVM.h>
|
||||
|
||||
#elif HGL_OS == HGL_OS_PSP2
|
||||
|
||||
#include<hgl/platform/os/psp2.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif
|
||||
|
||||
#elif HGL_OS == HGL_OS_AIX
|
||||
|
||||
#include<hgl/platform/os/aix.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_IBM
|
||||
#include<hgl/platform/compiler/IBM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_SGI
|
||||
#include<hgl/platform/compiler/SGI.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif
|
||||
|
||||
#elif HGL_OS == HGL_OS_Android
|
||||
|
||||
#include<hgl/platform/os/Android.h>
|
||||
|
||||
#if HGL_COMPILER == HGL_COMPILER_LLVM
|
||||
#include<hgl/platform/compiler/LLVM.h>
|
||||
#elif HGL_COMPILER == HGL_COMPILER_GNU
|
||||
#include<hgl/platform/compiler/GNU.h>
|
||||
#else
|
||||
#error Unrecognized compiler
|
||||
#endif//GNU
|
||||
#endif//HGL_OS
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
#define HGL_WINDOW_DIRECTORY_SEPARATOR OS_TEXT('\\')
|
||||
#define HGL_UNIX_DIRECTORY_SPEARATOR OS_TEXT('/')
|
||||
}//namespace hgl
|
||||
|
||||
#endif//HGL_PLATFORM_INCLUDE
|
21
inc/hgl/platform/compiler/DataTypeGNU.h
Normal file
21
inc/hgl/platform/compiler/DataTypeGNU.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef HGL_DATATYPE_GNU_INCLUDE
|
||||
#define HGL_DATATYPE_GNU_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
using int8 = signed char; ///<有符号 8位整型
|
||||
using uint8 =unsigned char; ///<无符号 8位整型
|
||||
using int16 = signed short; ///<有符号16位整型
|
||||
using uint16 =unsigned short; ///<无符号16位整型
|
||||
using int32 = signed int; ///<有符号32位整型
|
||||
using uint32 =unsigned int; ///<无符号32位整型
|
||||
|
||||
//64位系统下long/long long都是64位,32位系列下只有long long是64位
|
||||
|
||||
using int64 = signed long long; ///<有符号64位整型
|
||||
using uint64 =unsigned long long; ///<无符号64位整型
|
||||
|
||||
using float32 =float;
|
||||
using float64 =double;
|
||||
}//namespace hgl
|
||||
#endif//HGL_DATATYPE_GNU_INCLUDE
|
29
inc/hgl/platform/compiler/DataTypeTiny.h
Normal file
29
inc/hgl/platform/compiler/DataTypeTiny.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef HGL_DATA_TYPE_TINY_INCLUDE
|
||||
#define HGL_DATA_TYPE_TINY_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
using i8=int8;
|
||||
using i16=int16;
|
||||
using i32=int32;
|
||||
using i64=int64;
|
||||
|
||||
using u8=uint8;
|
||||
using u16=uint16;
|
||||
using u32=uint32;
|
||||
using u64=uint64;
|
||||
|
||||
using f32=float;
|
||||
using f64=double;
|
||||
|
||||
#define enum_int(name) enum name:int
|
||||
#define enum_uint(name) enum name:uint
|
||||
|
||||
using void_pointer=void *;
|
||||
|
||||
using uchar = unsigned char; ///< 无符号字符型
|
||||
using ushort = unsigned short; ///< 无符号短整型
|
||||
using uint = unsigned int; ///< 无符号整型
|
||||
using ulong = unsigned long; ///< 无符号长整型
|
||||
}//namespace hgl
|
||||
#endif//HGL_DATA_TYPE_TINY_INCLUDE
|
17
inc/hgl/platform/compiler/DataTypeWin.h
Normal file
17
inc/hgl/platform/compiler/DataTypeWin.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef HGL_DATATYPE_WINDOWS_INCLUDE
|
||||
#define HGL_DATATYPE_WINDOWS_INCLUDE
|
||||
namespace hgl
|
||||
{
|
||||
using int8 = signed __int8 ; ///<有符号 8位整型
|
||||
using uint8 =unsigned __int8 ; ///<无符号 8位整型
|
||||
using int16 = signed __int16; ///<有符号16位整型
|
||||
using uint16 =unsigned __int16; ///<无符号16位整型
|
||||
using int32 = signed __int32; ///<有符号32位整型
|
||||
using uint32 =unsigned __int32; ///<无符号32位整型
|
||||
using int64 = signed __int64; ///<有符号64位整型
|
||||
using uint64 =unsigned __int64; ///<无符号64位整型
|
||||
|
||||
using float32 =float;
|
||||
using float64 =double;
|
||||
}//namespace hgl
|
||||
#endif//HGL_DATATYPE_WINDOWS_INCLUDE
|
250
inc/hgl/platform/compiler/EventFunc.h
Normal file
250
inc/hgl/platform/compiler/EventFunc.h
Normal file
@ -0,0 +1,250 @@
|
||||
#ifndef HGL_EVENT_FUNC_INCLUDE
|
||||
#define HGL_EVENT_FUNC_INCLUDE
|
||||
|
||||
#include<hgl/type/_Object.h>
|
||||
#include<string.h>
|
||||
namespace hgl
|
||||
{
|
||||
#ifdef __BORLANDC__
|
||||
|
||||
#define SetEventCall(event_obj,obj_this,class_name,event_func) event_obj=obj_this->class_name::event_func
|
||||
#define SafeCallEvent(event_obj,intro) {if(event_obj)event_obj intro;}
|
||||
#define CallEvent(event_obj,intro) event_obj intro
|
||||
#define DefEvent(result,name,intro) result (__closure *name)intro
|
||||
|
||||
#else
|
||||
|
||||
template <typename RT,typename Func> struct EventFunc
|
||||
{
|
||||
typedef EventFunc<RT,Func> SelfClass;
|
||||
|
||||
union
|
||||
{
|
||||
void *vp_this;
|
||||
_Object *this_pointer;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
void *vp_func;
|
||||
Func func_pointer;
|
||||
ObjectMemberFunc omf;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
EventFunc()
|
||||
{
|
||||
ClearFunc();
|
||||
}
|
||||
|
||||
EventFunc(void *t,void *f)
|
||||
{
|
||||
ClearFunc();
|
||||
|
||||
vp_this=t;
|
||||
vp_func=f;
|
||||
}
|
||||
|
||||
void ClearFunc()
|
||||
{
|
||||
memset(this,0,sizeof(SelfClass));
|
||||
}
|
||||
|
||||
bool operator !()const
|
||||
{
|
||||
if(!vp_func)return(true);
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
void operator = (void *v)
|
||||
{
|
||||
if(v==0)
|
||||
memset(this,0,sizeof(SelfClass)); //omf可能不止一个指针的长度,所以必须这样清
|
||||
}
|
||||
|
||||
void operator = (const SelfClass &ef)
|
||||
{
|
||||
memcpy(this,&ef,sizeof(SelfClass));
|
||||
}
|
||||
|
||||
bool operator == (void *v)
|
||||
{
|
||||
return(vp_func==v);
|
||||
}
|
||||
|
||||
bool operator != (void *v)
|
||||
{
|
||||
return(vp_func!=v);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
RT operator()(ARGS...args)
|
||||
{
|
||||
return (this_pointer->*(func_pointer))(args...);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
RT operator()(ARGS...args)const
|
||||
{
|
||||
return (this_pointer->*(func_pointer))(args...);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
RT ThisCall(void *tp,ARGS...args)
|
||||
{
|
||||
return (((_Object *)tp)->*(func_pointer))(args...);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
RT ThisCall(void *tp,ARGS...args)const
|
||||
{
|
||||
return (((_Object *)tp)->*(func_pointer))(args...);
|
||||
}
|
||||
};//template<typename RT,typename Func> struct EventFunc
|
||||
|
||||
template<typename Func> struct EventFunc<void,Func>
|
||||
{
|
||||
typedef EventFunc<void,Func> SelfClass;
|
||||
|
||||
union
|
||||
{
|
||||
void *vp_this;
|
||||
_Object *this_pointer;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
void *vp_func;
|
||||
Func func_pointer;
|
||||
ObjectMemberFunc omf;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
EventFunc()
|
||||
{
|
||||
memset(this,0,sizeof(SelfClass));
|
||||
}
|
||||
|
||||
EventFunc(void *t,void *f)
|
||||
{
|
||||
memset(this,0,sizeof(SelfClass));
|
||||
|
||||
vp_this=t;
|
||||
vp_func=f;
|
||||
}
|
||||
|
||||
bool operator !()const
|
||||
{
|
||||
if(!vp_func)return(true);
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
void operator = (void *v)
|
||||
{
|
||||
if(v==0)
|
||||
memset(this,0,sizeof(SelfClass)); //omf可能不止一个指针的长度,所以必须这样清
|
||||
}
|
||||
|
||||
void operator = (const SelfClass &ef)
|
||||
{
|
||||
memcpy(this,&ef,sizeof(SelfClass));
|
||||
}
|
||||
|
||||
bool operator == (void *v)
|
||||
{
|
||||
return(vp_func==v);
|
||||
}
|
||||
|
||||
bool operator != (void *v)
|
||||
{
|
||||
return(vp_func!=v);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
void operator()(ARGS...args)
|
||||
{
|
||||
(this_pointer->*(func_pointer))(args...);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
void operator()(ARGS...args)const
|
||||
{
|
||||
(this_pointer->*(func_pointer))(args...);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
void ThisCall(void *tp,ARGS...args)
|
||||
{
|
||||
(((_Object *)tp)->*(func_pointer))(args...);
|
||||
}
|
||||
|
||||
template<typename ...ARGS>
|
||||
void ThisCall(void *tp,ARGS...args)const
|
||||
{
|
||||
(((_Object *)tp)->*(func_pointer))(args...);
|
||||
}
|
||||
};//template<void,typename Func> struct EventFunc
|
||||
|
||||
#define SetEventCall(event_obj,obj_this,class_name,event_func) { \
|
||||
event_obj.vp_this=obj_this; \
|
||||
event_obj.vp_func=GetMemberFuncPointer(class_name,event_func); \
|
||||
}
|
||||
|
||||
#define SetEventThis(event_obj,obj_this) event_obj.vp_this=obj_this;
|
||||
|
||||
// #define CallEvent(event_obj,intro) ((event_obj.this_pointer->*(event_obj.func_pointer))intro)
|
||||
|
||||
#define SafeCallEvent(event_obj,intro) {if(event_obj.vp_func)event_obj intro;}
|
||||
|
||||
#define DefEvent(result,name,intro) EventFunc<result,result (_Object:: *)intro> name;
|
||||
|
||||
#endif//__BORLANDC__
|
||||
|
||||
/*
|
||||
|
||||
使用方法:
|
||||
|
||||
class Example
|
||||
{
|
||||
//原Borland/CodeGear方式
|
||||
void (__closure *OnClick)(Object *);
|
||||
|
||||
//现通用方式
|
||||
DefEvent(void,OnClick,(Object *));
|
||||
};
|
||||
|
||||
void Test::ClickProc(Object *);
|
||||
|
||||
void Test::func()
|
||||
{
|
||||
Example *exp;
|
||||
|
||||
{
|
||||
//原Borland/CodeGear方式
|
||||
exp->OnClick=this->ClickProc;
|
||||
或
|
||||
exp->OnClick=ClickProc;
|
||||
|
||||
//现通用方式
|
||||
SetEventCall(exp->OnClick,this,Test,ClickProc);
|
||||
}
|
||||
|
||||
{
|
||||
//原Borland/CodeGear方式
|
||||
exp->OnClick(nullptr);
|
||||
|
||||
//现通用方式
|
||||
CallEvent(exp->OnClick,(nullptr));
|
||||
|
||||
//C++11方式
|
||||
exp->OnClick(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}//namespace hgl
|
||||
#endif//HGL_EVENT_FUNC_INCLUDE
|
85
inc/hgl/platform/compiler/GNU.h
Normal file
85
inc/hgl/platform/compiler/GNU.h
Normal file
@ -0,0 +1,85 @@
|
||||
#ifndef HGL_COMPILER_GNU_INCLUDE
|
||||
#define HGL_COMPILER_GNU_INCLUDE
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_COMPILER_NAME OS_TEXT("GNU C/C++")
|
||||
#define HGL_LIB_COMPILER_NAME OS_TEXT("GCC")
|
||||
|
||||
#if (__GNUC__<4)||(__GNUC__==4&&__GNUC_MINOR__<8)
|
||||
#error Please upgrade your compiler or development tools to GNU C/C++ 4.8 or later
|
||||
#else
|
||||
|
||||
#if __GNUC__ == 4
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("4")
|
||||
#elif __GNUC__ == 5
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("5")
|
||||
#elif __GNUC__ == 6
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("6")
|
||||
#elif __GNUC__ == 7
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("7")
|
||||
#elif __GNUC__ == 8
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("8")
|
||||
#elif __GNUC__ == 9
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("9")
|
||||
#elif __GNUC__ == 10
|
||||
#define HGL_LIB_COMPILER_MAIOR_VER OS_TEXT("10")
|
||||
#endif//__GNUC__
|
||||
|
||||
#if __GNUC_MINOR__ == 0
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("0")
|
||||
#elif __GNUC_MINOR__ == 1
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("1")
|
||||
#elif __GNUC_MINOR__ == 2
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("2")
|
||||
#elif __GNUC_MINOR__ == 3
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("3")
|
||||
#elif __GNUC_MINOR__ == 4
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("4")
|
||||
#elif __GNUC_MINOR__ == 5
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("5")
|
||||
#elif __GNUC_MINOR__ == 6
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("6")
|
||||
#elif __GNUC_MINOR__ == 7
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("7")
|
||||
#elif __GNUC_MINOR__ == 8
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("8")
|
||||
#elif __GNUC_MINOR__ == 9
|
||||
#define HGL_LIB_COMPILER_MINOR_VER OS_TEXT("9")
|
||||
#endif//
|
||||
|
||||
#if __GNUC_PATCHLEVEL__ == 0
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("0")
|
||||
#elif __GNUC_PATCHLEVEL__ == 1
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("1")
|
||||
#elif __GNUC_PATCHLEVEL__ == 2
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("2")
|
||||
#elif __GNUC_PATCHLEVEL__ == 3
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("3")
|
||||
#elif __GNUC_PATCHLEVEL__ == 4
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("4")
|
||||
#elif __GNUC_PATCHLEVEL__ == 5
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("5")
|
||||
#elif __GNUC_PATCHLEVEL__ == 6
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("6")
|
||||
#elif __GNUC_PATCHLEVEL__ == 7
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("7")
|
||||
#elif __GNUC_PATCHLEVEL__ == 8
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("8")
|
||||
#elif __GNUC_PATCHLEVEL__ == 9
|
||||
#define HGL_LIB_COMPILER_PATCH_LEVEL OS_TEXT("9")
|
||||
#endif//
|
||||
|
||||
#define HGL_LIB_COMPILER_VERSION HGL_LIB_COMPILER_MAIOR_VER OS_TEXT(".") HGL_LIB_COMPILER_MINOR_VER OS_TEXT(".") HGL_LIB_COMPILER_PATCH_LEVEL
|
||||
|
||||
#endif//__GNUC__
|
||||
|
||||
#define HGL_THREAD_LOCAL_STORAGE __thread //线程本地储存
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_LIB_FRONT HGL_LIB_OS "_" HGL_LIB_COMPILER_NAME "_" HGL_LIB_DEBUG_NAME "_"
|
||||
|
||||
#define HGL_LIB_END ".a"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<hgl/platform/compiler/DataTypeGNU.h>
|
||||
#include<hgl/platform/compiler/DataTypeTiny.h>
|
||||
#include<hgl/platform/compiler/Property.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_COMPILER_GNU_INCLUDE
|
43
inc/hgl/platform/compiler/Intel.h
Normal file
43
inc/hgl/platform/compiler/Intel.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef HGL_COMPILER_INTEL_INCLUDE
|
||||
#define HGL_COMPILER_INTEL_INCLUDE
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_COMPILER_NAME u"Intel C/C++"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#if __INTEL_COMPILER < 1200
|
||||
#error Please upgrade your compiler To Intel C/C++ 12.1 or later.
|
||||
#else
|
||||
#if __INTEL_COMPILER >=1200 && __INTEL_COMPILER < 1300
|
||||
#define HGL_LIB_COMPILER_NAME "IntelCPP12"
|
||||
#else
|
||||
#define HGL_LIB_COMPILER_NAME "IntelCPP_UnknownVersion"
|
||||
#endif//__INTEL_COMPILER
|
||||
|
||||
#define enum_uint(name) enum name:unsigned int
|
||||
#endif//__INTEL_COMPILER
|
||||
|
||||
#define vsnwprintf _vsnwprintf
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<hgl/platform/compiler/DataTypeGNU.h>
|
||||
#include<hgl/platform/compiler/DataTypeTiny.h>
|
||||
#include<hgl/platform/compiler/Property.h>
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
#define HGL_THREAD __declspec(thread)
|
||||
#else
|
||||
#define HGL_THREAD __thread
|
||||
#endif//HGL_OS == HGL_OS_Windows
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#ifdef _DLL
|
||||
#define HGL_LIB_CRT "Dynamic"
|
||||
#else
|
||||
#define HGL_LIB_CRT "Static"
|
||||
#endif//_DLL
|
||||
|
||||
#define HGL_LIB_FRONT HGL_LIB_OS "_" HGL_LIB_COMPILER_NAME "_" HGL_LIB_DEBUG_NAME "_" HGL_LIB_CRT "_"
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
#define HGL_LIB_END ".LIB"
|
||||
#elif
|
||||
#define HGL_LIB_END ".a"
|
||||
#endif//HGL_OS == HGL_OS_Windows
|
||||
#endif//HGL_COMPILER_INTEL_INCLUDE
|
25
inc/hgl/platform/compiler/LLVM.h
Normal file
25
inc/hgl/platform/compiler/LLVM.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef HGL_COMPILER_LLVM_CLANG_INCLUDE
|
||||
#define HGL_COMPILER_LLVM_CLANG_INCLUDE
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_COMPILER_NAME OS_TEXT("LLVM Clang")
|
||||
#define HGL_LIB_COMPILER_NAME OS_TEXT("LLVM")
|
||||
|
||||
#if (__clang_major__<3)||(__clang_major__==3&&__clang_minor__<7)
|
||||
#error Please upgrade your compiler or development tools to LLVM Clang 3.7 or later
|
||||
#else
|
||||
|
||||
#define HGL_LIB_COMPILER_VERSION __clang_version__
|
||||
|
||||
#endif//__clang__
|
||||
|
||||
#define HGL_THREAD_LOCAL_STORAGE __thread //线程本地储存
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_LIB_FRONT HGL_LIB_OS "_" HGL_LIB_COMPILER_NAME "_" HGL_LIB_DEBUG_NAME "_"
|
||||
|
||||
#define HGL_LIB_END ".a"
|
||||
|
||||
#include<hgl/platform/compiler/DataTypeGNU.h>
|
||||
#include<hgl/platform/compiler/DataTypeTiny.h>
|
||||
#include<hgl/platform/compiler/Property.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_COMPILER_LLVM_CLANG_INCLUDE
|
61
inc/hgl/platform/compiler/Microsoft.h
Normal file
61
inc/hgl/platform/compiler/Microsoft.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef HGL_COMPILER_MICROSOFT_INCLUDE
|
||||
#define HGL_COMPILER_MICROSOFT_INCLUDE
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_COMPILER_NAME OS_TEXT("Microsoft C/C++")
|
||||
#define HGL_LIB_COMPILER_NAME OS_TEXT("MSC")
|
||||
|
||||
#if _MSC_VER < 1900 //Visual C++ 2015(19)
|
||||
#error Please upgrade your compiler or development tools to Microsoft C/C++ 19.0 (Visual C++ 2015) or later.
|
||||
#else
|
||||
#if _MSC_VER >= 1910
|
||||
#define HGL_LIB_COMPILER_VERSION OS_TEXT("19.1") //Visual C++ 2017
|
||||
#elif _MSC_VER == 1900
|
||||
#define HGL_LIB_COMPILER_VERSION OS_TEXT("19") //Visual C++ 2015
|
||||
#else
|
||||
#define HGL_LIB_COMPILER_VERSION OS_TEXT("Unknow")
|
||||
#endif//_MSC_VER
|
||||
#endif//_MSC_VER
|
||||
|
||||
#define HGL_THREAD_LOCAL_STORAGE __declspec(thread) //线程本地储存
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_FMT_I64 "%I64d"
|
||||
#define HGL_FMT_U64 "%I64u"
|
||||
//参考文档最后查阅支持版本为VC2013,网址:http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define _USE_MATH_DEFINES // 使用数学常数定义
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#pragma warning(disable:4819) // ansi -> unicode
|
||||
#pragma warning(disable:4311) // 模板警告
|
||||
#pragma warning(disable:4800) // -> bool 性能损失警告
|
||||
#pragma warning(disable:4244) // -> int 精度丢失警告
|
||||
#pragma warning(disable:4804) // 不安全的类型比较
|
||||
#pragma warning(disable:4805) // 不安全的类型比较
|
||||
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif//
|
||||
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif//
|
||||
|
||||
#ifndef _CRT_NON_CONFORMING_SWPRINTFS
|
||||
#define _CRT_NON_CONFORMING_SWPRINTFS
|
||||
#endif//
|
||||
|
||||
#ifdef _DLL
|
||||
#define HGL_LIB_CRT "Dynamic"
|
||||
#else
|
||||
#define HGL_LIB_CRT "Static"
|
||||
#endif//_DLL
|
||||
|
||||
#define HGL_LIB_FRONT HGL_LIB_OS "_" HGL_LIB_COMPILER_NAME "_" HGL_LIB_DEBUG_NAME "_" HGL_LIB_CRT "_"
|
||||
|
||||
#define HGL_LIB_END ".LIB"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<hgl/platform/compiler/DataTypeWin.h>
|
||||
#include<hgl/platform/compiler/DataTypeTiny.h>
|
||||
#include<hgl/platform/compiler/Property.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_COMPILER_MICROSOFT_INCLUDE
|
||||
|
97
inc/hgl/platform/compiler/Property.h
Normal file
97
inc/hgl/platform/compiler/Property.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef HGL_PROPERTY_INCLUDE
|
||||
#define HGL_PROPERTY_INCLUDE
|
||||
|
||||
#include<hgl/platform/compiler/EventFunc.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 只读属性
|
||||
*/
|
||||
template<typename T> class PropertyRead
|
||||
{
|
||||
public:
|
||||
|
||||
DefEvent(T,Get,() const);
|
||||
};//template<typename T> class PropertyRead
|
||||
|
||||
/**
|
||||
* 属性
|
||||
*/
|
||||
template<typename T> class Property
|
||||
{
|
||||
public:
|
||||
|
||||
DefEvent(T,Get,() const);
|
||||
DefEvent(void,Set,(T));
|
||||
|
||||
public:
|
||||
|
||||
Property()
|
||||
{
|
||||
Get=0;
|
||||
Set=0;
|
||||
}
|
||||
|
||||
virtual ~Property() {}
|
||||
|
||||
operator T() const{return Get();}
|
||||
void operator = (T v){Set(v);}
|
||||
void operator = (const Property<T> &v){Set(v.operator T());}
|
||||
|
||||
T operator !(){ return !(operator T());}
|
||||
T operator ~(){ return ~(operator T());}
|
||||
|
||||
T operator ++ () { T v=operator T(); Set(++v); return v; } ///<前置++
|
||||
T operator -- () { T v=operator T(); Set(--v); return v; } ///<前置--
|
||||
|
||||
T operator ++ (int) { T r,v; v=operator T(); r=v; Set(++v); return r; } ///<后置++
|
||||
T operator -- (int) { T r,v; v=operator T(); r=v; Set(--v); return r; } ///<后置--
|
||||
|
||||
void operator += (T v) { if(v){Set(operator T() + v);} }
|
||||
void operator -= (T v) { if(v){Set(operator T() - v);} }
|
||||
void operator *= (T v) { Set(operator T() * v); }
|
||||
void operator /= (T v) { Set(operator T() / v); }
|
||||
void operator %= (T v) { Set(operator T() % v); }
|
||||
|
||||
void operator &= (T v) { Set(operator T() & v); }
|
||||
void operator |= (T v) { Set(operator T() | v); }
|
||||
|
||||
void operator >>= (int n) { Set((operator T())>>n);}
|
||||
void operator <<= (int n) { Set((operator T())<<n);}
|
||||
|
||||
T operator >> (int n) { return (operator T())>>n;}
|
||||
T operator << (int n) { return (operator T())<<n;}
|
||||
|
||||
bool operator == (const T &v){return(operator T()==v);}
|
||||
bool operator != (const T &v){return(operator T()!=v);}
|
||||
};//class Property
|
||||
|
||||
template<typename T> class PropertyObject:public Property<T *>
|
||||
{
|
||||
public:
|
||||
|
||||
T *operator ->()const{return Property<T *>::Get();}
|
||||
void operator =(void *pointer){Property<T *>::Set((T *)pointer);}
|
||||
};//class PropertyObject
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#define cmSetPropertyRead(name,tp,get) {name.Get=tp->get;}
|
||||
#define cmSetPropertyWrite(name,tp,set) {name.Set=tp->set;}
|
||||
#else
|
||||
#define cmSetPropertyRead(name,tp,get) { \
|
||||
name.Get.vp_this=tp; \
|
||||
name.Get.omf=ObjectMemberFunc(&get); \
|
||||
}
|
||||
|
||||
#define cmSetPropertyWrite(name,tp,set) { \
|
||||
name.Set.vp_this=tp; \
|
||||
name.Set.omf=ObjectMemberFunc(&set); \
|
||||
}
|
||||
#endif//
|
||||
|
||||
#define cmSetProperty(name,tp,get,set) { \
|
||||
cmSetPropertyRead(name,tp,get); \
|
||||
cmSetPropertyWrite(name,tp,set); \
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_PROPERTY_INCLUDE
|
86
inc/hgl/platform/os/Android.h
Normal file
86
inc/hgl/platform/os/Android.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef HGL_OS_ANDROID_INCLUDE
|
||||
#define HGL_OS_ANDROID_INCLUDE
|
||||
|
||||
#include<limits.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using u32char =char32_t;
|
||||
using u16char =char16_t;
|
||||
using os_char =char;
|
||||
#define to_oschar to_u8
|
||||
#define OS_TEXT(str) u8##str
|
||||
#define U8_TEXT(str) u8##str
|
||||
#define U16_TEXT(str) u##str
|
||||
|
||||
#define HGL_OS_NAME OS_TEXT("Android")
|
||||
#define HGL_LIB_OS "Android" //库操作系统前缀
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_PLUGIN_FRONTNAME "libCMP." //插件文件名前缀
|
||||
#define HGL_PLUGIN_EXTNAME ".so" //插件文件扩展名
|
||||
#define HGL_PLUGIN_FUNC extern "C" //插件函数定义
|
||||
|
||||
#define HGL_DIRECTORY_SEPARATOR '/' //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_STR OS_TEXT("/") //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_U8STR U8_TEXT("/") //目录分隔符
|
||||
|
||||
#define HGL_LINE_END "\n" //换行符
|
||||
#define HGL_LINE_END_SIZE 1 //换行符长度
|
||||
|
||||
#define HGL_MEM_ALIGN 16 //内存对齐字节数
|
||||
|
||||
#define HGL_MAX_PATH _POSIX_PATH_MAX
|
||||
|
||||
#define HGL_FMT_I64 "%lld"
|
||||
#define HGL_FMT_U64 "%llu"
|
||||
#define HGL_FMT_DOUBLE "%lf"
|
||||
#define HGL_FMT_LONG_DOUBLE "%le"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<malloc.h>
|
||||
#include<stdlib.h>
|
||||
#include<hgl/platform/os/PosixThread.h>
|
||||
|
||||
#define hgl_malloc(size) memalign(HGL_MEM_ALIGN,size) //这个所有版本linux libc都支持
|
||||
//#define hgl_malloc(size) aligned_alloc(HGL_MEM_ALIGN,size) //这个是C11新增,需要libc 2.16
|
||||
#define hgl_realloc(ptr,size) realloc(ptr,size)
|
||||
#define hgl_free free
|
||||
|
||||
template<typename T>
|
||||
inline T *hgl_aligned_malloc(size_t n)
|
||||
{
|
||||
return (T *)memalign(alignof(T),n*sizeof(T));
|
||||
}
|
||||
|
||||
#define OS_EXTERNAL_H <dlfcn.h>
|
||||
typedef void * ExternalModulePointer;
|
||||
#define pi_get dlsym
|
||||
#define pi_close dlclose
|
||||
|
||||
#define iconv_str char *
|
||||
|
||||
#define hgl_stat64 stat
|
||||
#define hgl_open64 open
|
||||
#define hgl_lseek64 lseek
|
||||
#define hgl_tell64(fp) lseek(fp,0,SEEK_CUR)
|
||||
#define hgl_fstat64 fstat
|
||||
#define hgl_lstat64 lstat
|
||||
#define hgl_read64 read
|
||||
#define hgl_write64 write
|
||||
#define hgl_pread64 pread
|
||||
#define hgl_pwrite64 pwrite
|
||||
|
||||
#define struct_stat64 struct stat
|
||||
#define struct_dirent64 struct dirent
|
||||
#define hgl_dirent64 dirent
|
||||
#define hgl_readdir64 readdir
|
||||
|
||||
#define sprintf_s snprintf
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
//初始化Android支持,以下函数二选一
|
||||
|
||||
#include<jni.h>
|
||||
|
||||
void InitAndroidSupport(JNIEnv *env,jobject obj); //JNI混编模式初始化Android支持
|
||||
|
||||
struct ANativeActivity;
|
||||
void InitAndroidSupport(struct ANativeActivity *app); //NativeActivity模式初始化Android支持
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_OS_ANDROID_INCLUDE
|
83
inc/hgl/platform/os/BSD.h
Normal file
83
inc/hgl/platform/os/BSD.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef HGL_OS_BSD_INCLUDE
|
||||
#define HGL_OS_BSD_INCLUDE
|
||||
|
||||
#include<limits.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using u32char =char32_t;
|
||||
using u16char =char16_t;
|
||||
using os_char =char;
|
||||
#define to_oschar to_u8
|
||||
#define OS_TEXT(str) u8##str
|
||||
#define U8_TEXT(str) u8##str
|
||||
#define U16_TEXT(str) u##str
|
||||
|
||||
#if defined(__FreeBSD__)||defined(__FreeBSD)
|
||||
#define HGL_OS_NAME OS_TEXT("FreeBSD")
|
||||
#define HGL_LIB_OS_NAME "FreeBSD"
|
||||
#elif defined(__NetBSD__)||defined(__NetBSD)
|
||||
#define HGL_OS_NAME OS_TEXT("NetBSD")
|
||||
#define HGL_LIB_OS_NAME "NetBSD"
|
||||
#elif defined(__OpenBSD__)||defined(__OPENBSD)
|
||||
#define HGL_OS_NAME OS_TEXT("OpenBSD")
|
||||
#define HGL_LIB_OS_NAME "OpenBSD"
|
||||
#else
|
||||
#define HGL_OS_NAME OS_TEXT("BSD")
|
||||
#define HGL_LIB_OS_NAME "BSD"
|
||||
#endif//
|
||||
|
||||
#define HGL_LIB_OS "BSD" //库操作系统前缀
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_PLUGIN_FRONTNAME "libCMP." //插件文件名前缀
|
||||
#define HGL_PLUGIN_EXTNAME ".so" //插件文件扩展名
|
||||
#define HGL_PLUGIN_FUNC extern "C" //插件函数定义
|
||||
|
||||
#define HGL_DIRECTORY_SEPARATOR '/' //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_STR OS_TEXT("/") //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_U8STR U8_TEXT("/") //目录分隔符
|
||||
|
||||
#define HGL_LINE_END "\n" //换行符
|
||||
#define HGL_LINE_END_SIZE 1 //换行符长度
|
||||
|
||||
#define HGL_MEM_ALIGN 16 //内存对齐字节数
|
||||
|
||||
#define HGL_MAX_PATH _POSIX_PATH_MAX
|
||||
|
||||
#define HGL_FMT_I64 "%lld"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<stdlib.h>
|
||||
#include<hgl/platform/os/PosixThread.h>
|
||||
|
||||
#define hgl_malloc(size) aligned_alloc(HGL_MEM_ALIGN,size) //这个是C11新增,需要libc 2.16
|
||||
#define hgl_realloc realloc
|
||||
#define hgl_free free
|
||||
|
||||
template<typename T>
|
||||
inline T *hgl_aligned_malloc(size_t n)
|
||||
{
|
||||
return (T *)aligned_alloc(alignof(T),n*sizeof(T));
|
||||
}
|
||||
|
||||
#define OS_EXTERNAL_H <dlfcn.h>
|
||||
typedef void * ExternalModulePointer;
|
||||
#define pi_get dlsym
|
||||
#define pi_close dlclose
|
||||
|
||||
typedef pthread_mutex_t hgl_thread_mutex;
|
||||
|
||||
#define hgl_stat64 stat
|
||||
#define hgl_open64 open
|
||||
#define hgl_lseek64 lseek
|
||||
#define hgl_tell64(fp) lseek(fp,0,SEEK_CUR)
|
||||
#define hgl_fstat64 fstat
|
||||
#define hgl_lstat64 lstat
|
||||
#define hgl_read64 read
|
||||
#define hgl_write64 write
|
||||
#define hgl_pread64 pread
|
||||
#define hgl_pwrite64 pwrite
|
||||
|
||||
#define struct_stat64 struct stat
|
||||
#define struct_dirent64 struct dirent
|
||||
#define hgl_dirent64 dirent
|
||||
#define hgl_readdir64 readdir
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_OS_BSD_INCLUDE
|
75
inc/hgl/platform/os/Linux.h
Normal file
75
inc/hgl/platform/os/Linux.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef HGL_OS_LINUX_INCLUDE
|
||||
#define HGL_OS_LINUX_INCLUDE
|
||||
|
||||
#include<limits.h>
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using u32char =char32_t;
|
||||
using u16char =char16_t;
|
||||
using os_char =char;
|
||||
#define to_oschar to_u8
|
||||
#define OS_TEXT(str) u8##str
|
||||
#define U8_TEXT(str) u8##str
|
||||
#define U16_TEXT(str) u##str
|
||||
|
||||
#define HGL_OS_NAME OS_TEXT("Linux")
|
||||
#define HGL_LIB_OS "Linux" //库操作系统前缀
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_PLUGIN_FRONTNAME "libCMP." //插件文件名前缀
|
||||
#define HGL_PLUGIN_EXTNAME ".so" //插件文件扩展名
|
||||
#define HGL_PLUGIN_FUNC extern "C" //插件函数定义
|
||||
|
||||
#define HGL_DIRECTORY_SEPARATOR '/' //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_STR OS_TEXT("/") //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_U8STR U8_TEXT("/") //目录分隔符
|
||||
|
||||
#define HGL_LINE_END "\n" //换行符
|
||||
#define HGL_LINE_END_SIZE 1 //换行符长度
|
||||
|
||||
#define HGL_MEM_ALIGN 16 //内存对齐字节数
|
||||
|
||||
#define HGL_MAX_PATH _POSIX_PATH_MAX
|
||||
|
||||
#define HGL_FMT_I64 "%lld"
|
||||
#define HGL_FMT_U64 "%llu"
|
||||
#define HGL_FMT_DOUBLE "%lf"
|
||||
#define HGL_FMT_LONG_DOUBLE "%le"
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<malloc.h>
|
||||
#include<stdlib.h>
|
||||
#include<hgl/platform/os/PosixThread.h>
|
||||
|
||||
//#define hgl_malloc(size) memalign(HGL_MEM_ALIGN,size) //这个所有版本linux libc都支持
|
||||
#define hgl_malloc(size) aligned_alloc(HGL_MEM_ALIGN,size) //这个是C11新增,需要libc 2.16
|
||||
#define hgl_realloc(ptr,size) realloc(ptr,size)
|
||||
#define hgl_free free
|
||||
|
||||
template<typename T>
|
||||
inline T *hgl_aligned_malloc(size_t n)
|
||||
{
|
||||
return (T *)aligned_alloc(alignof(T),n*sizeof(T));
|
||||
}
|
||||
|
||||
#define OS_EXTERNAL_H <dlfcn.h>
|
||||
typedef void * ExternalModulePointer;
|
||||
#define pi_get dlsym
|
||||
#define pi_close dlclose
|
||||
|
||||
#define hgl_stat64 stat64
|
||||
#define hgl_open64 open64
|
||||
#define hgl_lseek64 lseek64
|
||||
#define hgl_tell64(fp) lseek64(fp,0,SEEK_CUR)
|
||||
#define hgl_fstat64 fstat64
|
||||
#define hgl_lstat64 lstat64
|
||||
#define hgl_read64 read
|
||||
#define hgl_write64 write
|
||||
#define hgl_pread64 pread64
|
||||
#define hgl_pwrite64 pwrite64
|
||||
|
||||
#define struct_stat64 struct stat64
|
||||
#define struct_dirent64 struct dirent64
|
||||
#define hgl_dirent64 dirent64
|
||||
#define hgl_readdir64 readdir64
|
||||
|
||||
#define sprintf_s snprintf
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_OS_LINUX_INCLUDE
|
80
inc/hgl/platform/os/MSWindows.h
Normal file
80
inc/hgl/platform/os/MSWindows.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef HGL_OS_WIN_INCLUDE
|
||||
#define HGL_OS_WIN_INCLUDE
|
||||
|
||||
#include<malloc.h>
|
||||
#include<winsock2.h> //winsock2必须在Windows.h前面,不然会报错
|
||||
#include<windows.h>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using u32char =char32_t;
|
||||
using u16char =wchar_t;
|
||||
using os_char =wchar_t;
|
||||
#define to_oschar to_u16
|
||||
#define OS_TEXT(str) L##str
|
||||
#define U8_TEXT(str) u8##str
|
||||
#define U16_TEXT(str) L##str
|
||||
|
||||
#define HGL_OS_NAME OS_TEXT("Windows")
|
||||
|
||||
#if HGL_CPU == HGL_CPU_X86_32
|
||||
#define HGL_LIB_OS "Win32" //库操作系统前缀
|
||||
#elif HGL_CPU == HGL_CPU_X86_64
|
||||
#define HGL_LIB_OS "Win64" //库操作系统前缀
|
||||
#endif//HGL_CPU
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#define HGL_PLUGIN_FRONTNAME OS_TEXT("CMP.") //插件文件名前缀
|
||||
#define HGL_PLUGIN_EXTNAME OS_TEXT(".DLL") //插件文件扩展名
|
||||
#define HGL_PLUGIN_FUNC extern "C" __declspec(dllexport) //插件函数定义
|
||||
|
||||
#define HGL_DIRECTORY_SEPARATOR OS_TEXT('\\') //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_STR OS_TEXT("\\") //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_U8STR U8_TEXT("\\")
|
||||
|
||||
#define HGL_LINE_END OS_TEXT("\r\n") //换行符
|
||||
#define HGL_LINE_END_SIZE 2 //换行符长度
|
||||
|
||||
#define HGL_MAX_PATH MAX_PATH
|
||||
|
||||
#define HGL_MEM_ALIGN 16 //内存对齐字节数
|
||||
|
||||
#define HGL_GL_WINDOW_INCLUDE_FILE <hgl/platform/WinOpenGL.h> //指定OpenGL窗口引用头文件
|
||||
#define HGL_GL_WINDOW_CLASS WinGLWindow //指定OpenGL窗口类名称
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#if HGL_COMPILER == HGL_COMPILER_Microsoft
|
||||
#define hgl_malloc(size) _aligned_malloc(size,HGL_MEM_ALIGN)
|
||||
#define hgl_realloc(ptr,size) _aligned_realloc(ptr,size,HGL_MEM_ALIGN)
|
||||
#define hgl_free _aligned_free
|
||||
|
||||
template<typename T>
|
||||
inline T *hgl_aligned_malloc(size_t n)
|
||||
{
|
||||
return (T *)_aligned_malloc(n*sizeof(T),alignof(T));
|
||||
}
|
||||
#else
|
||||
#define hgl_malloc(size) memalign(HGL_MEM_ALIGN,size)
|
||||
#define hgl_realloc(ptr,size) realloc(ptr,size)
|
||||
#define hgl_free free
|
||||
#endif//
|
||||
|
||||
#define OS_EXTERNAL_H <winbase.h>
|
||||
typedef HMODULE ExternalModulePointer;
|
||||
#define pi_get GetProcAddress
|
||||
#define pi_close FreeLibrary
|
||||
|
||||
#define struct_stat64 struct _stat64
|
||||
//#define hgl_stat64 _stat64
|
||||
#define hgl_lseek64 _lseeki64
|
||||
#define hgl_tell64(fp) _telli64(fp)
|
||||
#define hgl_fstat64 _fstati64
|
||||
#define hgl_lstat64 _wstat64
|
||||
#define hgl_read64 _read
|
||||
#define hgl_write64 _write
|
||||
|
||||
using hgl_thread_mutex =CRITICAL_SECTION;
|
||||
using thread_ptr =HANDLE;
|
||||
#define THREAD_FUNC DWORD WINAPI
|
||||
#define HGL_THREAD_DETACH_SELF
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_OS_WIN_INCLUDE
|
78
inc/hgl/platform/os/MacOS.h
Normal file
78
inc/hgl/platform/os/MacOS.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef HGL_OS_MACOS_INCLUDE
|
||||
#define HGL_OS_MACOS_INCLUDE
|
||||
|
||||
#include<dirent.h>
|
||||
//------------------------------------------------------------------
|
||||
using u32char =char32_t;
|
||||
using u16char =char16_t;
|
||||
using os_char =char;
|
||||
#define to_oschar to_u8
|
||||
#define OS_TEXT(str) u8##str
|
||||
#define U8_TEXT(str) u8##str
|
||||
#define U16_TEXT(str) u##str
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#if HGL_OS == HGL_OS_iOS
|
||||
#define HGL_OS_NAME OS_TEXT("iOS")
|
||||
#define HGL_LIB_OS "iOS" //库操作系统前缀
|
||||
#else
|
||||
#define HGL_OS_NAME OS_TEXT("macOS")
|
||||
#define HGL_LIB_OS "mac" //库操作系统前缀
|
||||
#endif//HGL_OS == HGL_OS_iOS
|
||||
|
||||
#define HGL_PLUGIN_FRONTNAME "libCMP." //插件文件名前缀
|
||||
#define HGL_PLUGIN_EXTNAME OS_TEXT(".dylib") //插件文件扩展名
|
||||
#define HGL_PLUGIN_FUNC extern "C" //插件函数定义
|
||||
|
||||
#define HGL_DIRECTORY_SEPARATOR '/' //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_STR OS_TEXT("/") //目录分隔符
|
||||
#define HGL_DIRECTORY_SEPARATOR_U8STR U8_TEXT("/") //目录分隔符
|
||||
|
||||
#define HGL_LINE_END "\n" //换行符
|
||||
#define HGL_LINE_END_SIZE 1 //换行符长度
|
||||
|
||||
#define HGL_MEM_ALIGN 16 //内存对齐字节数
|
||||
|
||||
#define HGL_MAX_PATH __DARWIN_MAXPATHLEN
|
||||
|
||||
#define HGL_FMT_I64 "%lld"
|
||||
#define HGL_FMT_U64 "%llu"
|
||||
#define HGL_FMT_DOUBLE "%lf"
|
||||
#define HGL_FMT_LONG_DOUBLE "%le"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#include<hgl/platform/os/PosixThread.h>
|
||||
#include<stdlib.h>
|
||||
|
||||
#define hgl_malloc(size) malloc(size)
|
||||
#define hgl_realloc(ptr,size) realloc(ptr,size)
|
||||
#define hgl_free free
|
||||
|
||||
template<typename T>
|
||||
inline T *hgl_aligned_malloc(size_t n)
|
||||
{
|
||||
return (T *)hgl_malloc(n*sizeof(T));
|
||||
}
|
||||
|
||||
#define OS_EXTERNAL_H <dlfcn.h>
|
||||
using ExternalModulePointer=void *;
|
||||
#define pi_get dlsym
|
||||
#define pi_close dlclose
|
||||
|
||||
#define hgl_stat64 stat
|
||||
#define hgl_open64 open
|
||||
#define hgl_lseek64 lseek
|
||||
#define hgl_tell64(fp) lseek(fp,0,SEEK_CUR)
|
||||
#define hgl_fstat64 fstat
|
||||
#define hgl_lstat64 lstat
|
||||
#define hgl_read64 read
|
||||
#define hgl_write64 write
|
||||
#define hgl_pread64 pread
|
||||
#define hgl_pwrite64 pwrite
|
||||
|
||||
#define struct_stat64 struct stat
|
||||
#define struct_dirent64 struct dirent
|
||||
#define hgl_dirent64 dirent
|
||||
#define hgl_readdir64 readdir
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
#endif//HGL_OS_MACOS_INCLUDE
|
15
inc/hgl/platform/os/PosixThread.h
Normal file
15
inc/hgl/platform/os/PosixThread.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef HGL_POSIX_THREAD_INCLUDE
|
||||
#define HGL_POSIX_THREAD_INCLUDE
|
||||
|
||||
#include<pthread.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
using hgl_thread_mutex =pthread_mutex_t;
|
||||
|
||||
using thread_ptr =pthread_t;
|
||||
using THREAD_FUNC =void *;
|
||||
|
||||
#define HGL_THREAD_DETACH_SELF pthread_detach(pthread_self());
|
||||
}//namespace hgl
|
||||
#endif//HGL_POSIX_THREAD_INCLUDE
|
123
inc/hgl/thread/ASyncEvent.h
Normal file
123
inc/hgl/thread/ASyncEvent.h
Normal file
@ -0,0 +1,123 @@
|
||||
#ifndef HGL_THREAD_ASYNC_EVENT_INCLUDE
|
||||
#define HGL_THREAD_ASYNC_EVENT_INCLUDE
|
||||
|
||||
#include<hgl/thread/SwapData.h>
|
||||
#include<hgl/type/Queue.h>
|
||||
#include<hgl/thread/Thread.h>
|
||||
#include<hgl/Time.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace async
|
||||
{
|
||||
/**
|
||||
* 事件基类
|
||||
*/
|
||||
class EventProc
|
||||
{
|
||||
public:
|
||||
|
||||
EventProc()=default;
|
||||
virtual ~EventProc()=default;
|
||||
|
||||
virtual bool Proc(const double &cur_time)=0;
|
||||
};//class EventProc
|
||||
|
||||
using EventProcQueue=Queue<EventProc *>;
|
||||
using MTEventProcQueue=SemSwapData<EventProcQueue>;
|
||||
using MTEventProcPost=PostToSemSwapData<EventProcQueue>; ///<多线程事件结果投递对象重定义
|
||||
|
||||
/**
|
||||
* 增加事件到队列
|
||||
* @param queue 事件队列
|
||||
* @param event 事件
|
||||
*/
|
||||
inline void AddToEventQueue(MTEventProcQueue *queue,EventProc *event)
|
||||
{
|
||||
if(!queue||!event)
|
||||
return;
|
||||
|
||||
MTEventProcPost post(queue);
|
||||
|
||||
post->Push(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新执行事件队列
|
||||
* @param proc_queue 要执行的事件队列
|
||||
* @param cur_time 当前时间
|
||||
* @param wait 是否等待有事件
|
||||
*/
|
||||
inline void UpdateEventProcQueue(MTEventProcQueue *proc_queue,const double &cur_time,bool wait=false)
|
||||
{
|
||||
if(!proc_queue)
|
||||
return;
|
||||
|
||||
if(wait)
|
||||
{
|
||||
if(!proc_queue->WaitSemSwap())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!proc_queue->TrySemSwap())
|
||||
return;
|
||||
}
|
||||
|
||||
EventProcQueue &epq=proc_queue->GetReceive();
|
||||
|
||||
if(epq.GetCount()<=0)
|
||||
return;
|
||||
|
||||
EventProc *event;
|
||||
|
||||
while(epq.Pop(event))
|
||||
{
|
||||
event->Proc(cur_time);
|
||||
delete event;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步事件执行线程
|
||||
*/
|
||||
class EventThread:public Thread
|
||||
{
|
||||
MTEventProcQueue *event_proc_queue;
|
||||
|
||||
public:
|
||||
|
||||
EventThread(MTEventProcQueue *queue):event_proc_queue(queue){}
|
||||
virtual ~EventThread()=default;
|
||||
|
||||
bool Execute() override
|
||||
{
|
||||
if(!event_proc_queue)
|
||||
return(false);
|
||||
|
||||
UpdateEventProcQueue(event_proc_queue,GetDoubleTime(),true);
|
||||
|
||||
return(true);
|
||||
}
|
||||
};//class EventThread:public Thread
|
||||
|
||||
/**
|
||||
* 使用范例
|
||||
*/
|
||||
/*
|
||||
// 公用部分
|
||||
|
||||
MTEventProcQueue event_queue; ///<事件队列
|
||||
|
||||
// 其它 thread
|
||||
|
||||
class MyEvent:public EventProc{...}; //自有事件
|
||||
|
||||
AddToEventQueue(&event_queue,new MyEvent); //添加一个事件到事件队列
|
||||
|
||||
// 事件执行线程
|
||||
EventThread *et=new EventThread(&event_queue);
|
||||
et->Start();*/
|
||||
}//namespace async
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_ASYNC_EVENT_INCLUDE
|
61
inc/hgl/thread/Atomic.h
Normal file
61
inc/hgl/thread/Atomic.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef HGL_ATOMIC_INCLUDE
|
||||
#define HGL_ATOMIC_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
#include<hgl/thread/atomic/AtomicWin.h>
|
||||
#elif (HGL_OS == HGL_OS_macOS)||(HGL_OS == HGL_OS_Android)
|
||||
#include<atomic>
|
||||
|
||||
template<typename T> using atom=std::atomic<T>;
|
||||
#elif defined(__GNUC__)
|
||||
#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) && (defined(__x86_64__) || defined(__i386__) || defined(__powerpc__))
|
||||
#include<hgl/thread/atomic/AtomicGNU.h>
|
||||
#else
|
||||
#include<hgl/thread/atomic/AtomicAPR.h>
|
||||
#endif//
|
||||
#endif//
|
||||
|
||||
//ps.1:老旧的Linux/32bit下原子仅支持24位,但我们设定为不支持旧的Linux
|
||||
//ps.2:使用GCC 4.1内置宏实现的AtomicGNU的不支持doubel型处理,如需支持,则尽可能不要用atom_double
|
||||
|
||||
//ps..........GCC4.7/4.8/4.9下如果使用c++11的atomic会造成一些valgrind-memcheck报错,所以暂不使用。待valgrind更新
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
#if (HGL_OS == HGL_OS_Windows)//&&(!defined(HGL_ATOMIC_CPP11))
|
||||
typedef atom_win32<int > atom_int;
|
||||
typedef atom_win32<uint > atom_uint;
|
||||
typedef atom_win32<int32 > atom_int32;
|
||||
typedef atom_win32<uint32 > atom_uint32;
|
||||
typedef atom_win64<int64 > atom_int64;
|
||||
typedef atom_win64<uint64 > atom_uint64;
|
||||
typedef atom_win32<float > atom_float;
|
||||
// typedef atom_win64<double > atom_double;
|
||||
|
||||
typedef atom_win32<bool > atom_bool;
|
||||
typedef atom_win32<char > atom_char;
|
||||
typedef atom_win32<uchar > atom_uchar;
|
||||
// typedef atom_win32<wchar_t > atom_wchar;
|
||||
typedef atom_win32<u16char > atom_char16;
|
||||
// typedef atom_win32<char32_t > atom_char32;
|
||||
#else
|
||||
typedef atom<bool > atom_bool;
|
||||
typedef atom<int > atom_int;
|
||||
typedef atom<uint > atom_uint;
|
||||
typedef atom<int32 > atom_int32;
|
||||
typedef atom<uint32 > atom_uint32;
|
||||
typedef atom<int64 > atom_int64;
|
||||
typedef atom<uint64 > atom_uint64;
|
||||
typedef atom<float > atom_float;
|
||||
// typedef atom<double > atom_double;
|
||||
|
||||
typedef atom<char > atom_char;
|
||||
typedef atom<uchar > atom_uchar;
|
||||
// typedef atom<wchar_t > atom_wchar;
|
||||
typedef atom<u16char > atom_char16;
|
||||
// typedef atom<char32_t > atom_char32;
|
||||
#endif//windows & !c++11
|
||||
}//namespace hgl
|
||||
#endif//HGL_ATOMIC_INCLUDE
|
32
inc/hgl/thread/CondVar.h
Normal file
32
inc/hgl/thread/CondVar.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef HGL_MULTI_THREAD_CONDITION_VARIABLE_INCLUDE
|
||||
#define HGL_MULTI_THREAD_CONDITION_VARIABLE_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
namespace hgl
|
||||
{
|
||||
class ThreadMutex;
|
||||
class RWLock;
|
||||
|
||||
/**
|
||||
* 条件变量
|
||||
*/
|
||||
class CondVar
|
||||
{
|
||||
void *cond_var;
|
||||
|
||||
public:
|
||||
|
||||
CondVar();
|
||||
virtual ~CondVar();
|
||||
|
||||
bool Wait(ThreadMutex *,double time=0); ///<释放指定ThreadMutex,在条件符合后重新锁定并结束等待,0表示永久
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
bool Wait(RWLock *,double time=0,bool read=false); ///<释放指定RWLock,在条件符合后重新锁定并结束等待。(注:此函数仅在Windows 2008/Vista及更新版本中支持,Linux/BSD版不支持)
|
||||
#endif//HGL_OS == HGL_OS_Windows
|
||||
|
||||
void Signal(); ///<发送一个信号,让一个等待的线程解锁
|
||||
void Broadcast(); ///<广播一个信号,让所有等待的线程都解锁
|
||||
};//class CondVar
|
||||
}//namespace hgl
|
||||
#endif//HGL_MULTI_THREAD_CONDITION_VARIABLE_INCLUDE
|
156
inc/hgl/thread/DataPost.h
Normal file
156
inc/hgl/thread/DataPost.h
Normal file
@ -0,0 +1,156 @@
|
||||
#ifndef HGL_THREAD_DATA_POST_INCLUDE
|
||||
#define HGL_THREAD_DATA_POST_INCLUDE
|
||||
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/thread/Semaphore.h>
|
||||
#include<hgl/type/Stack.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 多线程数据投递模板<br>
|
||||
* 需要注意每个任务都会重新由空闲线程来进行获取,所以请将连续的任务合并为一个任务,而不是一次大量投递。
|
||||
*/
|
||||
template<typename T> class DataPost
|
||||
{
|
||||
protected:
|
||||
|
||||
List<T *> data_list[2];
|
||||
|
||||
int post_index,recv_index;
|
||||
int recv_offset;
|
||||
|
||||
ThreadMutex post_lock,recv_lock;
|
||||
|
||||
protected:
|
||||
|
||||
void _Swap()
|
||||
{
|
||||
if(recv_index){recv_index=0;post_index=1;}
|
||||
else{recv_index=1;post_index=0;}
|
||||
|
||||
recv_offset=0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
DataPost()
|
||||
{
|
||||
post_index=0;
|
||||
recv_index=1;
|
||||
|
||||
recv_offset=0;
|
||||
}
|
||||
|
||||
virtual ~DataPost()=default;
|
||||
|
||||
/**
|
||||
* 投递一个数据
|
||||
*/
|
||||
void Post(T *obj)
|
||||
{
|
||||
if(!obj)return;
|
||||
|
||||
post_lock.Lock();
|
||||
data_list[post_index].Add(obj);
|
||||
post_lock.Unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* 投递一批数据
|
||||
*/
|
||||
void Post(T **obj,int count)
|
||||
{
|
||||
if(!obj)return;
|
||||
|
||||
post_lock.Lock();
|
||||
data_list[post_index].Add(obj,count);
|
||||
post_lock.Unlock();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* 获取一个数据
|
||||
*/
|
||||
T *Receive()
|
||||
{
|
||||
T *obj=nullptr;
|
||||
|
||||
recv_lock.Lock();
|
||||
int count=data_list[recv_index].GetCount();
|
||||
|
||||
if(recv_offset<count)
|
||||
{
|
||||
obj=*(data_list[recv_index].GetData()+recv_offset);
|
||||
|
||||
++recv_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
data_list[recv_index].ClearData(); //清空接收区的数据
|
||||
|
||||
post_lock.Lock();
|
||||
_Swap();
|
||||
post_lock.Unlock();
|
||||
|
||||
count=data_list[recv_index].GetCount();
|
||||
if(count>0) //如果换出来的区有数据
|
||||
{
|
||||
obj=*(data_list[recv_index].GetData()+recv_offset);
|
||||
|
||||
++recv_offset;
|
||||
}
|
||||
}
|
||||
recv_lock.Unlock();
|
||||
|
||||
return obj;
|
||||
}
|
||||
};//template<typename T> class DataPost
|
||||
|
||||
/**
|
||||
* 信号自动交换数据访问模板
|
||||
*/
|
||||
template<typename T> class SemDataPost:public DataPost<T>
|
||||
{
|
||||
Semaphore sem;
|
||||
|
||||
public:
|
||||
|
||||
using DataPost<T>::DataPost;
|
||||
~SemDataPost()=default;
|
||||
|
||||
/**
|
||||
* 释放接收信号
|
||||
* @param count 信号个数
|
||||
*/
|
||||
void PostSem(int count=1)
|
||||
{
|
||||
sem.Post(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待获取一个信号并获取数据
|
||||
* @param time_out 等待时长
|
||||
*/
|
||||
T *WaitSemReceive(const double time_out=5)
|
||||
{
|
||||
if(!sem.Acquire(time_out))
|
||||
return(nullptr);
|
||||
|
||||
return this->Receive();
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试获取一个信号并获取数据
|
||||
*/
|
||||
T *TrySemReceive()
|
||||
{
|
||||
if(!sem.TryAcquire())
|
||||
return(nullptr);
|
||||
|
||||
return this->Receive();
|
||||
}
|
||||
};//template<typename T> class SemDataPost:public DataPost<T>
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_DATA_POST_INCLUDE
|
74
inc/hgl/thread/Loader.h
Normal file
74
inc/hgl/thread/Loader.h
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef HGL_LOADER_INCLUDE
|
||||
#define HGL_LOADER_INCLUDE
|
||||
|
||||
#include<cm.h>
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/object/EnumObject.h>
|
||||
#include<hgl/thread/Thread.h>
|
||||
namespace hgl
|
||||
{
|
||||
class HAC;
|
||||
|
||||
/**
|
||||
* 加载器,用于异步加载数据
|
||||
*/
|
||||
class Loader:public EnumObject,public Thread ///加载器
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 加载器状态枚举
|
||||
*/
|
||||
enum LoaderStatus //加载器状态
|
||||
{
|
||||
lsNone=0, //未使用
|
||||
|
||||
lsLoad, //正在加载
|
||||
lsProc, //正在处理
|
||||
lsProcFinish, //处理完成
|
||||
lsClear, //清理
|
||||
lsClearFinish, //清理完成
|
||||
|
||||
lsEnd, //完成
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
LoaderStatus status;
|
||||
|
||||
void SetStatus(LoaderStatus);
|
||||
|
||||
HAC *loader_hac;
|
||||
UTF16String loader_filename;
|
||||
void *loader_pointer;
|
||||
void *loader_data;
|
||||
int loader_size;
|
||||
|
||||
protected: //被动事件
|
||||
|
||||
virtual void ProcFinish()=default; ///<加载完成(异步事件)
|
||||
virtual void ProcEnd()=default; ///<结束处理
|
||||
virtual void ProcClear()=default; ///<清理处理(异步事件)
|
||||
|
||||
public: //事件
|
||||
|
||||
DefEvent(void,OnError,(Loader *)); ///<出错事件
|
||||
DefEvent(void,OnEnd,(Loader *)); ///<完成事件,在ProcEnd之后,ProcClear之前被调用
|
||||
|
||||
public:
|
||||
|
||||
Loader();
|
||||
virtual ~Loader()=default;
|
||||
|
||||
bool Execute();
|
||||
|
||||
void Update();
|
||||
|
||||
public: //方法
|
||||
|
||||
bool Load(HAC *,const u16char *); ///<加载一个文件到某个对象
|
||||
|
||||
LoaderStatus GetStatus(); ///<取得状态
|
||||
};//class Loader
|
||||
}//namespace hgl
|
||||
#endif//HGL_LOADER_INCLUDE
|
187
inc/hgl/thread/RWLock.h
Normal file
187
inc/hgl/thread/RWLock.h
Normal file
@ -0,0 +1,187 @@
|
||||
#ifndef HGL_RWLOCK_INCLUDE
|
||||
#define HGL_RWLOCK_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 读写锁/共享锁
|
||||
*/
|
||||
class RWLock ///读写锁/共享锁
|
||||
{
|
||||
void *lock;
|
||||
|
||||
public:
|
||||
|
||||
RWLock();
|
||||
virtual ~RWLock();
|
||||
|
||||
void *GetRWLock(){ return lock; } ///<返回操作系级锁
|
||||
|
||||
bool TryReadLock(); ///<尝试读(共享访问)锁定
|
||||
bool ReadLock(); ///<读(共享访问)锁定
|
||||
bool ReadUnlock(); ///<读(共享访问)解锁
|
||||
|
||||
bool TryWriteLock(); ///<尝试写(独占访问)锁定
|
||||
bool WriteLock(); ///<写(独占访问)锁定
|
||||
bool WriteUnlock(); ///<写(独占访问)解锁
|
||||
|
||||
#if (HGL_OS != HGL_OS_Windows)&&(HGL_OS != HGL_OS_macOS)
|
||||
bool WaitReadLock(double); ///<等待读(共享访问)锁定
|
||||
bool WaitWriteLock(double); ///<等待写(独占访问)锁定
|
||||
#endif//(HGL_OS != HGL_OS_Windows)&&(HGL_OS != HGL_OS_macOS)
|
||||
};//class RWLock
|
||||
|
||||
#define HGL_RWLOCK(lock) bool ReadLock() {return lock.ReadLock(); } \
|
||||
bool WriteLock() {return lock.WriteLock(); } \
|
||||
bool TryReadLock() {return lock.TryReadLock(); } \
|
||||
bool TryWriteLock() {return lock.TryWriteLock();} \
|
||||
bool ReadUnlock() {return lock.ReadUnlock(); } \
|
||||
bool WriteUnlock() {return lock.WriteUnlock(); }
|
||||
|
||||
#define HGL_RWLOCK_PTR(lock) bool ReadLock() {return lock->ReadLock(); } \
|
||||
bool WriteLock() {return lock->WriteLock(); } \
|
||||
bool TryReadLock() {return lock->TryReadLock(); } \
|
||||
bool TryWriteLock() {return lock->TryWriteLock(); } \
|
||||
bool ReadUnlock() {return lock->ReadUnlock(); } \
|
||||
bool WriteUnlock() {return lock->WriteUnlock(); }
|
||||
|
||||
#define HGL_NULL_RWLOCK bool ReadLock() {return true;} \
|
||||
bool WriteLock() {return true;} \
|
||||
bool TryReadLock() {return true;} \
|
||||
bool TryWriteLock() {return true;} \
|
||||
bool ReadUnlock() {return true;} \
|
||||
bool WriteUnlock() {return true;} \
|
||||
|
||||
#define HGL_VIRTUAL_NULL_RWLOCK virtual bool ReadLock() {return true;} \
|
||||
virtual bool WriteLock() {return true;} \
|
||||
virtual bool TryReadLock() {return true;} \
|
||||
virtual bool TryWriteLock() {return true;} \
|
||||
virtual bool ReadUnlock() {return true;} \
|
||||
virtual bool WriteUnlock() {return true;} \
|
||||
|
||||
/**
|
||||
* 读写锁/共享锁对象
|
||||
*/
|
||||
template<typename T> class RWLockObject:public RWLock
|
||||
{
|
||||
T *data;
|
||||
|
||||
public:
|
||||
|
||||
RWLockObject()
|
||||
{
|
||||
data=new T;
|
||||
}
|
||||
|
||||
RWLockObject(T *t)
|
||||
{
|
||||
data=t;
|
||||
}
|
||||
|
||||
virtual ~RWLockObject()
|
||||
{
|
||||
SAFE_CLEAR(data);
|
||||
}
|
||||
|
||||
void operator = (T *t)
|
||||
{
|
||||
if(data)
|
||||
delete data;
|
||||
|
||||
data=t;
|
||||
}
|
||||
|
||||
T *operator ->()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
bool valid()const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
bool operator !()
|
||||
{
|
||||
return !data;
|
||||
}
|
||||
};//class RWLockObject
|
||||
|
||||
/**
|
||||
* 读写锁共享锁定自动释放类
|
||||
*/
|
||||
class OnlyReadLock
|
||||
{
|
||||
RWLock *rw;
|
||||
|
||||
public:
|
||||
|
||||
OnlyReadLock(RWLock &rw_lock)
|
||||
{
|
||||
rw=&rw_lock;
|
||||
|
||||
rw->ReadLock();
|
||||
}
|
||||
|
||||
OnlyReadLock(RWLock *rw_lock)
|
||||
{
|
||||
rw=rw_lock;
|
||||
|
||||
rw->ReadLock();
|
||||
}
|
||||
|
||||
~OnlyReadLock()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if(rw)
|
||||
{
|
||||
rw->ReadUnlock();
|
||||
rw=nullptr;
|
||||
}
|
||||
}
|
||||
};//class ReadLock
|
||||
|
||||
/**
|
||||
* 读写锁独占访问锁定自动释放类
|
||||
*/
|
||||
class OnlyWriteLock
|
||||
{
|
||||
RWLock *rw;
|
||||
|
||||
public:
|
||||
|
||||
OnlyWriteLock(RWLock &rw_lock)
|
||||
{
|
||||
rw=&rw_lock;
|
||||
|
||||
rw->WriteLock();
|
||||
}
|
||||
|
||||
OnlyWriteLock(RWLock *rw_lock)
|
||||
{
|
||||
rw=rw_lock;
|
||||
|
||||
rw->WriteLock();
|
||||
}
|
||||
|
||||
~OnlyWriteLock()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if(rw)
|
||||
{
|
||||
rw->WriteUnlock();
|
||||
rw=nullptr;
|
||||
}
|
||||
}
|
||||
};//class WriteLock
|
||||
}//namespace hgl
|
||||
#endif//HGL_RWLOCK_INCLUDE
|
58
inc/hgl/thread/RingBuffer.cpp
Normal file
58
inc/hgl/thread/RingBuffer.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef HGL_THREAD_RING_BUFFER_SOURCE
|
||||
#define HGL_THREAD_RING_BUFFER_SOURCE
|
||||
|
||||
/**
|
||||
* 由于设定read_pos=write_pos表示无数据,所以当数据刚好读写到结尾时,不立即转成0,而是仍为buffer_size
|
||||
*/
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T>
|
||||
RingBuffer<T>::RingBuffer(int size)
|
||||
{
|
||||
buffer_size=size;
|
||||
|
||||
buffer=new T[size];
|
||||
|
||||
// memset(buffer,0,size); //有write_pos/read_pos没有根本读不出数据,所以无需清0
|
||||
|
||||
read_pos=0;
|
||||
write_pos=0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
RingBuffer<T>::~RingBuffer()
|
||||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::Clear()
|
||||
{
|
||||
read_pos=0;
|
||||
write_pos=0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::SafeClear()
|
||||
{
|
||||
Lock();
|
||||
Clear();
|
||||
Unlock();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RingBuffer<T>::ClampPosition()
|
||||
{
|
||||
if(read_pos<buffer_size
|
||||
||write_pos<buffer_size)return; //将指针减去整数部分,以免溢出
|
||||
|
||||
//不可以用read_pos%=buffer_size,write_pos%=buffer_size。
|
||||
//因为有可能read_pos=0,write_pos=buffersize,都用%buffer_size就会形成两个都为0的错误。
|
||||
//一般也就破一次界限,所以效能影响无所谓。
|
||||
|
||||
read_pos-=buffer_size;
|
||||
write_pos-=buffer_size;
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_RING_BUFFER_SOURCE
|
345
inc/hgl/thread/RingBuffer.h
Normal file
345
inc/hgl/thread/RingBuffer.h
Normal file
@ -0,0 +1,345 @@
|
||||
#ifndef HGL_THREAD_RING_BUFFER_INCLUDE
|
||||
#define HGL_THREAD_RING_BUFFER_INCLUDE
|
||||
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/io/InputStream.h>
|
||||
#include<hgl/io/OutputStream.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 多线程环形数据流,用于随时被读或写的情况以及在多线程应用中同时被读与写的情况。
|
||||
*/
|
||||
template<typename T> class RingBuffer:protected ThreadMutex ///多线程环形数据流
|
||||
{
|
||||
protected:
|
||||
|
||||
T *buffer;
|
||||
int buffer_size;
|
||||
|
||||
int read_pos,write_pos;
|
||||
|
||||
int read_cur,write_cur;
|
||||
int read_off,write_off;
|
||||
int read_max,write_max;
|
||||
int read_count,write_count;
|
||||
|
||||
bool read_peek;
|
||||
|
||||
protected:
|
||||
|
||||
void ClampPosition();
|
||||
|
||||
int _GetReadSize()const{return write_pos-read_pos;}
|
||||
int _GetWriteSize()const{return buffer_size-(write_pos-read_pos);}
|
||||
|
||||
int _SafeWriteStart();
|
||||
int _SafeReadStart(bool);
|
||||
|
||||
int _Write(const T *,int);
|
||||
int _Read(T *,int,bool);
|
||||
|
||||
public:
|
||||
|
||||
RingBuffer(int); ///<本类构造函数
|
||||
virtual ~RingBuffer(); ///<本类析构函数
|
||||
|
||||
const int GetBufferSize()const{return buffer_size;} ///<除取缓冲区长度
|
||||
|
||||
void Clear(); ///<清除整个缓冲区
|
||||
void SafeClear(); ///<安全清除整个缓冲区
|
||||
|
||||
public: //写处理函数
|
||||
|
||||
int WriteStart(); ///<开始写入
|
||||
int GetWriteSize()const{return write_max;} ///<取得可写入数据长度
|
||||
int Write(const T *,int); ///<向流中写入数据
|
||||
int WriteEnd(); ///<结束写入
|
||||
|
||||
int SafeTryWriteStart(); ///<安全尝试开始写入
|
||||
int SafeWriteStart(); ///<安全开始写入
|
||||
int SafeWriteEnd(); ///<安全结束写入
|
||||
|
||||
int SafeGetWriteSize(); ///<安全取得可写入数据长度
|
||||
int SafeWrite(const T *,int); ///<安全写入,用于简单的一次性写入
|
||||
|
||||
public: //读处理函数
|
||||
|
||||
int ReadStart(bool=true); ///<开始读取
|
||||
int GetReadSize()const{return read_max;} ///<取得可读取数据长度
|
||||
int Read(T *,int,bool=true); ///<从流中读取数据
|
||||
int Peek(T *ptr,int size){return Read(ptr,size,false);} ///<从流中预读数据
|
||||
int Skip(int size){return Read(0,size,true);} ///<跳过流中的指定长度数据
|
||||
int ReadEnd(); ///<结束写入
|
||||
|
||||
int SafeTryReadStart(bool=true); ///<安全尝试开始读取
|
||||
int SafeReadStart(bool=true); ///<安全开始读取
|
||||
int SafeReadEnd(); ///<安全结束读取
|
||||
|
||||
int SafeGetReadSize(); ///<安全取得可读取数据长度
|
||||
bool SafeTryGetReadSize(int &); ///<安全尝试取得可读取数据长度
|
||||
int SafeRead(T *,int,bool=true); ///<安全读取,用于简单的一次性读取
|
||||
int SafePeek(T *ptr,int size){return SafeRead(ptr,size,false);} ///<安全预读数据
|
||||
};//class RingBuffer
|
||||
}//namespace hgl
|
||||
|
||||
#include<hgl/thread/RingBuffer.cpp>
|
||||
#include<hgl/thread/RingBufferRead.cpp>
|
||||
#include<hgl/thread/RingBufferWrite.cpp>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
class RingInputStream:public InputStream
|
||||
{
|
||||
RingBuffer<char> *rb;
|
||||
|
||||
public:
|
||||
|
||||
RingInputStream (RingBuffer<char> *_rb){rb=_rb;}
|
||||
|
||||
RingBuffer<char> *GetRingBuffer(){return rb;}
|
||||
|
||||
int Start (){return rb?rb->ReadStart():-1;}
|
||||
int End (){return rb?rb->ReadEnd():-1;}
|
||||
int SafeStart (){return rb?rb->SafeReadStart():-1;}
|
||||
int SafeEnd (){return rb?rb->SafeReadEnd():-1;}
|
||||
|
||||
void Close (){}
|
||||
|
||||
public:
|
||||
|
||||
int64 Read (void *buf,int64 size){return rb?rb->Read((char *)buf,size):-1;} ///<读取数据
|
||||
int64 Peek (void *buf,int64 size){return rb?rb->Peek((char *)buf,size):-1;} ///<预览数据
|
||||
|
||||
bool CanRestart ()const{return false;} ///<是否可以复位
|
||||
bool CanSeek ()const{return false;} ///<是否可以定位
|
||||
bool CanSize ()const{return false;} ///<是否可以取得尺寸
|
||||
bool CanPeek ()const{return false;} ///<是否可以预览数据
|
||||
|
||||
bool Restart (){return false;} ///<复位访问指针
|
||||
int64 Skip (int64 size){return rb?rb->Skip(size):-1;} ///<跳过指定字节不访问
|
||||
int64 Seek (int64,SeekOrigin){return -1;} ///<移动访问指针
|
||||
int64 Tell ()const{return -1;} ///<返回当前访问位置
|
||||
int64 GetSize ()const{return -1;} ///<取得流长度
|
||||
int64 Available ()const{return rb?rb->GetReadSize():-1;} ///<剩下的可以不受阻塞访问的字节数
|
||||
};//class RingInputStream
|
||||
|
||||
class RingOutputStream:public OutputStream
|
||||
{
|
||||
RingBuffer<char> *rb;
|
||||
|
||||
public:
|
||||
|
||||
RingOutputStream (RingBuffer<char> *_rb){rb=_rb;}
|
||||
|
||||
RingBuffer<char> *GetRingBuffer(){return rb;}
|
||||
|
||||
int Start (){return rb?rb->WriteStart():-1;}
|
||||
int End (){return rb?rb->WriteEnd():-1;}
|
||||
int SafeStart (){return rb?rb->SafeWriteStart():-1;}
|
||||
int SafeEnd (){return rb?rb->SafeWriteEnd():-1;}
|
||||
|
||||
void Close (){}
|
||||
|
||||
public:
|
||||
|
||||
int64 Write (const void *buf,int64 size){return rb?rb->Write((char *)buf,size):-1;} ///<写入数据
|
||||
|
||||
bool CanRestart ()const{return false;}; ///<是否可以复位
|
||||
bool CanSeek ()const{return false;}; ///<是否可以定位
|
||||
bool CanSize ()const{return false;} ///<是否可以取得尺寸
|
||||
|
||||
bool Restart (){return false;} ///<复位访问指针
|
||||
int64 Seek (int64,SeekOrigin){return -1;} ///<移动访问指针
|
||||
int64 Tell ()const{return -1;} ///<返回当前访问位置
|
||||
int64 GetSize ()const{return -1;} ///<取得流长度
|
||||
int64 Available ()const{return rb?rb->GetWriteSize():-1;} ///<剩下的可以不受阻塞写入的字节数
|
||||
};//class RingOutputStream
|
||||
}//namespace io
|
||||
|
||||
class RingBufferRead
|
||||
{
|
||||
RingBuffer<char> *rb;
|
||||
int size;
|
||||
|
||||
public:
|
||||
|
||||
RingBufferRead(RingBuffer<char> *_rb)
|
||||
{
|
||||
rb=_rb;
|
||||
|
||||
size=rb->ReadStart();
|
||||
}
|
||||
|
||||
RingBufferRead(io::RingInputStream *ris)
|
||||
{
|
||||
rb=ris->GetRingBuffer();
|
||||
|
||||
size=rb->ReadStart();
|
||||
}
|
||||
|
||||
~RingBufferRead()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if(size>0)
|
||||
{
|
||||
rb->ReadEnd();
|
||||
size=0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};//class RingBufferRead
|
||||
|
||||
class RingBufferSafeRead
|
||||
{
|
||||
RingBuffer<char> *rb;
|
||||
int size;
|
||||
|
||||
public:
|
||||
|
||||
RingBufferSafeRead(RingBuffer<char> *_rb)
|
||||
{
|
||||
rb=_rb;
|
||||
size=-1;
|
||||
}
|
||||
|
||||
RingBufferSafeRead(io::RingInputStream *ris)
|
||||
{
|
||||
rb=ris->GetRingBuffer();
|
||||
size=-1;
|
||||
}
|
||||
|
||||
int Start()
|
||||
{
|
||||
size=rb->SafeReadStart();
|
||||
return size;
|
||||
}
|
||||
|
||||
int TryStart()
|
||||
{
|
||||
size=rb->SafeTryReadStart();
|
||||
return size;
|
||||
}
|
||||
|
||||
int GetSize()
|
||||
{
|
||||
size=rb->GetReadSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
~RingBufferSafeRead()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if(size>0)
|
||||
{
|
||||
rb->SafeReadEnd();
|
||||
size=0;
|
||||
}
|
||||
}
|
||||
};//class RingBufferSafeRead
|
||||
|
||||
class RingBufferWrite
|
||||
{
|
||||
RingBuffer<char> *rb;
|
||||
int size;
|
||||
|
||||
public:
|
||||
|
||||
RingBufferWrite(RingBuffer<char> *_rb)
|
||||
{
|
||||
rb=_rb;
|
||||
|
||||
size=rb->WriteStart();
|
||||
}
|
||||
|
||||
RingBufferWrite(io::RingOutputStream *ros)
|
||||
{
|
||||
rb=ros->GetRingBuffer();
|
||||
|
||||
size=rb->WriteStart();
|
||||
}
|
||||
|
||||
~RingBufferWrite()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if(size>0)
|
||||
{
|
||||
rb->WriteEnd();
|
||||
size=0;
|
||||
}
|
||||
}
|
||||
|
||||
int GetSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
};//class RingBufferWrite
|
||||
|
||||
class RingBufferSafeWrite
|
||||
{
|
||||
RingBuffer<char> *rb;
|
||||
int size;
|
||||
|
||||
public:
|
||||
|
||||
RingBufferSafeWrite(RingBuffer<char> *_rb)
|
||||
{
|
||||
rb=_rb;
|
||||
|
||||
size=-1;
|
||||
}
|
||||
|
||||
RingBufferSafeWrite(io::RingOutputStream *ros)
|
||||
{
|
||||
rb=ros->GetRingBuffer();
|
||||
}
|
||||
|
||||
int Start()
|
||||
{
|
||||
size=rb->SafeWriteStart();
|
||||
return(size);
|
||||
}
|
||||
|
||||
int TryStart()
|
||||
{
|
||||
size=rb->SafeTryWriteStart();
|
||||
return(size);
|
||||
}
|
||||
|
||||
~RingBufferSafeWrite()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
int Unlock()
|
||||
{
|
||||
int result=size;
|
||||
|
||||
if(size>0)
|
||||
{
|
||||
rb->SafeWriteEnd();
|
||||
size=0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};//class RingBufferSafeWrite
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_RING_BUFFER_INCLUDE
|
210
inc/hgl/thread/RingBufferRead.cpp
Normal file
210
inc/hgl/thread/RingBufferRead.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
#ifndef HGL_THREAD_RING_BUFFER_READ_SOURCE
|
||||
#define HGL_THREAD_RING_BUFFER_READ_SOURCE
|
||||
#include<string.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 安全取得可读取数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeGetReadSize()
|
||||
{
|
||||
Lock();
|
||||
|
||||
const int result=_GetReadSize();
|
||||
|
||||
Unlock();
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全尝试取得可读取数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
bool RingBuffer<T>::SafeTryGetReadSize(int &result)
|
||||
{
|
||||
if(!TryLock())
|
||||
return(false);
|
||||
|
||||
result=_GetReadSize();
|
||||
|
||||
Unlock();
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int RingBuffer<T>::ReadStart(bool peek)
|
||||
{
|
||||
ClampPosition();
|
||||
|
||||
write_off=write_pos%buffer_size;
|
||||
|
||||
read_max=_GetReadSize();
|
||||
|
||||
read_peek=peek; //标记是否真的取走
|
||||
read_count=0;
|
||||
read_cur=read_pos;
|
||||
|
||||
return(read_max);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int RingBuffer<T>::_SafeReadStart(bool peek)
|
||||
{
|
||||
ReadStart(peek);
|
||||
|
||||
if(read_max<=0)
|
||||
Unlock();
|
||||
|
||||
return(read_max);
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试开始读取数据,如失败或没有数据会立即解锁,不必再次调用SafeReadEnd
|
||||
* @param peek 是否真的取出数据
|
||||
* @return >0 可供读取的数据数量
|
||||
* @return =0 没有可供读取的数据
|
||||
* @return <0 暂时不能读取
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeTryReadStart(bool peek)
|
||||
{
|
||||
if(!TryLock())
|
||||
return(-1);
|
||||
|
||||
return _SafeReadStart(peek);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始读取数据,如果没有数据会立即关闭缓冲区,不必再次调用SafeReadEnd
|
||||
* @param peek 是否真的取出数据
|
||||
* @return 可供读取的数据数量
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeReadStart(bool peek)
|
||||
{
|
||||
Lock();
|
||||
|
||||
return _SafeReadStart(peek);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取数据
|
||||
* @param data 欲将访问数据存放的内存地址,可为NULL用于单纯后移读取指针
|
||||
* @param size 欲访问的数据长度
|
||||
* @param peek 是否后移访问指针(默认为真,仅针对当前这一次)
|
||||
* @return 实际可访问的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::Read(T *data,int size,bool peek)
|
||||
{
|
||||
if(size<=0)return(-1);
|
||||
|
||||
const int result=_Read(data,size,peek);
|
||||
|
||||
if(peek)
|
||||
read_count+=result;
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取结束
|
||||
* @return 返回读取的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::ReadEnd()
|
||||
{
|
||||
const int result=read_count;
|
||||
|
||||
if(read_peek&&result)
|
||||
read_pos=read_cur;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全读取结束
|
||||
* @return 返回读取的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeReadEnd()
|
||||
{
|
||||
const int result=ReadEnd();
|
||||
|
||||
Unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的读取数据,,此函数会直接开锁解锁,用于少量的一次性处理。如大量的数据要分次读取,请使用SafeReadStart/SafeReadEnd
|
||||
* @param data 欲将访问数据存放的内存地址,可为NULL用于单纯后移读取指针
|
||||
* @param size 欲访问的数据长度
|
||||
* @param peek 是否真的取出数据
|
||||
* @return 实际读取的数据长度
|
||||
* @return -1 出错
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeRead(T *data,int size,bool peek)
|
||||
{
|
||||
if(size<0)return(-1);
|
||||
if(size&&!data)return(-1);
|
||||
|
||||
if(SafeReadStart(peek)<=0)
|
||||
return(-1);
|
||||
|
||||
Read(data,size,peek);
|
||||
|
||||
return SafeReadEnd();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int RingBuffer<T>::_Read(T *data,int size,bool peek)
|
||||
{
|
||||
if(size<=0||read_max<=0)return(0);
|
||||
|
||||
if(size>read_max)
|
||||
size=read_max;
|
||||
|
||||
if(size>0)
|
||||
{
|
||||
if(data) //data可以为空,用于先尝试取数据后直接移走
|
||||
{
|
||||
const int temp_read =read_cur %buffer_size;
|
||||
|
||||
if(temp_read<write_off)
|
||||
{
|
||||
memcpy(data,buffer+temp_read,size*sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
int temp=buffer_size-temp_read;
|
||||
|
||||
if(size>temp)
|
||||
{
|
||||
memcpy(data,buffer+temp_read,temp*sizeof(T));
|
||||
|
||||
memcpy((char *)(data+temp),buffer,(size-temp)*sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(data,buffer+temp_read,size*sizeof(T));
|
||||
}
|
||||
}
|
||||
}//if(data)
|
||||
|
||||
if(peek)
|
||||
{
|
||||
read_cur+=size;
|
||||
read_max-=size;
|
||||
}
|
||||
}
|
||||
|
||||
return(size);
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_RING_BUFFER_READ_SOURCE
|
181
inc/hgl/thread/RingBufferWrite.cpp
Normal file
181
inc/hgl/thread/RingBufferWrite.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
#ifndef HGL_THREAD_RING_BUFFER_WRITE_SOURCE
|
||||
#define HGL_THREAD_RING_BUFFER_WRITE_SOURCE
|
||||
#include<string.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 安全取得可写入数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeGetWriteSize()
|
||||
{
|
||||
Lock();
|
||||
|
||||
const int result=_GetWriteSize();
|
||||
|
||||
Unlock();
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int RingBuffer<T>::WriteStart()
|
||||
{
|
||||
ClampPosition();
|
||||
|
||||
read_off=read_pos%buffer_size;
|
||||
|
||||
write_max=_GetWriteSize();
|
||||
|
||||
write_count=0;
|
||||
write_cur=write_pos;
|
||||
|
||||
return write_max;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int RingBuffer<T>::_SafeWriteStart()
|
||||
{
|
||||
WriteStart();
|
||||
|
||||
if(write_max<=0)
|
||||
Unlock();
|
||||
|
||||
return write_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试开始写入
|
||||
* @return >0 成功开始,可写入的数据长度
|
||||
* @return =0 没有可以写入的空间
|
||||
* @return <0 暂时不可写入
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeTryWriteStart()
|
||||
{
|
||||
if(!TryLock())
|
||||
return(-1);
|
||||
|
||||
return _SafeWriteStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始写入数据,如果没有空间会立即关闭缓冲区,不必再次调用SafeWriteEnd
|
||||
* @return 可写入的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeWriteStart()
|
||||
{
|
||||
Lock();
|
||||
|
||||
return _SafeWriteStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束写入数据
|
||||
* @param data 要写入的数据
|
||||
* @param size 要写入的数据长度
|
||||
* @return 实际写入的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::Write(const T *data,int size)
|
||||
{
|
||||
if(!data||size<=0)return(-1);
|
||||
|
||||
const int result=_Write(data,size);
|
||||
|
||||
write_count+=result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入结束
|
||||
* @return 返回写入的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::WriteEnd()
|
||||
{
|
||||
const int result=write_count;
|
||||
|
||||
if(result)
|
||||
write_pos=write_cur;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全写入结束
|
||||
* @return 返回写入的数据长度
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeWriteEnd()
|
||||
{
|
||||
const int result=WriteEnd();
|
||||
|
||||
Unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全写入数据,此函数会直接开锁解锁,用于少量的一次性处理。如大量的数据要分次写入,请使用SafeWriteStart/SafeWriteEnd
|
||||
* @param data 要写入的数据
|
||||
* @param size 要写入的数据长度
|
||||
* @return 实际写入的数据长度
|
||||
* @return -1 出错
|
||||
*/
|
||||
template<typename T>
|
||||
int RingBuffer<T>::SafeWrite(const T *data,int size)
|
||||
{
|
||||
if(!data||size<=0)return(-1);
|
||||
|
||||
if(SafeWriteStart()<=0)
|
||||
return(-1);
|
||||
|
||||
Write(data,size);
|
||||
|
||||
return SafeWriteEnd();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int RingBuffer<T>::_Write(const T *data,int size)
|
||||
{
|
||||
if(size<=0||write_max<=0)return(0);
|
||||
|
||||
if(size>write_max)
|
||||
size=write_max;
|
||||
|
||||
if(size>0)
|
||||
{
|
||||
const int temp_write=write_cur%buffer_size;
|
||||
|
||||
if(read_off<=temp_write)
|
||||
{
|
||||
int temp=buffer_size-temp_write;
|
||||
|
||||
if(size>temp)
|
||||
{
|
||||
memcpy(buffer+temp_write,data,temp*sizeof(T));
|
||||
|
||||
memcpy(buffer,(char *)(data+temp),(size-temp)*sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buffer+temp_write,data,size*sizeof(T));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buffer+temp_write,data,size*sizeof(T));
|
||||
}
|
||||
|
||||
write_cur+=size;
|
||||
write_max-=size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_RING_BUFFER_WRITE_SOURCE
|
233
inc/hgl/thread/SemLock.h
Normal file
233
inc/hgl/thread/SemLock.h
Normal file
@ -0,0 +1,233 @@
|
||||
#ifndef HGL_THREAD_SEM_LOCK_INCLUDE
|
||||
#define HGL_THREAD_SEM_LOCK_INCLUDE
|
||||
|
||||
#include<hgl/thread/Semaphore.h>
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/thread/RWLock.h>
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T,typename L> class SemLockTemplate
|
||||
{
|
||||
protected:
|
||||
|
||||
T data;
|
||||
|
||||
L lock;
|
||||
Semaphore sem;
|
||||
|
||||
public:
|
||||
|
||||
SemLockTemplate(){}
|
||||
|
||||
/**
|
||||
* 本类构造函数
|
||||
* @param d 数据
|
||||
* @param sem_count 最大信号数量(默认0表示不限制)
|
||||
*/
|
||||
SemLockTemplate(T &d,int sem_count=0):sem(sem_count)
|
||||
{
|
||||
data=d;
|
||||
}
|
||||
|
||||
public: //数据相关
|
||||
|
||||
void operator = (T &d){data=d;}
|
||||
T *operator->(){return &data;}
|
||||
|
||||
public: //信号相关
|
||||
|
||||
/**
|
||||
* 释放信号
|
||||
* @param n 释放的信号数量
|
||||
* @return 是否成功
|
||||
*/
|
||||
bool Post(int n=1)
|
||||
{
|
||||
if(n<=0)return(false);
|
||||
return sem.Post(n);
|
||||
}
|
||||
|
||||
bool TryAcquire(){return sem.TryAcquire();} ///<尝试获取一个信号
|
||||
/**
|
||||
* 获取一个信号
|
||||
* @param time_out 超时时间
|
||||
* @return 是否成功
|
||||
*/
|
||||
bool Acquire(double time_out=0.0f){return sem.Acquire();}
|
||||
};//template<typename T,typename L> class SemLockTemplate
|
||||
|
||||
/**
|
||||
* 信号线程排斥
|
||||
*/
|
||||
template<typename T> class SemThreadMutex:public SemLockTemplate<T,ThreadMutex>
|
||||
{
|
||||
public:
|
||||
|
||||
using SemLockTemplate<T,ThreadMutex>::SemLockTemplate;
|
||||
|
||||
public: //线程排斥相关
|
||||
|
||||
void Lock(){this->lock.Lock();} ///<取得的控制权(如果对象处于排斥状态,则等待)
|
||||
bool TryLock(){return this->lock.TryLock();} ///<尝试取得控制权
|
||||
bool WaitLock(double time_out=0){return this->lock.WaitLock();} ///<等待并取得控制权
|
||||
void Unlock(){this->lock.Unlock();} ///<放弃控制权
|
||||
|
||||
public: //综合应用相关
|
||||
|
||||
/**
|
||||
* 在指定时间内如果成功捕获到信号则锁定
|
||||
* @param time_out 最长等待时间
|
||||
* @return 是否锁定了
|
||||
*/
|
||||
bool WaitSemLock(double time_out)
|
||||
{
|
||||
if(!this->sem.Acquire(time_out))
|
||||
return(false);
|
||||
|
||||
this->lock.Lock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试捕获一个信号,如果成功则锁定
|
||||
* @return 是否锁定了
|
||||
*/
|
||||
bool TrySemLock()
|
||||
{
|
||||
if(!this->sem.TryAcquire())
|
||||
return(false);
|
||||
|
||||
this->lock.Lock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁定
|
||||
* @param try_lock 是否是尝试锁定
|
||||
* @param time_out 如果不是尝试锁定,则等待锁定的超时时间
|
||||
*/
|
||||
bool SemLock(bool try_lock,double time_out)
|
||||
{
|
||||
if(try_lock)
|
||||
{
|
||||
if(!this->sem.TryAcquire())
|
||||
return(false);
|
||||
}
|
||||
else //当前没人,那就慢慢等吧
|
||||
{
|
||||
if(!this->sem.Acquire(time_out))
|
||||
return(false);
|
||||
}
|
||||
|
||||
this->lock.Lock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解锁并释放信号
|
||||
* @param n 释放的信号数量
|
||||
*/
|
||||
void SemUnlock(int n=1)
|
||||
{
|
||||
this->lock.Unlock();
|
||||
|
||||
if(n>0)
|
||||
this->sem.Post(n);
|
||||
}
|
||||
};//template<typename T> class SemThreadMutex
|
||||
|
||||
/**
|
||||
* 信号读写锁
|
||||
*/
|
||||
template<typename T> class SemRWLock:public SemLockTemplate<T,RWLock>
|
||||
{
|
||||
public:
|
||||
|
||||
using SemLockTemplate<T,RWLock>::SemLockTemplate;
|
||||
|
||||
public: //读写锁相关
|
||||
|
||||
HGL_RWLOCK(this->lock);
|
||||
|
||||
public: //综合应用相关
|
||||
|
||||
/**
|
||||
* 在指定时间内如果成功捕获到信号则共享锁定
|
||||
* @param time_out 最长等待时间
|
||||
* @return 是否锁定了
|
||||
*/
|
||||
bool WaitSemReadLock(double time_out)
|
||||
{
|
||||
if(!this->sem.Acquire(time_out))
|
||||
return(false);
|
||||
|
||||
this->lock.ReadLock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在指定时间内如果成功捕获到信号则独占锁定
|
||||
* @param time_out 最长等待时间
|
||||
* @return 是否锁定了
|
||||
*/
|
||||
bool WaitSemWriteLock(double time_out)
|
||||
{
|
||||
if(!this->sem.Acquire(time_out))
|
||||
return(false);
|
||||
|
||||
this->lock.WriteLock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试捕获一个信号,如果成功则共享锁定
|
||||
* @return 是否锁定了
|
||||
*/
|
||||
bool TrySemReadLock()
|
||||
{
|
||||
if(!this->sem.TryAcquire())
|
||||
return(false);
|
||||
|
||||
this->lock.ReadLock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试捕获一个信号,如果成功则独占锁定
|
||||
* @return 是否锁定了
|
||||
*/
|
||||
bool TrySemWriteLock()
|
||||
{
|
||||
if(!this->sem.TryAcquire())
|
||||
return(false);
|
||||
|
||||
this->lock.WriteLock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除共享锁并释放信号
|
||||
* @param n 释放的信号数量
|
||||
*/
|
||||
void SemReadUnlock(int n=1)
|
||||
{
|
||||
this->lock.ReadUnlock();
|
||||
|
||||
if(n>0)
|
||||
this->sem.Post(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解除独占锁并释放信号
|
||||
* @param n 释放的信号数量
|
||||
*/
|
||||
void SemWriteUnlock(int n=1)
|
||||
{
|
||||
this->lock.WriteUnlock();
|
||||
|
||||
if(n>0)
|
||||
this->sem.Post(n);
|
||||
}
|
||||
};//template<typename T> class SemRWLock
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_SEM_LOCK_INCLUDE
|
33
inc/hgl/thread/Semaphore.h
Normal file
33
inc/hgl/thread/Semaphore.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef HGL_SEMAPHORE_INCLUDE
|
||||
#define HGL_SEMAPHORE_INCLUDE
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include<dispatch/dispatch.h>
|
||||
#endif//__APPLE__
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 信号是用于多线程同步中常用的一种技术<br>
|
||||
* 注意信号的用法是要有信号被发送出来,才能获取到信号。
|
||||
*/
|
||||
class Semaphore ///信号
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
dispatch_semaphore_t ptr;
|
||||
#else
|
||||
void *ptr;
|
||||
#endif//__APPLE__
|
||||
|
||||
public:
|
||||
|
||||
Semaphore(int=1024);
|
||||
virtual ~Semaphore();
|
||||
|
||||
virtual bool Post(int n=1); ///<发送信号
|
||||
|
||||
virtual bool TryAcquire(); ///<尝试取得一个信号
|
||||
virtual bool Acquire(double time=0.0); ///<等待并获取一个信号
|
||||
};//class Semaphore
|
||||
}//namespace hgl
|
||||
#endif//HGL_SEMAPHORE_INCLUDE
|
156
inc/hgl/thread/SwapColl.h
Normal file
156
inc/hgl/thread/SwapColl.h
Normal file
@ -0,0 +1,156 @@
|
||||
#ifndef HGL_THREAD_SWAP_LIST_INCLUDE
|
||||
#define HGL_THREAD_SWAP_LIST_INCLUDE
|
||||
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/thread/Semaphore.h>
|
||||
#include<hgl/type/List.h>
|
||||
#include<hgl/type/Set.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 数据交换合集
|
||||
*/
|
||||
template<typename T,template<typename> class S> class SwapColl
|
||||
{
|
||||
protected:
|
||||
|
||||
S<T> join_list;
|
||||
S<T> proc_list;
|
||||
|
||||
ThreadMutex lock;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~SwapColl(){}
|
||||
|
||||
/**
|
||||
* 加入一个数据到合集中
|
||||
*/
|
||||
bool Add(T &item)
|
||||
{
|
||||
lock.Lock();
|
||||
int result=join_list.Add(item);
|
||||
lock.Unlock();
|
||||
|
||||
return(result!=-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加一批数据到合集中
|
||||
*/
|
||||
int Add(T *item_list,const int count)
|
||||
{
|
||||
lock.Lock();
|
||||
int result=join_list.Add(item_list,count);
|
||||
lock.Unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得可以使用的列表
|
||||
*/
|
||||
S<T> &GetProcList()
|
||||
{
|
||||
lock.Lock();
|
||||
proc_list.Add(join_list);
|
||||
join_list.ClearData();
|
||||
lock.Unlock();
|
||||
|
||||
return proc_list;
|
||||
}
|
||||
|
||||
S<T> *operator ->(){return &proc_list;}
|
||||
operator S<T> &(){return proc_list;}
|
||||
};//template<typename T> class SwapColl
|
||||
|
||||
template<typename T> using SwapList=SwapColl<T,List>; ///<安全交换列表
|
||||
template<typename T> using SwapSet=SwapColl<T,Set>; ///<安全交换集合
|
||||
|
||||
/**
|
||||
* 信号安全交换合集
|
||||
*/
|
||||
template<typename T,template<typename> class S> class SemSwapColl
|
||||
{
|
||||
protected:
|
||||
|
||||
S<T> join_list;
|
||||
S<T> proc_list;
|
||||
|
||||
ThreadMutex lock;
|
||||
Semaphore sem;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~SemSwapColl()=default;
|
||||
|
||||
/**
|
||||
* 增加一个数据到合集中
|
||||
*/
|
||||
bool Add(T &item)
|
||||
{
|
||||
lock.Lock();
|
||||
int result=join_list.Add(item);
|
||||
lock.Unlock();
|
||||
|
||||
if(result!=-1)
|
||||
sem.Post(1);
|
||||
|
||||
return(result!=-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加一批数据到合集中
|
||||
*/
|
||||
int Add(T *item_list,const int count)
|
||||
{
|
||||
lock.Lock();
|
||||
int result=join_list.Add(item_list,count);
|
||||
lock.Unlock();
|
||||
|
||||
if(result>0)
|
||||
sem.Post(1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待信号
|
||||
*/
|
||||
bool WaitProc(const double time_out=HGL_TIME_ONE_MINUTE)
|
||||
{
|
||||
if(!sem.Acquire(time_out))
|
||||
return(false);
|
||||
|
||||
lock.Lock();
|
||||
proc_list.Add(join_list);
|
||||
join_list.ClearData();
|
||||
lock.Unlock();
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待信号
|
||||
*/
|
||||
bool TryProc()
|
||||
{
|
||||
if(!sem.TryAcquire())
|
||||
return(false);
|
||||
|
||||
lock.Lock();
|
||||
proc_list.Add(join_list);
|
||||
join_list.ClearData();
|
||||
lock.Unlock();
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
S<T> *operator ->(){return &proc_list;}
|
||||
operator S<T> &(){return proc_list;}
|
||||
};//template<typename T> class SemSwapColl
|
||||
|
||||
template<typename T> using SemSwapList=SemSwapColl<T,List>; ///<安全信号交换列表
|
||||
template<typename T> using SemSwapSet=SemSwapColl<T,Set>; ///<安全信号交换集合
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_SWAP_LIST_INCLUDE
|
240
inc/hgl/thread/SwapData.h
Normal file
240
inc/hgl/thread/SwapData.h
Normal file
@ -0,0 +1,240 @@
|
||||
#ifndef HGL_THREAD_SWAP_DATA_INCLUDE
|
||||
#define HGL_THREAD_SWAP_DATA_INCLUDE
|
||||
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/thread/Semaphore.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 单向多线程数据交换模板<br>
|
||||
* 适用环境为多个线程向其投递数据,一个线程接收数据。接收方在每次处理前交换数据指针,以达到最小线程切换代价
|
||||
*/
|
||||
template<typename T> class SwapData
|
||||
{
|
||||
protected:
|
||||
|
||||
T data[2];
|
||||
|
||||
int post_index;
|
||||
int recv_index;
|
||||
|
||||
ThreadMutex lock;
|
||||
|
||||
protected:
|
||||
|
||||
void _Swap()
|
||||
{
|
||||
if(recv_index){recv_index=0;post_index=1;}
|
||||
else{recv_index=1;post_index=0;}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
SwapData()
|
||||
{
|
||||
recv_index=0;
|
||||
post_index=1;
|
||||
}
|
||||
|
||||
virtual ~SwapData()=default;
|
||||
|
||||
/**
|
||||
* 获取投递方数据访问权
|
||||
*/
|
||||
T &GetPost()
|
||||
{
|
||||
lock.Lock();
|
||||
|
||||
return data[post_index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放多线程投递方数据访问权
|
||||
*/
|
||||
void ReleasePost()
|
||||
{
|
||||
lock.Unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得接收方数据访问权
|
||||
*/
|
||||
T &GetReceive(){return data[recv_index];}
|
||||
|
||||
/**
|
||||
* 交换双方数据
|
||||
*/
|
||||
void Swap()
|
||||
{
|
||||
lock.Lock();
|
||||
|
||||
this->_Swap();
|
||||
|
||||
lock.Unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试交换双方数据
|
||||
*/
|
||||
bool TrySwap()
|
||||
{
|
||||
if(!lock.TryLock())
|
||||
return(false);
|
||||
|
||||
this->_Swap();
|
||||
|
||||
lock.Unlock();
|
||||
return(true);
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
/**
|
||||
* 尝试交换双方数据
|
||||
*/
|
||||
bool WaitSwap(const double time_out)
|
||||
{
|
||||
if(!lock.WaitLock(time_out))
|
||||
return(false);
|
||||
|
||||
this->_Swap();
|
||||
|
||||
lock.Unlock();
|
||||
return(true);
|
||||
}
|
||||
#endif//__APPLE__
|
||||
};//template<typename T> class SwapData
|
||||
|
||||
/**
|
||||
* 信号自动交换数据访问模板
|
||||
*/
|
||||
template<typename T> class SemSwapData:public SwapData<T>
|
||||
{
|
||||
Semaphore sem;
|
||||
|
||||
public:
|
||||
|
||||
using SwapData<T>::SwapData;
|
||||
~SemSwapData()=default;
|
||||
|
||||
/**
|
||||
* 释放接收信号
|
||||
* @param count 信号个数
|
||||
*/
|
||||
void PostSem(int count=1)
|
||||
{
|
||||
sem.Post(count);
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待获取一个信号并交换前后台数据
|
||||
* @param time_out 等待时长
|
||||
*/
|
||||
bool WaitSemSwap(const double time_out=5)
|
||||
{
|
||||
if(!sem.Acquire(time_out))
|
||||
return(false);
|
||||
|
||||
this->Swap();
|
||||
return(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试获取一个信号并交换前后台数据
|
||||
*/
|
||||
bool TrySemSwap()
|
||||
{
|
||||
if(!sem.TryAcquire())
|
||||
return(false);
|
||||
|
||||
this->Swap();
|
||||
return(true);
|
||||
}
|
||||
};//template<typename T> class SemSwapData:public SwapData<T>
|
||||
|
||||
/**
|
||||
* SwapData模板自动释放Post工具模板
|
||||
*/
|
||||
template<typename T> class PostToSwapData
|
||||
{
|
||||
SwapData<T> *swap_data;
|
||||
T *post;
|
||||
|
||||
public:
|
||||
|
||||
PostToSwapData(SwapData<T> *sd)
|
||||
{
|
||||
swap_data=sd;
|
||||
|
||||
if(swap_data)
|
||||
post=&(swap_data->GetPost());
|
||||
else
|
||||
post=nullptr;
|
||||
}
|
||||
|
||||
~PostToSwapData()
|
||||
{
|
||||
if(swap_data)
|
||||
swap_data->ReleasePost();
|
||||
}
|
||||
|
||||
T *operator ->(){return post;}
|
||||
};//template<typename T> class PostToSwapData
|
||||
|
||||
/**
|
||||
* SemSwapData模板自动释放Post工具模板
|
||||
*/
|
||||
template<typename T> class PostToSemSwapData
|
||||
{
|
||||
SemSwapData<T> *swap_data;
|
||||
T *post;
|
||||
|
||||
public:
|
||||
|
||||
PostToSemSwapData(SemSwapData<T> *sd)
|
||||
{
|
||||
swap_data=sd;
|
||||
|
||||
if(swap_data)
|
||||
post=&(swap_data->GetPost());
|
||||
else
|
||||
post=nullptr;
|
||||
}
|
||||
|
||||
~PostToSemSwapData()
|
||||
{
|
||||
if(swap_data)
|
||||
{
|
||||
swap_data->ReleasePost();
|
||||
swap_data->PostSem();
|
||||
}
|
||||
}
|
||||
|
||||
T *operator ->(){return post;}
|
||||
};//template<typename T> class PostToSemSwapData
|
||||
|
||||
/**
|
||||
* 使用范例
|
||||
*
|
||||
* using EventQueue=Queue<int>;
|
||||
* using MTEventQueue=SemSwapData<EventQueue>;
|
||||
* using MTEventPost=PostToSemSwapData<EventQueue>;
|
||||
*
|
||||
* MTEventQueue mt_event_queue;
|
||||
*
|
||||
* 新方式:
|
||||
* MTEventPost post(mt_event_queue);
|
||||
*
|
||||
* post.Push(1);
|
||||
*
|
||||
* 直接模式:
|
||||
* EventQueue &eq=mt_event_queue.GetPost();
|
||||
*
|
||||
* eq->Push(1);
|
||||
*
|
||||
* mt_event_queue.ReleasePost();
|
||||
* mt_event_queue.PostSem();
|
||||
*
|
||||
*/
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_SWAP_DATA_INCLUDE
|
230
inc/hgl/thread/Thread.h
Normal file
230
inc/hgl/thread/Thread.h
Normal file
@ -0,0 +1,230 @@
|
||||
#ifndef HGL_THREAD_INCLUDE
|
||||
#define HGL_THREAD_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/type/Set.h>
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/LogInfo.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
void WaitThreadExit(thread_ptr tp,const double &time_out);
|
||||
|
||||
/**
|
||||
* 线程类.本类用于建立一个线程并管理它。<br>
|
||||
* Sleep和Exit函数是给线程内的程序使用的;而Start,Close,Pause,Rewind是给线程外的程序使用的。<br>
|
||||
* 使用本类只需要重载本类,并将代码写在Execute函数内即可。<br>
|
||||
* 执行大概为:<br>
|
||||
* if(ProcStartThread()) <br>
|
||||
* while(Execute()); <br>
|
||||
* else <br>
|
||||
* return(0);
|
||||
* <br>
|
||||
* ProcEndThread();
|
||||
*/
|
||||
class Thread ///线程类
|
||||
{
|
||||
friend void WaitThread(Thread **,int,double);
|
||||
|
||||
private:
|
||||
|
||||
thread_ptr tp=0;
|
||||
|
||||
ThreadMutex live_lock;
|
||||
ThreadMutex exit_lock;
|
||||
|
||||
friend THREAD_FUNC ThreadFunc(Thread *tc);
|
||||
|
||||
#ifdef _DEBUG
|
||||
UTF8String thread_addr_string; ///<线程地址用字符串,调试使用
|
||||
#endif//_DEBUG
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Thread()=default;
|
||||
|
||||
#ifdef _DEBUG
|
||||
const UTF8String &GetThreadAddressString()const{return thread_addr_string;} ///<取得线程地址字符串
|
||||
#endif//_DEBUG
|
||||
|
||||
/**
|
||||
* 线程执行函数,会被反复调用
|
||||
* @return true 继续执行
|
||||
* @return false 退出执行
|
||||
*/
|
||||
virtual bool Execute()=0; ///<线程的运行函数
|
||||
|
||||
virtual bool ProcStartThread() ///<线程启动运行函数,在Execute前被调用
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
char thread_addr[(sizeof(thread_ptr)<<1)+1];
|
||||
|
||||
DataToUpperHexStr(thread_addr,(uint8 *)&tp,sizeof(thread_ptr));
|
||||
|
||||
thread_addr_string=thread_addr;
|
||||
#endif//_DEBUG
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual void ProcEndThread(){} ///<结程结束运行函数,在Execute后被调用
|
||||
|
||||
virtual bool IsExitDelete()const{return true;} ///<返回在退出线程时,是否删除本对象(注:此函数不可动态变动值)
|
||||
|
||||
bool IsLive() ///<当前线程是否还活着
|
||||
{
|
||||
if(live_lock.TryLock())
|
||||
{
|
||||
//成功了,证明这个线程已经关闭了
|
||||
live_lock.Unlock();
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
public: //线程运行控制
|
||||
|
||||
virtual bool Start(); ///<开始运行当前线程
|
||||
|
||||
virtual bool IsCurThread(); ///<是否是当前线程
|
||||
|
||||
virtual void Exit() ///<退出当前线程(其它线程调用)
|
||||
{
|
||||
exit_lock.Unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* (线程外部调用)退出当前线程,并等待其完成退出<br>
|
||||
* @param time_out 等待的时间,如果为0表示等到线程运行结束为止。默认为0
|
||||
*/
|
||||
virtual void WaitExit(const double &time_out=0)
|
||||
{
|
||||
if(!tp)
|
||||
return;
|
||||
|
||||
thread_ptr self_tp=tp;
|
||||
|
||||
Exit();
|
||||
|
||||
WaitThreadExit(self_tp,time_out);
|
||||
}
|
||||
};//class Thread
|
||||
|
||||
void WaitThread(Thread **,int,double time=0); ///<等待多个线程中的一个完成
|
||||
|
||||
bool CreateThread(Thread *); ///<创建一个线程
|
||||
|
||||
/**
|
||||
* 简单的多线程管理
|
||||
*/
|
||||
template<typename THREAD> class MultiThreadManage
|
||||
{
|
||||
protected:
|
||||
|
||||
Set<THREAD *> thread_set;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~MultiThreadManage()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
THREAD *GetThread(int index)
|
||||
{
|
||||
THREAD *result;
|
||||
|
||||
if(thread_set.Get(index,result))
|
||||
return result;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加一个线程到合集中
|
||||
* @return 是否增加成功
|
||||
*/
|
||||
bool Add(THREAD *p)
|
||||
{
|
||||
if(!p)return(false);
|
||||
|
||||
return(thread_set.Add(p)!=-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个线程
|
||||
*/
|
||||
void Delete(THREAD *p)
|
||||
{
|
||||
if(!p)return;
|
||||
|
||||
thread_set.Delete(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭所有线程
|
||||
*/
|
||||
void Close()
|
||||
{
|
||||
const int count=thread_set.GetCount();
|
||||
|
||||
THREAD **p=thread_set.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
(*p)->WaitExit();
|
||||
++p;
|
||||
}
|
||||
|
||||
thread_set.ClearData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动所有线程
|
||||
* @return 成功启动的线程数量
|
||||
*/
|
||||
int Start()
|
||||
{
|
||||
const int count=thread_set.GetCount();
|
||||
|
||||
THREAD **p=thread_set.GetData();
|
||||
|
||||
int total=0;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if((*p)->Start())
|
||||
++total;
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查还有几个线程活着
|
||||
*/
|
||||
int IsLive()
|
||||
{
|
||||
const int count=thread_set.GetCount();
|
||||
|
||||
THREAD **p=thread_set.GetData();
|
||||
|
||||
int total=0;
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
if((*p)->IsLive())
|
||||
++total;
|
||||
|
||||
++p;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
};//class MultiThreadManage
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_INCLUDE
|
163
inc/hgl/thread/ThreadMutex.h
Normal file
163
inc/hgl/thread/ThreadMutex.h
Normal file
@ -0,0 +1,163 @@
|
||||
#ifndef HGL_THREAD_MUTEX_INCLUDE
|
||||
#define HGL_THREAD_MUTEX_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h>
|
||||
#include<hgl/Macro.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 排斥(线程)访问类可以判断数据在被一个代码段访问时,不能被另一代码段访问<br>
|
||||
* 注:此排斥仅在当前进程内有效
|
||||
*/
|
||||
class ThreadMutex ///排斥访问类(仅当前进程)
|
||||
{
|
||||
cm_thread_mutex ptr;
|
||||
|
||||
public:
|
||||
|
||||
ThreadMutex(); ///<本类构造函数
|
||||
virtual ~ThreadMutex(); ///<本类析构函数
|
||||
|
||||
cm_thread_mutex *GetThreadMutex(){return &ptr;}
|
||||
|
||||
virtual void Lock(); ///<取得的控制权(如果对象处于排斥状态,则等待)
|
||||
virtual bool TryLock(); ///<尝试取得控制权
|
||||
#if !defined(__APPLE__)&&!defined(__ANDROID__)
|
||||
virtual bool WaitLock(const double=0); ///<等待并取得控制权
|
||||
#endif//__APPLE__
|
||||
virtual void Unlock(); ///<放弃控制权
|
||||
};//class Mutex
|
||||
|
||||
/**
|
||||
* 线程排斥对象
|
||||
*/
|
||||
template<typename T> class ThreadMutexObject:public ThreadMutex
|
||||
{
|
||||
T *data;
|
||||
|
||||
public:
|
||||
|
||||
ThreadMutexObject()
|
||||
{
|
||||
data=new T;
|
||||
}
|
||||
|
||||
ThreadMutexObject(T *t)
|
||||
{
|
||||
data=t;
|
||||
}
|
||||
|
||||
virtual ~ThreadMutexObject()
|
||||
{
|
||||
SAFE_CLEAR(data);
|
||||
}
|
||||
|
||||
void operator = (T *t)
|
||||
{
|
||||
if(data)
|
||||
delete data;
|
||||
|
||||
data=t;
|
||||
}
|
||||
|
||||
T *operator ->()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
bool valid()const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
bool operator !()
|
||||
{
|
||||
return !data;
|
||||
}
|
||||
};//class ThreadMutexObject
|
||||
|
||||
/**
|
||||
* 线程排斥对像阵列
|
||||
*/
|
||||
template<typename T> class ThreadMutexObjectArray
|
||||
{
|
||||
protected:
|
||||
|
||||
ThreadMutexObject<T> *items;
|
||||
|
||||
public:
|
||||
|
||||
ThreadMutexObjectArray()
|
||||
{
|
||||
items=nullptr;
|
||||
}
|
||||
|
||||
ThreadMutexObjectArray(int count)
|
||||
{
|
||||
if(count<=0)
|
||||
{
|
||||
items=nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
items=new ThreadMutexObject<T>[count];
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~ThreadMutexObjectArray()
|
||||
{
|
||||
delete[] items; //delete nullptr不是个错误
|
||||
}
|
||||
|
||||
ThreadMutexObject<T> &operator [](int index)
|
||||
{
|
||||
return items[index];
|
||||
}
|
||||
};//class ThreadMutexObjectArray
|
||||
|
||||
/**
|
||||
* 智能自释放线程排斥锁
|
||||
*/
|
||||
class ThreadMutexLock
|
||||
{
|
||||
ThreadMutex *tm;
|
||||
|
||||
public:
|
||||
|
||||
ThreadMutexLock(ThreadMutex *tm_lock)
|
||||
{
|
||||
tm=tm_lock;
|
||||
|
||||
if(tm)
|
||||
tm->Lock();
|
||||
}
|
||||
|
||||
~ThreadMutexLock()
|
||||
{
|
||||
if(tm)
|
||||
tm->Unlock();
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
if(tm)
|
||||
tm->Lock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if(tm)
|
||||
tm->Unlock();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if(tm)
|
||||
{
|
||||
tm->Unlock();
|
||||
tm=nullptr;
|
||||
}
|
||||
}
|
||||
};//class ThreadMutexLock
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_MUTEX_INCLUDE
|
371
inc/hgl/thread/Workflow.h
Normal file
371
inc/hgl/thread/Workflow.h
Normal file
@ -0,0 +1,371 @@
|
||||
#ifndef HGL_WORKFLOW_INCLUDE
|
||||
#define HGL_WORKFLOW_INCLUDE
|
||||
|
||||
#include<hgl/thread/Thread.h>
|
||||
#include<hgl/thread/ThreadMutex.h>
|
||||
#include<hgl/thread/SwapData.h>
|
||||
#include<hgl/thread/DataPost.h>
|
||||
#include<hgl/type/List.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 工作流名字空间<br>
|
||||
* 工作流是一种对工作的多线安排管理机制,它适用于按业务分配多线程的工作环境<br>
|
||||
* 开发者需要为每一种工作指定一定的线程数量,但每一种工作确只有一个工作分配入口和分发出口。<br>
|
||||
* 由其它程序提交工作任务到入口,开发者可以自行重载分配入口的分配函数。
|
||||
*/
|
||||
namespace workflow
|
||||
{
|
||||
/**
|
||||
* 工作处理基类模板
|
||||
* @param W 工作对象
|
||||
*/
|
||||
template<typename W> class WorkProc
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~WorkProc()=default;
|
||||
|
||||
public: //投递工作线程所需调用的方法
|
||||
|
||||
virtual void Post(W *w)=0; ///<投递一个工作
|
||||
virtual void Post(W **w,int count)=0; ///<投递一批工作
|
||||
|
||||
public: //需用户重载实现的真正执行工作的方法
|
||||
|
||||
/**
|
||||
* 单个工作执行事件函数,此函数需用户重载实现
|
||||
*/
|
||||
virtual void OnWork(const uint,W *)=0;
|
||||
|
||||
public: //由工作线程调用的执行工作事件函数
|
||||
|
||||
/**
|
||||
* 工作执行处理函数
|
||||
*/
|
||||
virtual bool OnExecuteWork(const uint)=0;
|
||||
};//template<typename W> class WorkProc
|
||||
|
||||
/**
|
||||
* 单体工作处理<br>
|
||||
* 该类可以由多个线程投递工作,但只能被一个工作线程获取工作
|
||||
*/
|
||||
template<typename W> class SingleWorkProc:public WorkProc<W>
|
||||
{
|
||||
public:
|
||||
|
||||
using WorkList=List<W *>;
|
||||
|
||||
private:
|
||||
|
||||
SemSwapData<WorkList> work_list; ///<工程列表
|
||||
|
||||
protected:
|
||||
|
||||
double time_out;
|
||||
|
||||
public:
|
||||
|
||||
SingleWorkProc()
|
||||
{
|
||||
time_out=5;
|
||||
}
|
||||
|
||||
virtual ~SingleWorkProc()=default;
|
||||
|
||||
void SetTimeOut(const double to) ///<设置超时时间
|
||||
{
|
||||
if(to<=0)time_out=0;
|
||||
else time_out=to;
|
||||
}
|
||||
|
||||
virtual void Post(W *w) override ///<投递一个工作
|
||||
{
|
||||
WorkList &wl=work_list.GetPost();
|
||||
wl.Add(w);
|
||||
work_list.ReleasePost();
|
||||
}
|
||||
|
||||
virtual void Post(W **w,int count) override ///<投递一批工作
|
||||
{
|
||||
WorkList &wl=work_list.GetPost();
|
||||
wl.Add(w,count);
|
||||
work_list.ReleasePost();
|
||||
}
|
||||
|
||||
virtual void ToWork() ///<将堆积的工作列表发送给工作线程
|
||||
{
|
||||
work_list.PostSem(1);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* 当前工作序列完成事件函数,如需使用请重载此函数
|
||||
*/
|
||||
virtual void OnFinish(const uint wt_index)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始执行工作函数
|
||||
*/
|
||||
virtual bool OnExecuteWork(const uint wt_index) override
|
||||
{
|
||||
//为什么不使用TrySemSwap,使用TrySemSwap固然会立即返回结果,但会引起线程频繁刷新造成CPU的流费。
|
||||
//使用WaitSemSwap目前唯一坏处是在退出时,需要等待超时时间。
|
||||
|
||||
if(!work_list.WaitSemSwap(time_out))
|
||||
return(false);
|
||||
|
||||
WorkList &wl=work_list.GetReceive();
|
||||
|
||||
const int count=wl.GetCount();
|
||||
|
||||
if(count>0)
|
||||
{
|
||||
W **p=wl.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
this->OnWork(wt_index,*p);
|
||||
++p;
|
||||
}
|
||||
|
||||
this->OnFinish(wt_index);
|
||||
|
||||
wl.ClearData();
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
};//template<typename W> class SingleWorkProc:public WorkProc<W>
|
||||
|
||||
/**
|
||||
* 多体工作处理<br>
|
||||
* 该类可以由多个线程投递工作,也可以同时被多个工作线程获取工作
|
||||
*/
|
||||
template<typename W> class MultiWorkProc:public WorkProc<W>
|
||||
{
|
||||
protected:
|
||||
|
||||
SemDataPost<W> work_list; ///<工程列表
|
||||
|
||||
protected:
|
||||
|
||||
double time_out;
|
||||
|
||||
public:
|
||||
|
||||
MultiWorkProc()
|
||||
{
|
||||
time_out=5;
|
||||
}
|
||||
|
||||
virtual ~MultiWorkProc()=default;
|
||||
|
||||
void SetTimeOut(const double to) ///<设置超时时间
|
||||
{
|
||||
if(to<=0)time_out=0;
|
||||
else time_out=to;
|
||||
}
|
||||
|
||||
virtual void Post(W *w) override ///<投递一个工作
|
||||
{
|
||||
if(!w)return;
|
||||
|
||||
work_list.Post(w);
|
||||
work_list.PostSem(1);
|
||||
}
|
||||
|
||||
virtual void Post(W **w,int count) override ///<投递一批工作
|
||||
{
|
||||
if(!w||count<=0)return;
|
||||
|
||||
work_list.Post(w,count);
|
||||
work_list.PostSem(count);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* 开始执行工作函数
|
||||
*/
|
||||
virtual bool OnExecuteWork(const uint wt_index) override
|
||||
{
|
||||
//为什么不使用TrySemReceive,使用TrySemReceive固然会立即返回结果,但会引起线程频繁刷新造成CPU的流费。
|
||||
//使用WaitSemReceive目前唯一坏处是在退出时,需要等待超时时间。
|
||||
|
||||
W *obj=work_list.WaitSemReceive(time_out);
|
||||
|
||||
if(!obj)
|
||||
return(false);
|
||||
|
||||
this->OnWork(wt_index,obj);
|
||||
|
||||
return(true);
|
||||
}
|
||||
};//template<typename W> class MultiWorkProc:public WorkProc<W>
|
||||
|
||||
/**
|
||||
* 工作线程,用于真正处理事务
|
||||
*/
|
||||
template<typename W> class WorkThread:public Thread
|
||||
{
|
||||
protected:
|
||||
|
||||
using WorkList=List<W *>;
|
||||
|
||||
WorkProc<W> *work_proc;
|
||||
|
||||
uint work_thread_index;
|
||||
|
||||
bool force_close;
|
||||
|
||||
public:
|
||||
|
||||
WorkThread(WorkProc<W> *wp)
|
||||
{
|
||||
work_proc=wp;
|
||||
work_thread_index=0;
|
||||
force_close=false;
|
||||
}
|
||||
|
||||
#ifndef _DEBUG
|
||||
virtual ~WorkThread()=default;
|
||||
#else
|
||||
virtual ~WorkThread()
|
||||
{
|
||||
LOG_INFO(U8_TEXT("WorkThread Destruct [")+thread_addr_string+U8_TEXT("]"));
|
||||
}
|
||||
|
||||
#endif//_DEBUG
|
||||
|
||||
bool IsExitDelete()const override{return false;} ///<返回在退出线程时,不删除本对象
|
||||
|
||||
void SetWorkThreadIndex(const uint index)
|
||||
{
|
||||
work_thread_index=index;
|
||||
}
|
||||
|
||||
void ExitWork(const bool fc)
|
||||
{
|
||||
force_close=fc;
|
||||
Thread::WaitExit();
|
||||
}
|
||||
|
||||
virtual void ProcEndThread() override
|
||||
{
|
||||
if(!force_close) //不是强退
|
||||
while(work_proc->OnExecuteWork(work_thread_index)); //把工作全部做完
|
||||
|
||||
#ifdef _DEBUG
|
||||
{
|
||||
LOG_INFO(U8_TEXT("WorkThread Finish [")+thread_addr_string+U8_TEXT("]"));
|
||||
}
|
||||
#endif//_DEBUG
|
||||
}
|
||||
|
||||
virtual bool Execute() override
|
||||
{
|
||||
if(!work_proc)
|
||||
RETURN_FALSE;
|
||||
|
||||
work_proc->OnExecuteWork(work_thread_index);
|
||||
|
||||
return(true);
|
||||
}
|
||||
};//template<typename W> class WorkThread:public Thread
|
||||
|
||||
/**
|
||||
* 工作组<br>
|
||||
* 用于管理一组的工作线程以及投递器<br>
|
||||
* 注:可以一组工作线程共用一个投递器,也可以每个工作线程配一个投递器。工作组管理只为方便统一清理
|
||||
*/
|
||||
template<typename WP,typename WT> class WorkGroup
|
||||
{
|
||||
ObjectList<WP> wp_list; ///<投递器列表
|
||||
ObjectList<WT> wt_list; ///<工作线程列表
|
||||
|
||||
bool run=false;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~WorkGroup()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
virtual bool Add(WP *wp)
|
||||
{
|
||||
if(!wp)return(false);
|
||||
|
||||
wp_list.Add(wp);
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Add(WP **wp,const int count)
|
||||
{
|
||||
if(!wp)return(false);
|
||||
|
||||
wp_list.Add(wp,count);
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Add(WT *wt)
|
||||
{
|
||||
if(!wt)return(false);
|
||||
|
||||
int index=wt_list.Add(wt);
|
||||
wt->SetWorkThreadIndex(index);
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Add(WT **wt,const int count)
|
||||
{
|
||||
if(!wt)return(false);
|
||||
|
||||
int index=wt_list.Add(wt,count);
|
||||
for(int i=0;i<count;i++)
|
||||
{
|
||||
(*wt)->SetWorkThreadIndex(index);
|
||||
++index;
|
||||
++wt;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual bool Start()
|
||||
{
|
||||
int count=wt_list.GetCount();
|
||||
|
||||
if(count<=0)
|
||||
RETURN_FALSE;
|
||||
|
||||
WT **wt=wt_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
wt[i]->Start();
|
||||
|
||||
run=true;
|
||||
return(true);
|
||||
}
|
||||
|
||||
virtual void Close(bool force_close=false)
|
||||
{
|
||||
if(!run)return;
|
||||
|
||||
int count=wt_list.GetCount();
|
||||
|
||||
WT **wt=wt_list.GetData();
|
||||
|
||||
for(int i=0;i<count;i++)
|
||||
wt[i]->ExitWork(force_close);
|
||||
|
||||
run=false;
|
||||
}
|
||||
};//template<typename WP,typename WT> class WorkGroup
|
||||
}//namespace workflow
|
||||
}//namespace hgl
|
||||
#endif//HGL_WORKFLOW_INCLUDE
|
48
inc/hgl/thread/atomic/AtomicGNU.h
Normal file
48
inc/hgl/thread/atomic/AtomicGNU.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef HGL_THREAD_ATOMIC_GNU_INCLUDE
|
||||
#define HGL_THREAD_ATOMIC_GNU_INCLUDE
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
template<typename T> class atom
|
||||
{
|
||||
volatile T value;
|
||||
|
||||
public:
|
||||
|
||||
atom(){value=0;}
|
||||
atom(const volatile T new_value){operator=(new_value);}
|
||||
|
||||
inline T operator ->(){return value;}
|
||||
|
||||
inline T operator *= (const volatile T v) {return operator=(value *=v);}
|
||||
inline T operator /= (const volatile T v) {return operator=(value /=v);}
|
||||
inline T operator %= (const volatile T v) {return operator=(value %=v);}
|
||||
inline T operator >>= (const volatile T v) {return operator=(value>>=v);}
|
||||
inline T operator <<= (const volatile T v) {return operator=(value<<=v);}
|
||||
|
||||
inline T operator ! ()const {return !value;}
|
||||
inline T operator ~ ()const {return ~value;}
|
||||
|
||||
inline operator T () {return value;}
|
||||
inline operator const T ()const {return value;}
|
||||
inline bool operator ! () {return !value;}
|
||||
|
||||
inline bool operator == (const volatile T v)const {return value==v;}
|
||||
inline bool operator != (const volatile T v)const {return value!=v;}
|
||||
|
||||
inline T operator = (const volatile T new_value) {__sync_lock_test_and_set(&value,new_value); return value;}
|
||||
|
||||
inline T operator += (const volatile T add_value) {return __sync_add_and_fetch(&value,add_value);}
|
||||
inline T operator -= (const volatile T sub_value) {return __sync_sub_and_fetch(&value,sub_value);}
|
||||
|
||||
inline T operator &= (const volatile T v) {return __sync_and_and_fetch(&value,v);}
|
||||
inline T operator |= (const volatile T v) {return __sync_or_and_fetch (&value,v);}
|
||||
inline T operator ^= (const volatile T v) {return __sync_xor_and_fetch(&value,v);}
|
||||
|
||||
inline T operator ++ () {return __sync_add_and_fetch(&value,1);} //前置++
|
||||
inline T operator ++ (int) {return __sync_fetch_and_add(&value,1);} //后置++
|
||||
inline T operator -- () {return __sync_sub_and_fetch(&value,1);}
|
||||
inline T operator -- (int) {return __sync_fetch_and_sub(&value,1);}
|
||||
};//template<typename T> class atom
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_ATOMIC_GNU_INCLUDE
|
50
inc/hgl/thread/atomic/AtomicOSX.h
Normal file
50
inc/hgl/thread/atomic/AtomicOSX.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef HGL_THREAD_ATOMIC_OSX_INCLUDE
|
||||
#define HGL_THREAD_ATOMIC_OSX_INCLUDE
|
||||
|
||||
#include<libkern/OSAtomic.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
typedef int aint;
|
||||
|
||||
typedef volatile aint avint;
|
||||
typedef const avint cavint;
|
||||
|
||||
template<typename T> class atom ///原子数据
|
||||
{
|
||||
avint value;
|
||||
|
||||
public:
|
||||
|
||||
atom(){value=0;}
|
||||
atom(cavint new_value){operator=(new_value);}
|
||||
|
||||
inline aint operator *= (cavint v) {return operator=(value *=v);}
|
||||
inline aint operator /= (cavint v) {return operator=(value /=v);}
|
||||
inline aint operator %= (cavint v) {return operator=(value %=v);}
|
||||
inline aint operator >>= (cavint v) {return operator=(value>>=v);}
|
||||
inline aint operator <<= (cavint v) {return operator=(value<<=v);}
|
||||
|
||||
inline aint operator ! ()const {return !value;}
|
||||
inline aint operator ~ ()const {return ~value;}
|
||||
|
||||
inline operator const aint ()const {return value;}
|
||||
inline bool operator ! () {return !value;}
|
||||
|
||||
inline bool operator == (cavint v)const {return value==v;}
|
||||
inline bool operator != (cavint v)const {return value!=v;}
|
||||
inline aint operator = (cavint new_value) {value=new_value;return value;}
|
||||
inline aint operator ++ () {return OSAtomicIncrement32(&value);}
|
||||
inline aint operator -- () {return OSAtomicDecrement32(&value);}
|
||||
inline aint operator += (cavint add_value) {return;}
|
||||
inline aint operator -= (cavint sub_value) {return;}
|
||||
|
||||
inline aint operator &= (cavint v) {return operator=(value &=v);}
|
||||
inline aint operator |= (cavint v) {return operator=(value |=v);}
|
||||
inline aint operator ^= (cavint v) {return operator=(value ^=v);}
|
||||
|
||||
inline aint operator ++ (int) {aint ret=value;operator++();return ret;}//后置++
|
||||
inline aint operator -- (int) {volatile T ret=value;operator--();return ret;}//后置--
|
||||
};//class atom
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_ATOMIC_OSX_INCLUDE
|
91
inc/hgl/thread/atomic/AtomicWin.h
Normal file
91
inc/hgl/thread/atomic/AtomicWin.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef HGL_THREAD_ATOMIC_WINDOWS_INCLUDE
|
||||
#define HGL_THREAD_ATOMIC_WINDOWS_INCLUDE
|
||||
|
||||
#include<windows.h>
|
||||
namespace hgl
|
||||
{
|
||||
//开发日志 2013-06-19
|
||||
//1.原本是一个模板,但将32/64中不一样的部分各自特例化,但不知为何VC2012中无法认出对应的操作符,所以改成2个模板
|
||||
//2.部分原子函数没有8/16位版本
|
||||
|
||||
//32位版
|
||||
template<typename T> class atom_win32
|
||||
{
|
||||
volatile T value;
|
||||
|
||||
public:
|
||||
|
||||
atom_win32(){value=0;}
|
||||
atom_win32(const volatile T new_value){operator=(new_value);}
|
||||
|
||||
T operator *= (const volatile T v) {return operator=(value *=v);}
|
||||
T operator /= (const volatile T v) {return operator=(value /=v);}
|
||||
T operator %= (const volatile T v) {return operator=(value %=v);}
|
||||
T operator >>= (const volatile T v) {return operator=(value>>=v);}
|
||||
T operator <<= (const volatile T v) {return operator=(value<<=v);}
|
||||
|
||||
T operator ! ()const {return !value;}
|
||||
T operator ~ ()const {return ~value;}
|
||||
|
||||
operator T () {return value;}
|
||||
operator const T ()const {return value;}
|
||||
bool operator ! () {return !value;}
|
||||
|
||||
bool operator == (const volatile T v)const {return value==v;}
|
||||
bool operator != (const volatile T v)const {return value!=v;}
|
||||
|
||||
T operator = (const volatile T nv) {return InterlockedExchange((unsigned long *)&value,(unsigned long)nv);}
|
||||
T operator ++ () {return InterlockedIncrement((unsigned long *)&value);}
|
||||
T operator -- () {return InterlockedDecrement((unsigned long *)&value);}
|
||||
T operator += (const volatile T av) {return InterlockedExchangeAdd((unsigned long *)&value, av); }
|
||||
T operator -= (const volatile T av) {return InterlockedExchangeAdd((unsigned long *)&value, -av); }
|
||||
|
||||
volatile T operator &= (const volatile T v) {return InterlockedAnd((unsigned long *)&value,v);}
|
||||
volatile T operator |= (const volatile T v) {return InterlockedOr((unsigned long *)&value, v); }
|
||||
volatile T operator ^= (const volatile T v) {return InterlockedXor((unsigned long *)&value, v); }
|
||||
|
||||
volatile T operator ++ (int) {volatile T ret=value;operator++();return ret;}//后置++
|
||||
volatile T operator -- (int) {volatile T ret=value;operator--();return ret;}//后置--
|
||||
};//template<typename T> class atom_win32
|
||||
|
||||
//64位版
|
||||
template<typename T> class atom_win64
|
||||
{
|
||||
volatile T value;
|
||||
|
||||
public:
|
||||
|
||||
atom_win64(){value=0;}
|
||||
atom_win64(const volatile T new_value){operator=(new_value);}
|
||||
|
||||
T operator *= (const volatile T v) {return operator=(value *=v);}
|
||||
T operator /= (const volatile T v) {return operator=(value /=v);}
|
||||
T operator %= (const volatile T v) {return operator=(value %=v);}
|
||||
T operator >>= (const volatile T v) {return operator=(value>>=v);}
|
||||
T operator <<= (const volatile T v) {return operator=(value<<=v);}
|
||||
|
||||
T operator ! ()const {return !value;}
|
||||
T operator ~ ()const {return ~value;}
|
||||
|
||||
operator T () {return value;}
|
||||
operator const T ()const {return value;}
|
||||
bool operator ! () {return !value;}
|
||||
|
||||
bool operator == (const volatile T v)const {return value==v;}
|
||||
bool operator != (const volatile T v)const {return value!=v;}
|
||||
|
||||
T operator = (const volatile T nv) {return InterlockedExchange64((LONG64 *)&value, (LONG64)nv); }
|
||||
T operator ++ () {return InterlockedIncrement64((LONG64 *)&value); }
|
||||
T operator -- () {return InterlockedDecrement64((LONG64 *)&value); }
|
||||
T operator += (const volatile T av) {return InterlockedExchangeAdd64((LONG64 *)&value, av); }
|
||||
T operator -= (const volatile T av) {return InterlockedExchangeAdd64((LONG64 *)&value, -av); }
|
||||
|
||||
volatile T operator &= (const volatile T v) {return InterlockedAnd64((LONG64 *)&value, v); }
|
||||
volatile T operator |= (const volatile T v) {return InterlockedOr64((LONG64 *)&value, v); }
|
||||
volatile T operator ^= (const volatile T v) {return InterlockedXor64((LONG64 *)&value, v); }
|
||||
|
||||
volatile T operator ++ (int) {volatile T ret=value;operator++();return ret;}//后置++
|
||||
volatile T operator -- (int) {volatile T ret=value;operator--();return ret;}//后置--
|
||||
};//template<typename T> class atom_win64
|
||||
}//namespace hgl
|
||||
#endif//HGL_THREAD_ATOMIC_WINDOWS_INCLUDE
|
1208
inc/hgl/type/BaseString.h
Normal file
1208
inc/hgl/type/BaseString.h
Normal file
File diff suppressed because it is too large
Load Diff
11
inc/hgl/type/DataType.h
Normal file
11
inc/hgl/type/DataType.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef HGL_DATATYPE_INCLUDE
|
||||
#define HGL_DATATYPE_INCLUDE
|
||||
|
||||
#include<hgl/platform/Platform.h> // 平台定义
|
||||
#include<hgl/Macro.h> // 常用宏定义
|
||||
#include<hgl/type/Smart.h> // 智能指针
|
||||
#include<hgl/TypeFunc.h> // 常用数值宏及内联函数
|
||||
#include<hgl/endian/Endian.h> // 编码序定义
|
||||
#include<hgl/CompOperator.h> // 比较操作符实现定义
|
||||
|
||||
#endif//HGL_DATATYPE_INCLUDE
|
460
inc/hgl/type/Smart.h
Normal file
460
inc/hgl/type/Smart.h
Normal file
@ -0,0 +1,460 @@
|
||||
#ifndef HGL_SMART_INCLUDE
|
||||
#define HGL_SMART_INCLUDE
|
||||
|
||||
#include<hgl/TypeFunc.h>
|
||||
#include<hgl/Macro.h>
|
||||
#include<hgl/thread/Atomic.h>
|
||||
namespace hgl
|
||||
{
|
||||
struct RefCount
|
||||
{
|
||||
atom_int count;
|
||||
atom_int weak;
|
||||
|
||||
public:
|
||||
|
||||
RefCount()
|
||||
{
|
||||
count=1;
|
||||
weak=0;
|
||||
}
|
||||
|
||||
virtual ~RefCount()=default;
|
||||
|
||||
virtual void Delete()=0;
|
||||
|
||||
int inc_ref()
|
||||
{
|
||||
return ++count;
|
||||
}
|
||||
|
||||
virtual int unref()
|
||||
{
|
||||
count--;
|
||||
|
||||
if(count<=0)
|
||||
{
|
||||
Delete();
|
||||
|
||||
if(weak<=0)
|
||||
delete this;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int inc_ref_weak()
|
||||
{
|
||||
return ++weak;
|
||||
}
|
||||
|
||||
int unref_weak()
|
||||
{
|
||||
weak--;
|
||||
|
||||
if(weak<=0)
|
||||
{
|
||||
if(count<=0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return weak;
|
||||
}
|
||||
};//struct RefCount
|
||||
|
||||
template<typename T> struct SmartData:public RefCount
|
||||
{
|
||||
T *data;
|
||||
|
||||
public:
|
||||
|
||||
SmartData(T *ptr)
|
||||
{
|
||||
data=ptr;
|
||||
}
|
||||
|
||||
~SmartData()
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
|
||||
void Delete()
|
||||
{
|
||||
SAFE_CLEAR(data);
|
||||
}
|
||||
};//struct template<typename T> struct SmartData
|
||||
|
||||
template<typename T> struct SmartArrayData:public RefCount
|
||||
{
|
||||
T *data;
|
||||
|
||||
public:
|
||||
|
||||
SmartArrayData(T *ptr)
|
||||
{
|
||||
data=ptr;
|
||||
}
|
||||
|
||||
~SmartArrayData()
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
|
||||
void Delete()
|
||||
{
|
||||
SAFE_CLEAR_ARRAY(data);
|
||||
}
|
||||
|
||||
const T &operator *() const {return data;}
|
||||
const bool operator!() const{return !data;}
|
||||
};//struct template<typename T> struct SmartArrayData
|
||||
|
||||
template<typename SD,typename T> class _Smart
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef _Smart<SD,T> SelfClass;
|
||||
|
||||
SD *sd;
|
||||
|
||||
public:
|
||||
|
||||
_Smart()
|
||||
{
|
||||
sd=0;
|
||||
}
|
||||
|
||||
_Smart(T *ptr)
|
||||
{
|
||||
if(ptr)
|
||||
sd=new SD(ptr);
|
||||
else
|
||||
sd=0;
|
||||
}
|
||||
|
||||
_Smart(const SelfClass &st)
|
||||
{
|
||||
sd=0;
|
||||
|
||||
set(st);
|
||||
}
|
||||
|
||||
virtual ~_Smart()=default;
|
||||
|
||||
T *set(T *ptr)
|
||||
{
|
||||
if(sd)
|
||||
sd->unref();
|
||||
|
||||
if(!ptr)
|
||||
{
|
||||
sd=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
sd=new SD(ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void inc_ref(const SelfClass &sc)
|
||||
{
|
||||
if(sd==sc.sd)return;
|
||||
|
||||
unref();
|
||||
|
||||
sd=sc.sd;
|
||||
|
||||
if(sd)
|
||||
sd->inc_ref();
|
||||
}
|
||||
|
||||
void unref()
|
||||
{
|
||||
if(sd)
|
||||
{
|
||||
sd->unref();
|
||||
sd=0;
|
||||
}
|
||||
}
|
||||
|
||||
void inc_ref_weak(const SelfClass &sc)
|
||||
{
|
||||
if(sd==sc.sd)return;
|
||||
|
||||
unref();
|
||||
|
||||
sd=sc.sd;
|
||||
|
||||
if(sd)
|
||||
sd->inc_ref_weak();
|
||||
}
|
||||
|
||||
void unref_weak()
|
||||
{
|
||||
if(sd)
|
||||
{
|
||||
sd->unref_weak();
|
||||
sd=0;
|
||||
}
|
||||
}
|
||||
|
||||
T *get()const{return sd?sd->data:0;}
|
||||
virtual bool valid()const{return sd;}
|
||||
int use_count()const{return sd?sd->count:-1;}
|
||||
bool only()const{return sd?sd->count==1:true;}
|
||||
|
||||
public:
|
||||
|
||||
const T &operator *() const {return *(sd->data);}
|
||||
const bool operator!() const{return sd?!(sd->data):true;}
|
||||
|
||||
operator T *()const{return(sd?sd->data:0);}
|
||||
T *operator ->()const{return(sd?sd->data:0);}
|
||||
|
||||
bool operator == (const SelfClass & rp)const{return(get()==rp.get()); }
|
||||
bool operator == (const T * rp)const{return(get()==rp); }
|
||||
|
||||
bool operator != (const SelfClass & rp)const{return !(operator==(rp)); }
|
||||
bool operator != (const T * rp)const{return !(operator==(rp)); }
|
||||
};//template <typename T> class _Smart
|
||||
|
||||
template<typename T> class WeakPtr;
|
||||
|
||||
/**
|
||||
* 共享指针数据类<br>
|
||||
* 用于自动释放超出作用域的指针
|
||||
*/
|
||||
template<typename T> class SharedPtr:public _Smart<SmartData<T>,T> ///共享指针数据类
|
||||
{
|
||||
friend class WeakPtr<T>;
|
||||
|
||||
public:
|
||||
|
||||
typedef _Smart<SmartData<T>,T> SuperClass;
|
||||
typedef SharedPtr<T> SelfClass;
|
||||
|
||||
public:
|
||||
|
||||
SharedPtr():SuperClass(){}
|
||||
SharedPtr(T *ptr):SuperClass(ptr){}
|
||||
SharedPtr(const SelfClass &sp):SuperClass()
|
||||
{
|
||||
operator=(sp);
|
||||
}
|
||||
|
||||
SharedPtr(const WeakPtr<T> &wp):SuperClass()
|
||||
{
|
||||
operator=(wp);
|
||||
}
|
||||
|
||||
~SharedPtr()
|
||||
{
|
||||
SuperClass::unref();
|
||||
}
|
||||
|
||||
operator T *()
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
operator const T *()const
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
T *operator =(T *ptr)
|
||||
{
|
||||
return SuperClass::set(ptr);
|
||||
}
|
||||
|
||||
SelfClass &operator =(const SelfClass &sp)
|
||||
{
|
||||
SuperClass::inc_ref(sp);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
SelfClass &operator =(const WeakPtr<T> &wp)
|
||||
{
|
||||
SuperClass::inc_ref(wp);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
bool valid()const override{return this->sd?(this->sd->data?true:false):false;}
|
||||
};//template <typename T> class SharedPtr
|
||||
|
||||
template<typename T> class WeakArray;
|
||||
|
||||
/**
|
||||
* 共享阵列数据类,它在SharedPtr的基础上增加了[]操作符访问,以及在删除时使用delete[]
|
||||
*/
|
||||
template<typename T> class SharedArray:public _Smart<SmartArrayData<T>,T> ///共享阵列数据类
|
||||
{
|
||||
friend class WeakArray<T>;
|
||||
|
||||
public:
|
||||
|
||||
typedef _Smart<SmartArrayData<T>,T> SuperClass;
|
||||
typedef SharedArray<T> SelfClass;
|
||||
|
||||
public:
|
||||
|
||||
SharedArray():SuperClass(){}
|
||||
SharedArray(T *ptr):SuperClass(ptr){}
|
||||
SharedArray(const SelfClass &sa):SuperClass()
|
||||
{
|
||||
operator=(sa);
|
||||
}
|
||||
|
||||
SharedArray(const WeakArray<T> &wa):SuperClass()
|
||||
{
|
||||
operator=(wa);
|
||||
}
|
||||
|
||||
~SharedArray()
|
||||
{
|
||||
SuperClass::unref();
|
||||
}
|
||||
|
||||
operator T *()
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
operator const T *()const
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
T &operator [](int n)
|
||||
{
|
||||
return SuperClass::sd->data[n];
|
||||
}
|
||||
|
||||
SelfClass &operator =(const SelfClass &sap)
|
||||
{
|
||||
SuperClass::inc_ref(sap);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
SelfClass &operator =(const WeakPtr<T> &wp)
|
||||
{
|
||||
SuperClass::inc_ref(wp);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
};//template <typename T> class SharedArray
|
||||
|
||||
template<typename T> class WeakPtr:public _Smart<SmartData<T>,T>
|
||||
{
|
||||
friend class SharedPtr<T>;
|
||||
|
||||
public:
|
||||
|
||||
typedef _Smart<SmartData<T>,T> SuperClass;
|
||||
typedef WeakPtr<T> SelfClass;
|
||||
|
||||
public:
|
||||
|
||||
WeakPtr():SuperClass(){}
|
||||
WeakPtr(const SharedPtr<T> &sp):SuperClass()
|
||||
{
|
||||
operator=(sp);
|
||||
}
|
||||
|
||||
WeakPtr(const SelfClass &wp):SuperClass()
|
||||
{
|
||||
operator=(wp);
|
||||
}
|
||||
|
||||
~WeakPtr()
|
||||
{
|
||||
SuperClass::unref_weak();
|
||||
}
|
||||
|
||||
operator T *()
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
operator const T *()const
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
virtual SuperClass &operator =(const SharedPtr<T> &sp)
|
||||
{
|
||||
SuperClass::inc_ref_weak(sp);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
virtual SelfClass &operator =(const SelfClass &wp)
|
||||
{
|
||||
SuperClass::inc_ref_weak(wp);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
};//template<typename T> class WeakPtr
|
||||
|
||||
template<typename T> class WeakArray:public _Smart<SmartArrayData<T>,T>
|
||||
{
|
||||
friend class SharedArray<T>;
|
||||
|
||||
public:
|
||||
|
||||
typedef _Smart<SmartArrayData<T>,T> SuperClass;
|
||||
typedef WeakArray<T> SelfClass;
|
||||
|
||||
public:
|
||||
|
||||
WeakArray():SuperClass(){}
|
||||
WeakArray(const SharedArray<T> &sap):SuperClass()
|
||||
{
|
||||
operator=(sap);
|
||||
}
|
||||
|
||||
WeakArray(const WeakArray<T> &wap):SuperClass()
|
||||
{
|
||||
operator=(wap);
|
||||
}
|
||||
|
||||
~WeakArray()
|
||||
{
|
||||
SuperClass::unref_weak();
|
||||
}
|
||||
|
||||
operator T *()
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
operator const T *()const
|
||||
{
|
||||
return SuperClass::get();
|
||||
}
|
||||
|
||||
virtual SuperClass &operator =(const SharedArray<T> &sap)
|
||||
{
|
||||
SuperClass::inc_ref_weak(sap);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
virtual SelfClass &operator =(const SelfClass &wap)
|
||||
{
|
||||
SuperClass::inc_ref_weak(wap);
|
||||
|
||||
return(*this);
|
||||
}
|
||||
};//template<typename T> class WeakArray
|
||||
}//namespace hgl
|
||||
#endif//HGL_SMART_INCLUDE
|
35
inc/hgl/type/StdString.h
Normal file
35
inc/hgl/type/StdString.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include<string>
|
||||
#include<hgl/type/BaseString.h>
|
||||
#include<hgl/CodePage.h>
|
||||
|
||||
#if HGL_OS == HGL_OS_Windows
|
||||
inline hgl::OSString ToOSString(const std::string &str)
|
||||
{
|
||||
return hgl::to_u16(str.c_str(),(int)(str.length()));
|
||||
}
|
||||
|
||||
inline std::string ToStdString(const hgl::OSString &str)
|
||||
{
|
||||
UTF8String u8_str=hgl::to_u8(str);
|
||||
|
||||
return std::string(u8_str.c_str());
|
||||
}
|
||||
#else
|
||||
inline hgl::OSString ToOSString(const std::string &str)
|
||||
{
|
||||
return hgl::OSString(str.c_str(),str.size());
|
||||
}
|
||||
|
||||
inline std::string ToStdString(const hgl::OSString &str)
|
||||
{
|
||||
return std::string(str.c_str());
|
||||
}
|
||||
#endif//
|
||||
|
||||
inline hgl::UTF8String ToUTF8String(const std::string &str)
|
||||
{
|
||||
return hgl::UTF8String(str.c_str(),str.size());
|
||||
}
|
||||
|
501
inc/hgl/type/StringInstance.h
Normal file
501
inc/hgl/type/StringInstance.h
Normal file
@ -0,0 +1,501 @@
|
||||
#ifndef HGL_TYPE_STRING_INSTANCE_INCLUDE
|
||||
#define HGL_TYPE_STRING_INSTANCE_INCLUDE
|
||||
|
||||
#include<hgl/type/DataType.h>
|
||||
#include<hgl/Str.h>
|
||||
#include<string.h>
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 字符串实例类
|
||||
*/
|
||||
template<typename T> class StringInstance ///字符串实例类
|
||||
{
|
||||
protected:
|
||||
|
||||
typedef StringInstance<T> SelfClass;
|
||||
|
||||
int length; ///<字符串长度
|
||||
int malloc_length; ///<空间实际分配长度
|
||||
|
||||
T *buffer;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void InitPrivate()
|
||||
{
|
||||
malloc_length=0;
|
||||
length=0;
|
||||
buffer=0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
StringInstance()
|
||||
{
|
||||
InitPrivate();
|
||||
}
|
||||
|
||||
StringInstance(const T *str,int len=-1,bool one_instance=false)
|
||||
{
|
||||
if(!str)
|
||||
{
|
||||
InitPrivate();
|
||||
return;
|
||||
}
|
||||
|
||||
if(len<0)
|
||||
length=hgl::strlen(str);
|
||||
else
|
||||
{
|
||||
length=hgl::strlen(str,len);
|
||||
|
||||
while(length&&!str[length-1]) //清除后面的0
|
||||
length--;
|
||||
}
|
||||
|
||||
if(length<=0)
|
||||
{
|
||||
InitPrivate();
|
||||
|
||||
if(one_instance)
|
||||
delete[] str;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(one_instance&&str[length]==0) //如果最后不是0,则需要重新分配内存创建带0结尾的字串
|
||||
{
|
||||
malloc_length=len;
|
||||
buffer=(T *)str;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
malloc_length=power_to_2(length+1);
|
||||
|
||||
buffer=new T[malloc_length];
|
||||
memcpy(buffer,str,length*sizeof(T));
|
||||
buffer[length]=0;
|
||||
|
||||
if(one_instance)
|
||||
delete[] str;
|
||||
}
|
||||
|
||||
StringInstance(const SelfClass &bs)
|
||||
{
|
||||
if(bs.Length<=0)
|
||||
{
|
||||
InitPrivate();
|
||||
return;
|
||||
}
|
||||
|
||||
length=bs.length;
|
||||
|
||||
if(length<=0)
|
||||
return;
|
||||
|
||||
malloc_length=bs.malloc_length;
|
||||
|
||||
buffer=new T[malloc_length];
|
||||
memcpy(buffer,bs.buffer,length*sizeof(T));
|
||||
}
|
||||
|
||||
virtual ~StringInstance()
|
||||
{
|
||||
delete[] buffer; //delete[] NULL; don't is error
|
||||
}
|
||||
|
||||
const bool isEmpty()const ///<是否为空
|
||||
{
|
||||
return !buffer;
|
||||
}
|
||||
|
||||
SelfClass *CreateCopy() ///<创建一份自身的拷贝
|
||||
{
|
||||
if(!buffer)return(0);
|
||||
|
||||
return(new SelfClass(buffer,length));
|
||||
}
|
||||
|
||||
SelfClass *CreateCopy(int start,int count=-1)
|
||||
{
|
||||
if(!buffer)return(nullptr);
|
||||
if(start<0||count==0)return(nullptr);
|
||||
if(count>0&&start+count>=length)return(nullptr);
|
||||
|
||||
return(new SelfClass(buffer+start,count));
|
||||
}
|
||||
|
||||
T *Discard()
|
||||
{
|
||||
T *result=buffer;
|
||||
|
||||
buffer=nullptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
T * c_str() ///<取得字符串C指针
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
const int GetLength()const ///<取得字符串长度
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
bool GetChar(int n,T &ch)const
|
||||
{
|
||||
if(n>=length)
|
||||
return(false);
|
||||
|
||||
ch=buffer[n];
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool SetChar(int n,const T &ch)
|
||||
{
|
||||
if(n>=length)
|
||||
return(false);
|
||||
|
||||
buffer[n]=ch;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
const T GetBeginChar()const
|
||||
{
|
||||
return buffer?*buffer:0;
|
||||
}
|
||||
|
||||
const T GetEndChar()const
|
||||
{
|
||||
return buffer?*(buffer+length-1):0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串进行比较
|
||||
* @param sc 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int Comp(const SelfClass *sc)const
|
||||
{
|
||||
if(!sc)
|
||||
return length;
|
||||
|
||||
return hgl::strcmp(buffer,length,sc->buffer,sc->length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串进行比较
|
||||
* @param pos 起始位置
|
||||
* @param sc 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int Comp(const int pos,const SelfClass *sc)const
|
||||
{
|
||||
if(!sc)
|
||||
return length;
|
||||
|
||||
if(length<pos)
|
||||
return -1;
|
||||
|
||||
return hgl::strcmp(buffer+pos,length-pos,sc->buffer,sc->length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串进行比较
|
||||
* @param str 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int Comp(const T *str)const
|
||||
{
|
||||
return hgl::strcmp(buffer,length,str,hgl::strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串进行比较
|
||||
* @param pos 起始位置
|
||||
* @param str 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int Comp(const int pos,const T *str)const
|
||||
{
|
||||
if(!str)
|
||||
return length;
|
||||
|
||||
if(length<pos)
|
||||
return -1;
|
||||
|
||||
return hgl::strcmp(buffer+pos,length-pos,str,hgl::strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串比较指字长度的字符
|
||||
* @param str 比较字符串
|
||||
* @param num 比较字数
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int Comp(const T *str,const int num)const
|
||||
{
|
||||
if(!str)
|
||||
return length-num;
|
||||
|
||||
return hgl::strcmp(buffer,str,num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串比较指字长度的字符
|
||||
* @param str 比较字符串
|
||||
* @param num 比较字数
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int Comp(const int pos,const T *str,const int num)const
|
||||
{
|
||||
if(!str)
|
||||
return(length-pos);
|
||||
|
||||
if(length<pos)
|
||||
return(-1);
|
||||
|
||||
return hgl::strcmp(buffer+pos,str,num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串进行比较,英文不区分大小写
|
||||
* @param sc 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int CaseComp(const SelfClass &sc)const
|
||||
{
|
||||
return hgl::stricmp(buffer,length,sc.buffer,sc.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 和那一个字符串进行比较,英文不区分大小写
|
||||
* @param str 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int CaseComp(const T &str)const
|
||||
{
|
||||
return hgl::stricmp(buffer,length,str,hgl::strlen(str));
|
||||
}
|
||||
|
||||
/**
|
||||
* 和一个字符串进行比较指字长度的字符,英文不区分大小写
|
||||
* @param sc 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int CaseComp(const SelfClass &sc,const int num)const
|
||||
{
|
||||
return hgl::stricmp(buffer,length,sc.buffer,num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 和那一个字符串进行比较指字长度的字符,英文不区分大小写
|
||||
* @param str 比较字符串
|
||||
* @return <0 我方小
|
||||
* @return 0 等同
|
||||
* @return >0 我方大
|
||||
*/
|
||||
const int CaseComp(const T &str,const int num)const
|
||||
{
|
||||
return hgl::stricmp(buffer,length,str,num);
|
||||
}
|
||||
|
||||
bool Insert(int pos,const T *istr,int len) ///<插入一个字符串
|
||||
{
|
||||
if(!istr||!*istr)
|
||||
return(false);
|
||||
|
||||
if(len==-1)
|
||||
len=hgl::strlen(istr);
|
||||
else
|
||||
len=hgl::strlen(istr,len);
|
||||
|
||||
if(pos<0||pos>length||len<=0)return(false);
|
||||
|
||||
const int need_length=length+len+1;
|
||||
|
||||
if(need_length>malloc_length)
|
||||
{
|
||||
malloc_length=power_to_2(need_length);
|
||||
|
||||
T *new_str=new T[malloc_length];
|
||||
|
||||
if(pos)
|
||||
hgl_typecpy(new_str,buffer,pos);
|
||||
|
||||
hgl_typecpy(new_str+pos,istr,len);
|
||||
|
||||
if(pos<length)
|
||||
hgl_typecpy(new_str+pos+len,buffer+pos,length-pos);
|
||||
|
||||
new_str[need_length-1]=0;
|
||||
|
||||
length+=len;
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
buffer=new_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
hgl_typemove(buffer+pos+len,buffer+pos,length-pos+1);
|
||||
hgl_typecpy(buffer+pos,istr,len);
|
||||
length+=len;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Insert(int pos,const T &ch ){return Insert(pos, &ch, 1 );}
|
||||
bool Insert(int pos,const T *str ){return Insert(pos, str, hgl::strlen(str));}
|
||||
bool Insert(int pos,const SelfClass &str){return Insert(pos, str.c_str(),str.GetLength() );}
|
||||
|
||||
bool Append(const T &ch ){return Insert(length, &ch, 1 );}
|
||||
bool Append(const T *str,const int len ){return Insert(length, str, len );}
|
||||
bool Append(const T *str ){return Insert(length, str, hgl::strlen(str));}
|
||||
bool Append(const SelfClass &str ){return Insert(length, str.c_str(),str.GetLength() );}
|
||||
|
||||
bool Delete(int pos,int num) ///<删除指定字符
|
||||
{
|
||||
if(pos<0||pos>=length||num<0)return(false);
|
||||
|
||||
if(num==0)return(true);
|
||||
|
||||
if(pos+num>length) //超出长度
|
||||
{
|
||||
buffer[pos]=0;
|
||||
|
||||
length=pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
hgl_typemove(buffer+pos,buffer+pos+num,length-pos-num);
|
||||
|
||||
length-=num;
|
||||
|
||||
buffer[length]=0;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ClipLeft(int num)
|
||||
{
|
||||
if(num<0||num>length)
|
||||
return(false);
|
||||
|
||||
buffer[num]=0;
|
||||
length=num;
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool TrimRight(int num)
|
||||
{
|
||||
return ClipLeft(length-num);
|
||||
}
|
||||
|
||||
bool Clip(int pos,int num)
|
||||
{
|
||||
if(pos<0||pos>length
|
||||
||num<0||pos+num>length)
|
||||
return(false);
|
||||
|
||||
hgl_typemove(buffer,buffer+pos,num);
|
||||
buffer[num]=0;
|
||||
length=num;
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool SubString(const int start,int n=-1)
|
||||
{
|
||||
if(start<0||n==0)return(false);
|
||||
if(n>0&&start+n>length)return(false);
|
||||
|
||||
if(n<0)
|
||||
n=length-start;
|
||||
|
||||
hgl_typemove(buffer,buffer+start,n);
|
||||
buffer[n]=0;
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Resize(int num)
|
||||
{
|
||||
if(num<=0)
|
||||
return(false);
|
||||
|
||||
if(num<length)
|
||||
{
|
||||
buffer[num]=0;
|
||||
length=num;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(length>=malloc_length)
|
||||
{
|
||||
malloc_length=power_to_2(length+1);
|
||||
T *new_str=new T[malloc_length];
|
||||
hgl_typecpy(new_str,buffer,length);
|
||||
delete[] buffer;
|
||||
buffer=new_str;
|
||||
}
|
||||
|
||||
hgl_set(buffer+length,' ',num-length);
|
||||
length=num;
|
||||
buffer[length]=0;
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Write(int pos,const SelfClass &str)
|
||||
{
|
||||
if(pos<0||pos>length)
|
||||
return(false);
|
||||
|
||||
int end_pos=pos+str.length;
|
||||
|
||||
if(end_pos>malloc_length)
|
||||
{
|
||||
malloc_length=power_to_2(end_pos+1);
|
||||
|
||||
T *new_str=new T[malloc_length];
|
||||
|
||||
hgl_typecpy(new_str,buffer,length);
|
||||
delete[] buffer;
|
||||
buffer=new_str;
|
||||
}
|
||||
|
||||
hgl_typecpy(buffer+pos,str.buffer,str.length);
|
||||
buffer[end_pos]=0;
|
||||
length=end_pos;
|
||||
return(true);
|
||||
}
|
||||
};//class StringInstance
|
||||
}//namespace hgl
|
||||
#endif//HGL_TYPE_STRING_INSTANCE_INCLUDE
|
42
inc/hgl/type/_Object.h
Normal file
42
inc/hgl/type/_Object.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef HGL__OBJECT_INCLUDE
|
||||
#define HGL__OBJECT_INCLUDE
|
||||
|
||||
#include<hgl/type/BaseString.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
/**
|
||||
* 最终基类
|
||||
*/
|
||||
class _Object ///最终基类
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~_Object()=default; ///<本类析构函数
|
||||
|
||||
public: //调试用
|
||||
|
||||
virtual UTF8String ToDebugString(){} ///<输出调试用字符串
|
||||
};//class _Object
|
||||
|
||||
typedef void (_Object::*ObjectMemberFunc)();
|
||||
|
||||
//此代码取自AngelScript,感谢
|
||||
#define GetMemberFuncPointer(c,m) MethodPtr<sizeof(void (c::*)())>::Convert((void (c::*)())(&c::m))
|
||||
|
||||
template <int> struct MethodPtr
|
||||
{
|
||||
template<class M>
|
||||
static void *Convert(M Mthd)
|
||||
{
|
||||
union u
|
||||
{
|
||||
M m;
|
||||
void *v;
|
||||
};
|
||||
|
||||
return ((u *)(&Mthd))->v;
|
||||
}
|
||||
};//struct MethodPtr
|
||||
}//namespace hgl
|
||||
#endif//HGL__OBJECT_INCLUDE
|
Loading…
x
Reference in New Issue
Block a user