481 lines
10 KiB
C
481 lines
10 KiB
C
|
|
#ifndef __VIZUM_HELPER_HEADER__
|
|||
|
|
#define __VIZUM_HELPER_HEADER__
|
|||
|
|
|
|||
|
|
#include <atomic>
|
|||
|
|
#include <mutex>
|
|||
|
|
#include <vector>
|
|||
|
|
#include <set>
|
|||
|
|
#include <list>
|
|||
|
|
#include <queue>
|
|||
|
|
#include <map>
|
|||
|
|
#include "string.h"
|
|||
|
|
#include <stdarg.h>
|
|||
|
|
|
|||
|
|
#ifndef _WIN32
|
|||
|
|
#include <unistd.h>
|
|||
|
|
#else
|
|||
|
|
#include <windows.h>
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#define _VZ_MEM_CHECK_ /*
|
|||
|
|
#ifdef _WIN32\
|
|||
|
|
#ifdef _DEBUG\
|
|||
|
|
#include <crtdbg.h>\
|
|||
|
|
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)\
|
|||
|
|
#endif\
|
|||
|
|
#endif
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
// Aligned memory allocated/free
|
|||
|
|
#define VzAlignedAlloc(_dwSize, _align) _aligned_malloc((_dwSize), (_align))
|
|||
|
|
|
|||
|
|
#define VzAlignedFree(_pointer)\
|
|||
|
|
if (NULL != (_pointer))\
|
|||
|
|
{_aligned_free((void*)(_pointer));(_pointer) = NULL;}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#define VZ_UNUSED(x) (void)x
|
|||
|
|
|
|||
|
|
#define VZ_EQU_D(_dVal, _dCmp) (fabs(_dVal - _dCmp) < 0.000001)
|
|||
|
|
#define VZ_EQU_F(_dVal, _dCmp) (fabs(_dVal - _dCmp) < 0.000001f)
|
|||
|
|
|
|||
|
|
#define VZ_DB2INT(a) \
|
|||
|
|
(int)(((a)>0.0 ? ((a)+0.5) : ((a)-0.5)))
|
|||
|
|
|
|||
|
|
#define VZ_FL2INT(a) \
|
|||
|
|
(int)(((a)>0.0f ? ((a)+0.5f) : ((a)-0.5f)))
|
|||
|
|
|
|||
|
|
#define VZ_DB2ULONGLONG(a) \
|
|||
|
|
(unsigned long long)(((a)>0.0 ? ((a)+0.5) : ((a)-0.5)))
|
|||
|
|
|
|||
|
|
class IVzUnknown;
|
|||
|
|
class IVzPoolElement;
|
|||
|
|
|
|||
|
|
//namespace VzMemLeakUtils
|
|||
|
|
//{
|
|||
|
|
// class AutoDetectMemory
|
|||
|
|
// {
|
|||
|
|
// public:
|
|||
|
|
// AutoDetectMemory()
|
|||
|
|
// {
|
|||
|
|
//#ifdef _WIN32
|
|||
|
|
//#ifdef _DEBUG
|
|||
|
|
// _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
|
|||
|
|
// _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
|||
|
|
//#endif
|
|||
|
|
//#endif
|
|||
|
|
// }
|
|||
|
|
// };
|
|||
|
|
//
|
|||
|
|
// static AutoDetectMemory gs_am;
|
|||
|
|
//}
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 记录申请的Unknwon对象
|
|||
|
|
//class CVzRecordSystemObject
|
|||
|
|
//{
|
|||
|
|
//public:
|
|||
|
|
// CVzRecordSystemObject()
|
|||
|
|
// {
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// ~CVzRecordSystemObject()
|
|||
|
|
// {
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
//public:
|
|||
|
|
// static CVzRecordSystemObject* GetInstance()
|
|||
|
|
// {
|
|||
|
|
// if (nullptr == m_SysObject)
|
|||
|
|
// {
|
|||
|
|
// m_SysObject = new CVzRecordSystemObject;
|
|||
|
|
// }
|
|||
|
|
// return m_SysObject;
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
//public:
|
|||
|
|
// /// @brief
|
|||
|
|
// /// 获取物体ID
|
|||
|
|
// void RecordObject(IVzUnknown* pIObject)
|
|||
|
|
// {
|
|||
|
|
// std::lock_guard<std::mutex> oAutoLock(m_mtxObj);
|
|||
|
|
// m_setRecordObjects.insert(pIObject);
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
// /// @brief
|
|||
|
|
// ///
|
|||
|
|
// void RemoveRecord(IVzUnknown* pIObject)
|
|||
|
|
// {
|
|||
|
|
// std::lock_guard<std::mutex> oAutoLock(m_mtxObj);
|
|||
|
|
// m_setRecordObjects.erase(pIObject);
|
|||
|
|
// }
|
|||
|
|
//
|
|||
|
|
//protected:
|
|||
|
|
// std::mutex m_mtxObj;
|
|||
|
|
// std::set<IVzUnknown*> m_setRecordObjects;
|
|||
|
|
//
|
|||
|
|
//protected:
|
|||
|
|
// static CVzRecordSystemObject* m_SysObject;
|
|||
|
|
//};
|
|||
|
|
|
|||
|
|
class IVzUnknown
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
IVzUnknown() : m_nReferenceCount(1)
|
|||
|
|
{
|
|||
|
|
//CVzRecordSystemObject::GetInstance()->RecordObject(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
virtual ~IVzUnknown()
|
|||
|
|
{
|
|||
|
|
//CVzRecordSystemObject::GetInstance()->RemoveRecord(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
virtual void AddRef()
|
|||
|
|
{
|
|||
|
|
std::atomic_fetch_add(&m_nReferenceCount, (unsigned int)1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
virtual int Release()
|
|||
|
|
{
|
|||
|
|
int nRef = std::atomic_fetch_sub(&m_nReferenceCount, (unsigned int)1);
|
|||
|
|
if (1 == nRef)
|
|||
|
|
delete this;
|
|||
|
|
return (nRef - 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
std::atomic<unsigned int> m_nReferenceCount;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// @breif
|
|||
|
|
/// 元素分配器
|
|||
|
|
class IVzElementAlloc : public IVzUnknown
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
/// @brief
|
|||
|
|
/// 分配一个元素。
|
|||
|
|
virtual bool AllocElement(void* pParam, IVzPoolElement** ppIElement) = 0;
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 设置分配参数
|
|||
|
|
virtual void SetElementParam(IVzPoolElement* pIElement, void* pParam) { VZ_UNUSED(pIElement); VZ_UNUSED(pParam); }
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 元素池基类
|
|||
|
|
class IVzPoolUnknown : public IVzUnknown
|
|||
|
|
{
|
|||
|
|
friend class IVzPoolElement;
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
/// @brief
|
|||
|
|
/// 回收一个对象
|
|||
|
|
/// <param name = "pIElement">[in]要回收的对象</param>
|
|||
|
|
/// 回收成功返回true。
|
|||
|
|
virtual bool RecoveryResource(IVzPoolElement* pIElement) = 0;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 元素池
|
|||
|
|
template<typename T>
|
|||
|
|
class IVzPool : public IVzPoolUnknown
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
/// @brief
|
|||
|
|
/// 获取一个元素对象
|
|||
|
|
/// <param name = "nTimeOut">[in]超时时间</param>
|
|||
|
|
/// <param name = "ppIElement">[out]输出元素。</param>
|
|||
|
|
/// @reutrn 是否成功分配内存块
|
|||
|
|
virtual bool QueryPoolElement(unsigned int nTimeOut, void* pParam, T** ppIElement) = 0;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 元素基类
|
|||
|
|
class IVzPoolElement : public IVzUnknown
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
IVzPoolElement():m_pIParent(nullptr){}
|
|||
|
|
public:
|
|||
|
|
/// @brief
|
|||
|
|
/// 清除资源信息
|
|||
|
|
virtual void ClearResource() = 0;
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 释放
|
|||
|
|
virtual int Release()
|
|||
|
|
{
|
|||
|
|
int nRef = std::atomic_fetch_sub(&m_nReferenceCount, (unsigned int)1);
|
|||
|
|
if (2 == nRef)
|
|||
|
|
{
|
|||
|
|
if (m_pIParent)
|
|||
|
|
m_pIParent->RecoveryResource(this);
|
|||
|
|
}
|
|||
|
|
else if (1 == nRef)
|
|||
|
|
{
|
|||
|
|
delete this;
|
|||
|
|
}
|
|||
|
|
return (nRef - 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public:
|
|||
|
|
/// @brief
|
|||
|
|
/// 设置Element的Parent
|
|||
|
|
virtual void SetParent(IVzPoolUnknown* pIParent){m_pIParent = pIParent;}
|
|||
|
|
|
|||
|
|
protected:
|
|||
|
|
IVzPoolUnknown* m_pIParent;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeAddRef(T* pUnknown)
|
|||
|
|
{
|
|||
|
|
if (nullptr == pUnknown)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
pUnknown->AddRef();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeAddRef(std::vector<T*>& vecTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::vector<T*>::iterator it = vecTemplate.begin();
|
|||
|
|
while(it != vecTemplate.end())
|
|||
|
|
{
|
|||
|
|
T* pUnknown = (*it);
|
|||
|
|
if (pUnknown)
|
|||
|
|
{
|
|||
|
|
pUnknown->AddRef();
|
|||
|
|
}
|
|||
|
|
it++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeAddRef(std::list<T*>& listTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::list<T*>::iterator it = listTemplate.begin();
|
|||
|
|
while (it != listTemplate.end())
|
|||
|
|
{
|
|||
|
|
T* pUnknown = (*it);
|
|||
|
|
if (pUnknown)
|
|||
|
|
{
|
|||
|
|
VzSafeAddRef(pUnknown);
|
|||
|
|
}
|
|||
|
|
it++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeAddRef(std::set<T*>& listTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::set<T*>::iterator it = listTemplate.begin();
|
|||
|
|
while (it != listTemplate.end())
|
|||
|
|
{
|
|||
|
|
T* pUnknown = (*it);
|
|||
|
|
if (pUnknown)
|
|||
|
|
{
|
|||
|
|
VzSafeAddRef(pUnknown);
|
|||
|
|
}
|
|||
|
|
it++;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeRelease(T** ppUnknown)
|
|||
|
|
{
|
|||
|
|
if (nullptr == ppUnknown)
|
|||
|
|
return;
|
|||
|
|
if (nullptr == *ppUnknown)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
(*ppUnknown)->Release();
|
|||
|
|
*ppUnknown = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeRelease(std::vector<T*>& vecTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::vector<T*>::iterator it = vecTemplate.begin();
|
|||
|
|
while(it != vecTemplate.end())
|
|||
|
|
{
|
|||
|
|
T* pUnknown = (*it);
|
|||
|
|
VzSafeRelease(&pUnknown);
|
|||
|
|
it++;
|
|||
|
|
}
|
|||
|
|
vecTemplate.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename TKey, typename TValue>
|
|||
|
|
inline void VzSafeRelease(std::map<TKey, TValue*>& mapTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::map<TKey, TValue*>::iterator itMap = mapTemplate.begin();
|
|||
|
|
while(itMap != mapTemplate.end())
|
|||
|
|
{
|
|||
|
|
TValue* pUnknown = itMap->second;
|
|||
|
|
VzSafeRelease(&pUnknown);
|
|||
|
|
itMap++;
|
|||
|
|
}
|
|||
|
|
mapTemplate.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeRelease(std::set<T*>& setTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::set<T*>::iterator it = setTemplate.begin();
|
|||
|
|
while(it != setTemplate.end())
|
|||
|
|
{
|
|||
|
|
T* pUnknown = (*it);
|
|||
|
|
VzSafeRelease(&pUnknown);
|
|||
|
|
it++;
|
|||
|
|
}
|
|||
|
|
setTemplate.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeRelease(std::list<T*>& listTemplate)
|
|||
|
|
{
|
|||
|
|
typename std::list<T*>::iterator it = listTemplate.begin();
|
|||
|
|
while(it != listTemplate.end())
|
|||
|
|
{
|
|||
|
|
T* pUnknown = (*it);
|
|||
|
|
VzSafeRelease(&pUnknown);
|
|||
|
|
it++;
|
|||
|
|
}
|
|||
|
|
listTemplate.clear();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeRelease(std::queue<T*>& queTemplate)
|
|||
|
|
{
|
|||
|
|
while (false == queTemplate.empty())
|
|||
|
|
{
|
|||
|
|
T* pElement = queTemplate.front();
|
|||
|
|
queTemplate.pop();
|
|||
|
|
VzSafeRelease(&pElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeRelease(std::deque<T*>& queTemplate)
|
|||
|
|
{
|
|||
|
|
while (false == queTemplate.empty())
|
|||
|
|
{
|
|||
|
|
T* pElement = queTemplate.front();
|
|||
|
|
queTemplate.pop_front();
|
|||
|
|
VzSafeRelease(&pElement);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeDeleteObject(T** ppObject)
|
|||
|
|
{
|
|||
|
|
if (nullptr == ppObject)
|
|||
|
|
return;
|
|||
|
|
if (nullptr == *ppObject)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
delete (*ppObject);
|
|||
|
|
*ppObject = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<typename T>
|
|||
|
|
inline void VzSafeDeleteArray(T** ppArray)
|
|||
|
|
{
|
|||
|
|
if (nullptr == ppArray)
|
|||
|
|
return;
|
|||
|
|
if (nullptr == *ppArray)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
delete[] (*ppArray);
|
|||
|
|
*ppArray = nullptr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
inline void VzSafeCloseHandle(HANDLE* phHandle)
|
|||
|
|
{
|
|||
|
|
if (nullptr == phHandle)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (nullptr == *phHandle)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
CloseHandle(*phHandle);
|
|||
|
|
|
|||
|
|
*phHandle = nullptr;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
|
|||
|
|
/// @brief
|
|||
|
|
/// 定义延时函数
|
|||
|
|
inline void VzSleep(unsigned int nMs)
|
|||
|
|
{
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
Sleep(nMs);
|
|||
|
|
#else
|
|||
|
|
usleep(1000 * nMs);
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 定义延时函数
|
|||
|
|
inline void VzUSleep(unsigned int nMs)
|
|||
|
|
{
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
LARGE_INTEGER lStart, lCur, lFreq;
|
|||
|
|
QueryPerformanceFrequency(&lFreq);
|
|||
|
|
QueryPerformanceCounter(&lStart);
|
|||
|
|
double dTakeTime = 0;
|
|||
|
|
do {
|
|||
|
|
QueryPerformanceCounter(&lCur);
|
|||
|
|
dTakeTime = (double)(lCur.QuadPart - lStart.QuadPart) * 1000 / (double)lFreq.QuadPart;
|
|||
|
|
} while (dTakeTime < nMs);
|
|||
|
|
#else
|
|||
|
|
usleep(1000 * nMs);
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// @brief 安全拷贝
|
|||
|
|
inline void _vzstrcpy(char* szDest, unsigned int nDestLenth, const char* szSrc)
|
|||
|
|
{
|
|||
|
|
if (nullptr == szDest || 0 == nDestLenth || nullptr == szSrc)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
#ifdef _MSC_VER
|
|||
|
|
strcpy_s(szDest, nDestLenth, szSrc);
|
|||
|
|
#else
|
|||
|
|
strncpy(szDest, szSrc, nDestLenth);
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// @brief 安全sscanf
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
#define _vzscanf sscanf_s
|
|||
|
|
#else
|
|||
|
|
#define _vzscanf sscanf
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/// @brief 安全格式化
|
|||
|
|
inline void _vzsprintf( char* pszOutput,
|
|||
|
|
unsigned int nOutputLength,
|
|||
|
|
const char* lpszFormat,
|
|||
|
|
...)
|
|||
|
|
{
|
|||
|
|
va_list args;
|
|||
|
|
va_start(args, lpszFormat);
|
|||
|
|
#ifdef _WIN32
|
|||
|
|
vsprintf_s(pszOutput, nOutputLength, lpszFormat, args);
|
|||
|
|
#else
|
|||
|
|
vsprintf(pszOutput, lpszFormat, args);
|
|||
|
|
#endif
|
|||
|
|
va_end(args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#define VZ_FALSE_BREAK(_condition) if (false == (_condition)) { VZASSERT(false); break; }
|
|||
|
|
#define VZ_FALSE_BREAK_WITHLOG(_condition, _log) if (false == (_condition)) { VZASSERT(false); LOG_ERR(_log);break; }
|
|||
|
|
#define VZ_FALSE_BREAK_NOASSERT(_condition) if (false == (_condition)) { break; }
|
|||
|
|
#define VZ_FALSE_BREAK_ERRCODE(_condition, _varerr, _errcode) if (false == (_condition)) { _varerr = _errcode; break;}
|
|||
|
|
#define VZ_FALSE_BREAK_ERRCODE_WITHLOG(_condition, _varerr, _errcode, _log) if (false == (_condition)) { _varerr = _errcode; LOG_ERR(_log); VZASSERT(false); break;}
|
|||
|
|
|
|||
|
|
#endif //__VIZUM_HELPER_HEADER__
|