27 #ifndef _AK_PLATFORM_FUNCS_H_
28 #define _AK_PLATFORM_FUNCS_H_
30 #if !defined(WIN32_LEAN_AND_MEAN)
31 #define WIN32_LEAN_AND_MEAN
69 #define AK_DECLARE_THREAD_ROUTINE( FuncName ) DWORD WINAPI FuncName(LPVOID lpParameter)
70 #define AK_THREAD_RETURN( _param_ ) return (_param_);
71 #define AK_THREAD_ROUTINE_PARAMETER lpParameter
72 #define AK_GET_THREAD_ROUTINE_PARAMETER_PTR(type) reinterpret_cast<type*>( AK_THREAD_ROUTINE_PARAMETER )
73 #define AK_RETURN_THREAD_OK 0x00000000
74 #define AK_RETURN_THREAD_ERROR 0x00000001
75 #define AK_DEFAULT_STACK_SIZE (128*1024)
76 #define AK_THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
77 #define AK_THREAD_PRIORITY_ABOVE_NORMAL THREAD_PRIORITY_ABOVE_NORMAL
78 #define AK_THREAD_PRIORITY_BELOW_NORMAL THREAD_PRIORITY_BELOW_NORMAL
79 #define AK_THREAD_PRIORITY_TIME_CRITICAL THREAD_PRIORITY_TIME_CRITICAL
80 #define AK_THREAD_MODE_BACKGROUND_BEGIN THREAD_MODE_BACKGROUND_BEGIN
83 #define AK_NULL_THREAD NULL
85 #define AK_INFINITE INFINITE
87 #define AkMax(x1, x2) (((x1) > (x2))? (x1): (x2))
88 #define AkMin(x1, x2) (((x1) < (x2))? (x1): (x2))
89 #define AkClamp(x, min, max) ((x) < (min)) ? (min) : (((x) > (max) ? (max) : (x)))
105 out_event = ::CreateEvent(
NULL,
117 ::CloseHandle( io_event );
124 AKVERIFY( ::WaitForSingleObject( in_event, INFINITE ) == WAIT_OBJECT_0 );
142 out_semaphore = ::CreateSemaphore(
153 ::CloseHandle(io_semaphore);
159 AKVERIFY(::WaitForSingleObject(in_semaphore, INFINITE) == WAIT_OBJECT_0);
165 AKVERIFY(ReleaseSemaphore(in_semaphore, in_count,
NULL) >= 0);
188 AKVERIFY( ::CloseHandle( *in_pThread ) );
192 #define AkExitThread( _result ) return _result;
206 const DWORD MS_VC_EXCEPTION=0x406D1388;
209 typedef struct tagTHREADNAME_INFO
218 THREADNAME_INFO info;
219 info.dwType = 0x1000;
220 info.szName = in_szThreadName;
221 info.dwThreadID = in_dwThreadID;
226 RaiseException( MS_VC_EXCEPTION, 0,
sizeof(info)/
sizeof(ULONG_PTR), (ULONG_PTR*)&info );
228 #pragma warning(suppress: 6312 6322)
229 __except(EXCEPTION_CONTINUE_EXECUTION)
233 #if defined(AK_XBOX) || defined(_GAMING_DESKTOP) // also applicable on Windows when Win7 support is dropped. SetThreadDescription is a Win10 only API
234 wchar_t wszThreadName[32];
235 AkUInt32 maxStrLen = (
sizeof(wszThreadName) /
sizeof(
wchar_t)) - 1;
236 AkUInt32 nameStrLen =
AkMin((
int)strlen(in_szThreadName), maxStrLen);
237 MultiByteToWideChar(CP_UTF8, 0, in_szThreadName, nameStrLen, wszThreadName, maxStrLen);
238 wszThreadName[nameStrLen] =
'\0';
239 SetThreadDescription(in_threadHnd, wszThreadName);
249 const char * in_szThreadName )
252 AKASSERT( (in_threadProperties.
nPriority >= THREAD_PRIORITY_LOWEST && in_threadProperties.
nPriority <= THREAD_PRIORITY_HIGHEST)
253 || ( in_threadProperties.
nPriority == THREAD_PRIORITY_TIME_CRITICAL )
254 || ( in_threadProperties.
nPriority == THREAD_MODE_BACKGROUND_BEGIN ) );
257 *out_pThread = ::CreateThread(
NULL,
278 if ( !::SetThreadPriority( *out_pThread, in_threadProperties.
nPriority ) &&
279 in_threadProperties.
nPriority != THREAD_MODE_BACKGROUND_BEGIN )
281 AKASSERT( !
"Failed setting thread priority" );
289 DWORD_PTR procAffinity, sysAffinity;
290 if (::GetProcessAffinityMask(::GetCurrentProcess(), &procAffinity, &sysAffinity))
293 dwAffinityMask &= procAffinity;
295 if (!::SetThreadAffinityMask(*out_pThread, dwAffinityMask))
297 AKASSERT(!
"Failed setting thread affinity mask");
305 if (!::ResumeThread(*out_pThread))
307 AKASSERT(!
"Failed to start the thread");
319 ::WaitForSingleObject( *in_pThread, INFINITE );
325 return ::GetCurrentThreadId();
331 ::Sleep( in_ulMilliseconds );
340 ::QueryPerformanceCounter( (LARGE_INTEGER*)out_piLastTime );
346 ::QueryPerformanceFrequency( (LARGE_INTEGER*)out_piFreq );
366 char* io_pszAnsiString )
368 if(!io_pszAnsiString)
369 return WideCharToMultiByte(CP_UTF8, 0, in_pszUnicodeString, -1,
NULL, 0,
NULL,
NULL);
371 int iWritten = ::WideCharToMultiByte(CP_UTF8,
374 (
int)
AkMin( ( (
AkUInt32)wcslen( in_pszUnicodeString )), in_uiOutBufferSize-1 ),
379 io_pszAnsiString[iWritten] = 0;
386 void* io_pvUnicodeStringBuffer )
388 return ::MultiByteToWideChar( CP_UTF8,
392 (
wchar_t*)io_pvUnicodeStringBuffer,
399 void* io_pvUnicodeStringBuffer )
401 return ::MultiByteToWideChar( CP_UTF8,
405 (
wchar_t*)io_pvUnicodeStringBuffer,
410 inline void SafeStrCpy(
wchar_t * in_pDest,
const wchar_t* in_pSrc,
size_t in_uDestMaxNumChars )
412 size_t iSizeCopy =
AkMin( in_uDestMaxNumChars - 1, wcslen( in_pSrc ) + 1 );
413 wcsncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy );
414 in_pDest[iSizeCopy] =
'\0';
418 inline void SafeStrCpy(
char * in_pDest,
const char* in_pSrc,
size_t in_uDestMaxNumChars )
420 size_t iSizeCopy =
AkMin( in_uDestMaxNumChars - 1, strlen( in_pSrc ) + 1 );
421 strncpy_s( in_pDest, in_uDestMaxNumChars, in_pSrc, iSizeCopy );
422 in_pDest[iSizeCopy] =
'\0';
426 inline void SafeStrCat(
wchar_t * in_pDest,
const wchar_t* in_pSrc,
size_t in_uDestMaxNumChars )
428 int iAvailableSize = (int)( in_uDestMaxNumChars - wcslen( in_pDest ) - 1 );
429 wcsncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc,
AkMin( iAvailableSize, (
int)wcslen( in_pSrc ) ) );
433 inline void SafeStrCat(
char * in_pDest,
const char* in_pSrc,
size_t in_uDestMaxNumChars )
435 int iAvailableSize = (int)( in_uDestMaxNumChars - strlen( in_pDest ) - 1 );
436 strncat_s( in_pDest, in_uDestMaxNumChars, in_pSrc,
AkMin( iAvailableSize, (
int)strlen( in_pSrc ) ) );
439 inline int SafeStrFormat(
wchar_t * in_pDest,
size_t in_uDestMaxNumChars,
const wchar_t* in_pszFmt, ...)
442 va_start(args, in_pszFmt);
443 int r = vswprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
448 inline int SafeStrFormat(
char * in_pDest,
size_t in_uDestMaxNumChars,
const char* in_pszFmt, ...)
451 va_start(args, in_pszFmt);
452 int r = vsnprintf(in_pDest, in_uDestMaxNumChars, in_pszFmt, args);
458 #define AkAlloca( _size_ ) _alloca( _size_ )
461 #if ! defined(AK_OPTIMIZED)
464 OutputDebugStringW( in_pszMsg );
470 OutputDebugStringA( in_pszMsg );
477 template <
int MaxSize = 256>
484 wchar_t* msg = (
wchar_t*)
AkAlloca(MaxSize *
sizeof(
wchar_t));
485 msg[MaxSize - 1] =
'\0';
488 va_start(args, in_pszFmt);
489 vswprintf(msg, MaxSize, in_pszFmt, args);
499 template <
int MaxSize = 256>
506 msg[MaxSize - 1] =
'\0';
509 va_start(args, in_pszFmt);
510 size = vsnprintf(msg, MaxSize, in_pszFmt, args);
514 if (0 <= size && size <= MaxSize)
526 char* msg = (
char*)
AkAlloca((size) *
sizeof(char));
527 msg[size - 1] =
'\0';
530 va_start(args, in_pszFmt);
531 vsnprintf(msg, size, in_pszFmt, args);
542 template <
int MaxSize = 0>
545 template <
int MaxSize = 0>
557 #define CONVERT_WIDE_TO_OSCHAR( _wstring_, _oscharstring_ ) ( _oscharstring_ ) = (AkOSChar*)( _wstring_ )
567 #define CONVERT_CHAR_TO_OSCHAR( _astring_, _oscharstring_ ) \
568 _oscharstring_ = (AkOSChar*)AkAlloca( (1 + strlen( _astring_ )) * sizeof(AkOSChar)); \
569 AKPLATFORM::AkCharToWideChar( _astring_, (AkUInt32)(1 + strlen(_astring_ )), (AkOSChar*)( _oscharstring_ ) )
579 #define CONVERT_OSCHAR_TO_WIDE( _osstring_, _wstring_ ) _wstring_ = _osstring_
589 #define CONVERT_OSCHAR_TO_CHAR( _osstring_, _astring_ ) \
590 _astring_ = (char*)AkAlloca( 1 + AKPLATFORM::AkWideCharToChar( _osstring_, 0, NULL )); \
591 AKPLATFORM::AkWideCharToChar( _osstring_, AkUInt32(1 + AKPLATFORM::AkWideCharToChar( _osstring_, 0, NULL )), _astring_ );
597 return ( wcslen( in_pStr ) );
604 return ( wcslen( in_pszString ) );
608 #define AK_OSPRINTF swprintf_s
618 return ( wcscmp( in_pszString1, in_pszString2 ) );
629 return wcsncmp(in_pszString1, in_pszString2, in_MaxCountSize);
632 #define AK_UTF16_TO_WCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
633 #define AK_WCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
634 #define AK_UTF8_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
635 #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
636 #define AK_UTF16_TO_CHAR( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkWideCharToChar( in_pSrc, in_MaxSize, in_pdDest )
637 #define AK_CHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::AkCharToWideChar( in_pSrc, in_MaxSize, in_pdDest )
638 #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize ) AKPLATFORM::SafeStrCpy( in_pdDest, in_pSrc, in_MaxSize )
644 (in_pathLen >= 3 && in_pszPath[1] ==
':' && in_pszPath[2] ==
'\\') ||
645 (in_pathLen >= 2 && in_pszPath[0] ==
'\\');
649 #define AK_PATH_SEPARATOR L"\\"
650 #define AK_LIBRARY_PREFIX L""
651 #define AK_DYNAMIC_LIBRARY_EXTENSION L".dll"
653 #define AK_FILEHANDLE_TO_UINTPTR(_h) ((AkUIntPtr)_h)
654 #define AK_SET_FILEHANDLE_TO_UINTPTR(_h,_u) _h = (AkFileHandle)_u
658 #endif // _AK_PLATFORM_FUNCS_H_