DqnTimer unix implementation

This commit is contained in:
Doyle Thai 2017-06-22 18:10:44 +10:00
parent f464e869ec
commit 187fc14d02
2 changed files with 462 additions and 369 deletions

175
dqn.h
View File

@ -18,7 +18,7 @@
// You can search by #<entry> to jump straight to the section. // You can search by #<entry> to jump straight to the section.
// The first match is the public API, the next matche(s) are the implementation // The first match is the public API, the next matche(s) are the implementation
// API > Portable Code // #Portable Code
// #DqnAssert Assertions // #DqnAssert Assertions
// #DqnMem Memory Allocation // #DqnMem Memory Allocation
// #DqnMemStack Memory Allocator, Push, Pop Style // #DqnMemStack Memory Allocator, Push, Pop Style
@ -36,18 +36,19 @@
// #DqnWStr WStr Operations (WStr_Len() etc) // #DqnWStr WStr Operations (WStr_Len() etc)
// #DqnRnd Random Number Generator (ints and floats) // #DqnRnd Random Number Generator (ints and floats)
// API > Cross Platform Code // #XPlatform (Win32 & Unix)
// #DqnFile File I/O (Read, Write, Delete) // #DqnFile File I/O (Read, Write, Delete)
// #DqnDir Directory Querying // #DqnDir Directory Querying
// #DqnTimer High Resolution Timer
// API > Win32 Only // #Platform
// #DqnTime Platform High Resolution Timer // - #Win32Platform
// #DqnLock Mutex Synchronisation // - #DqnLock Mutex Synchronisation
// #DqnAtomic Interlocks/Atomic Operations // - #DqnAtomic Interlocks/Atomic Operations
// #DqnJobQueue Multithreaded Job Queue // - #DqnJobQueue Multithreaded Job Queue
// #DqnWin32 Common Win32 API Helpers // - #DqnWin32 Common Win32 API Helpers
// API > External Code // #External Code
// #DqnIni Simple INI Config File API (Public Domain lib by Mattias Gustavsson) // #DqnIni Simple INI Config File API (Public Domain lib by Mattias Gustavsson)
// #DqnSprintf Cross-platform Sprintf Implementation (Public Domain lib stb_sprintf) // #DqnSprintf Cross-platform Sprintf Implementation (Public Domain lib stb_sprintf)
@ -58,15 +59,15 @@
// a platform implementation, platform specific implementations in the portable // a platform implementation, platform specific implementations in the portable
// layer will get activated. // layer will get activated.
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION) #if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
#define DQN_PLATFORM_LAYER #define DQN_XPLATFORM_LAYER
#define DQN_WIN32_PLATFORM #define DQN_WIN32_PLATFORM
#elif defined(__linux__) && defined(DQN_UNIX_IMPLEMENTATION) #elif defined(__linux__) && defined(DQN_UNIX_IMPLEMENTATION)
#define DQN_PLATFORM_LAYER #define DQN_XPLATFORM_LAYER
#define DQN_UNIX_PLATFORM #define DQN_UNIX_PLATFORM
#endif #endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Portable Layer // #Portable Code
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifndef DQN_H #ifndef DQN_H
#define DQN_H #define DQN_H
@ -893,26 +894,13 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max);
#endif /* DQN_H */ #endif /* DQN_H */
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Cross-Platform Layer // #XPlatform (Win32 & Unix) Public API
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Functions in the Cross Platform are guaranteed to be supported in both Unix // Functions in the Cross Platform are guaranteed to be supported in both Unix
// and Win32 // and Win32
#ifdef DQN_PLATFORM_LAYER #ifdef DQN_XPLATFORM_LAYER
#ifdef DQN_WIN32_PLATFORM
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#ifdef DQN_UNIX_PLATFORM
#include <sys/stat.h>
#include <stdio.h> // Basic File I/O // TODO(doyle): Syscall versions
#include <unistd.h> // unlink()
#include <dirent.h> // readdir()/opendir()/closedir()
#endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Cross-Platform > #DqnFile Public API - File I/O // XPlatform > #DqnFile Public API - File I/O
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
enum DqnFilePermissionFlag enum DqnFilePermissionFlag
{ {
@ -964,6 +952,9 @@ DQN_FILE_SCOPE void DqnFile_Close(DqnFile *const file);
DQN_FILE_SCOPE bool DqnFile_Delete (const char *const path); DQN_FILE_SCOPE bool DqnFile_Delete (const char *const path);
DQN_FILE_SCOPE bool DqnFile_DeleteW(const wchar_t *const path); DQN_FILE_SCOPE bool DqnFile_DeleteW(const wchar_t *const path);
////////////////////////////////////////////////////////////////////////////////
// XPlatform > #DqnDir Public API - Directory Querying
////////////////////////////////////////////////////////////////////////////////
// numFiles: Pass in a pointer to a u32. The function fills it out with the number of entries. // numFiles: Pass in a pointer to a u32. The function fills it out with the number of entries.
// return: An array of strings of the files in the directory in UTF-8. The directory lisiting is // return: An array of strings of the files in the directory in UTF-8. The directory lisiting is
// allocated with malloc and must be freed using free() or the helper function DqnDir_ReadFree() // allocated with malloc and must be freed using free() or the helper function DqnDir_ReadFree()
@ -971,20 +962,27 @@ DQN_FILE_SCOPE char **DqnDir_Read (const char *const dir, u32 *const numFiles
DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles); DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform Layer // XPlatform > #DqnTimer Public API - High Resolution Timer
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE f64 DqnTimer_NowInMs();
DQN_FILE_SCOPE f64 DqnTimer_NowInS ();
#endif // DQN_XPLATFORM_LAYER
////////////////////////////////////////////////////////////////////////////////
// #Platform Public API
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Functions here are only available for the #defined sections (i.e. all functions in // Functions here are only available for the #defined sections (i.e. all functions in
// DQN_WIN32_PLATFORM only have a valid implementation in Win32. // DQN_WIN32_PLATFORM only have a valid implementation in Win32.
////////////////////////////////////////////////////////////////////////////////
// #Win32Platform Public API
////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM #ifdef DQN_WIN32_PLATFORM
//////////////////////////////////////////////////////////////////////////////// #define WIN32_LEAN_AND_MEAN
// Platform > Win32 > #DqnTimer Public API - High Resolution Timer #include <Windows.h>
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE f64 DqnTime_NowInS();
DQN_FILE_SCOPE f64 DqnTime_NowInMs();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnLock Public API - Mutex Synchronisation // Win32Platform > #DqnLock Public API - Mutex Synchronisation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef struct DqnLock typedef struct DqnLock
{ {
@ -997,14 +995,14 @@ DQN_FILE_SCOPE void DqnLock_Release(DqnLock *const lock);
DQN_FILE_SCOPE void DqnLock_Delete (DqnLock *const lock); DQN_FILE_SCOPE void DqnLock_Delete (DqnLock *const lock);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnAtomic Public API - Interlocks/Atomic Operations // Win32Platform > #DqnAtomic Public API - Interlocks/Atomic Operations
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *dest, u32 swapVal, u32 compareVal); DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *dest, u32 swapVal, u32 compareVal);
DQN_FILE_SCOPE u32 DqnAtomic_Add32 (u32 volatile *src); DQN_FILE_SCOPE u32 DqnAtomic_Add32 (u32 volatile *src);
DQN_FILE_SCOPE u32 DqnAtomic_Sub32 (u32 volatile *src); DQN_FILE_SCOPE u32 DqnAtomic_Sub32 (u32 volatile *src);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueue Public API - Multithreaded Job Queue // Win32Platform > #DqnJobQueue Public API - Multithreaded Job Queue
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// DqnJobQueue is a platform abstracted "lockless" multithreaded work queue. It will create threads // DqnJobQueue is a platform abstracted "lockless" multithreaded work queue. It will create threads
// and assign threads to complete the job via the job "callback" using the "userData" supplied. // and assign threads to complete the job via the job "callback" using the "userData" supplied.
@ -1082,14 +1080,9 @@ DQN_FILE_SCOPE i32 DqnWin32_GetEXEDirectory(char *const buf, const u32 bufLen);
DQN_FILE_SCOPE void DqnWin32_GetNumThreadsAndCores(i32 *const numCores, i32 *const numThreadsPerCore); DQN_FILE_SCOPE void DqnWin32_GetNumThreadsAndCores(i32 *const numCores, i32 *const numThreadsPerCore);
#endif // DQN_WIN32_PLATFORM #endif // DQN_WIN32_PLATFORM
#ifdef DQN_UNIX_PLATFORM
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Unix // #External Code
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#endif
#endif // DQN_PLATFORM_LAYER
#ifndef DQN_INI_H #ifndef DQN_INI_H
#define DQN_INI_H #define DQN_INI_H
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -3657,6 +3650,9 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max)
return min + value; return min + value;
} }
////////////////////////////////////////////////////////////////////////////////
// #External Code
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// #DqnSprintf Implementation - STB_Sprintf // #DqnSprintf Implementation - STB_Sprintf
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -5349,14 +5345,24 @@ void DqnIni_PropertyValueSet(DqnIni *ini, int section, int property,
#endif #endif
#endif // DQN_IMPLEMENTATION #endif // DQN_IMPLEMENTATION
#if defined(DQN_XPLATFORM_LAYER)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Cross-Platform Layer // #XPlatform (Win32 & Unix) Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Functions in the Cross Platform are guaranteed to be supported in both Unix // Functions in the Cross Platform are guaranteed to be supported in both Unix
// and Win32 // and Win32
#ifdef DQN_UNIX_PLATFORM
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <stdio.h> // Basic File I/O // TODO(doyle): Syscall versions
#include <unistd.h> // unlink()
#include <dirent.h> // readdir()/opendir()/closedir()
#endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Cross-Platform > #DqnFileInternal Implementation // XPlatform > #DqnFileInternal Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM #ifdef DQN_WIN32_PLATFORM
FILE_SCOPE bool DqnFileInternal_Win32OpenW(const wchar_t *const path, FILE_SCOPE bool DqnFileInternal_Win32OpenW(const wchar_t *const path,
@ -5645,7 +5651,7 @@ DQN_FILE_SCOPE char **DqnDirInternal_PlatformRead(const char *const dir,
#endif // DQN_UNIX_PLATFORM #endif // DQN_UNIX_PLATFORM
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Cross-Platform > #DqnFile Implementation // XPlatform > #DqnFile Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE DQN_FILE_SCOPE
bool DqnFile_Open(const char *const path, DqnFile *const file, bool DqnFile_Open(const char *const path, DqnFile *const file,
@ -5674,7 +5680,7 @@ bool DqnFile_OpenW(const wchar_t *const path, DqnFile *const file, const u32 per
{ {
if (!file || !path) return false; if (!file || !path) return false;
#ifdef DQN_WIN32_PLATFORM #if defined(DQN_WIN32_PLATFORM)
return DqnFileInternal_Win32OpenW(path, file, permissionFlags, action); return DqnFileInternal_Win32OpenW(path, file, permissionFlags, action);
#else #else
DQN_ASSERT(DQN_INVALID_CODE_PATH); DQN_ASSERT(DQN_INVALID_CODE_PATH);
@ -5780,7 +5786,7 @@ DQN_FILE_SCOPE bool DqnFile_Delete(const char *const path)
// TODO(doyle): Logging // TODO(doyle): Logging
#if defined(DQN_WIN32_PLATFORM) #if defined(DQN_WIN32_PLATFORM)
return DeleteFile(path); return DeleteFileA(path);
#elif defined(DQN_UNIX_PLATFORM) #elif defined(DQN_UNIX_PLATFORM)
i32 result = unlink(path); i32 result = unlink(path);
@ -5791,6 +5797,9 @@ DQN_FILE_SCOPE bool DqnFile_Delete(const char *const path)
#endif #endif
} }
////////////////////////////////////////////////////////////////////////////////
// XPlatform > #DqnDir Implementation
////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE char **DqnDir_Read(const char *const dir, u32 *const numFiles) DQN_FILE_SCOPE char **DqnDir_Read(const char *const dir, u32 *const numFiles)
{ {
char **result = DqnDirInternal_PlatformRead(dir, numFiles); char **result = DqnDirInternal_PlatformRead(dir, numFiles);
@ -5812,13 +5821,10 @@ DQN_FILE_SCOPE void DqnDir_ReadFree(char **fileList, u32 numFiles)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform Layer // XPlatform > #DqnTimer Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM #if defined (DQN_WIN32_PLATFORM)
//////////////////////////////////////////////////////////////////////////////// FILE_SCOPE f64 DqnTimerInternal_Win32QueryPerfCounterTimeInMs()
// Platform > Win32 > #DqnTimer Implementation
////////////////////////////////////////////////////////////////////////////////
FILE_SCOPE f64 DqnTimeInternal_Win32QueryPerfCounterTimeInS()
{ {
LOCAL_PERSIST LARGE_INTEGER queryPerformanceFrequency = {0}; LOCAL_PERSIST LARGE_INTEGER queryPerformanceFrequency = {0};
if (queryPerformanceFrequency.QuadPart == 0) if (queryPerformanceFrequency.QuadPart == 0)
@ -5830,28 +5836,53 @@ FILE_SCOPE f64 DqnTimeInternal_Win32QueryPerfCounterTimeInS()
LARGE_INTEGER qpcResult; LARGE_INTEGER qpcResult;
QueryPerformanceCounter(&qpcResult); QueryPerformanceCounter(&qpcResult);
// Convert to ms // Convert to microseconds first then divide by ticks per second then to milliseconds
f64 timestamp = qpcResult.QuadPart *= 1000000;
qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart; f64 timestamp = qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart;
timestamp /= 1000.0f;
return timestamp; return timestamp;
} }
#endif
f64 DqnTime_NowInS() DQN_FILE_SCOPE f64 DqnTimer_NowInMs()
{ {
f64 result; f64 result = 0;
#ifdef DQN_WIN32_PLATFORM #if defined(DQN_WIN32_PLATFORM)
result = DQN_MAX(DqnTimeInternal_Win32QueryPerfCounterTimeInS(), 0); result = DQN_MAX(DqnTimerInternal_Win32QueryPerfCounterTimeInMs(), 0);
#elif defined(DQN_UNIX_PLATFORM)
struct timespec timeSpec = {0};
if (clock_gettime(CLOCK_MONOTONIC, &timeSpec))
{
// TODO(doyle): Failed logging
DQN_ASSERT_HARD(DQN_INVALID_CODE_PATH);
}
else
{
printf("tv_nsec: %ld\n", timeSpec.tv_nsec);
result = ((f64)timeSpec.tv_sec * 1000.0f) + ((f64)timeSpec.tv_nsec / 100000.0f);
}
#else #else
result = 0; DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Unix/Win32 path not implemented yet");
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented yet");
#endif #endif
return result; return result;
}; };
f64 DqnTime_NowInMs() { return DqnTime_NowInS() * 1000.0f; } DQN_FILE_SCOPE f64 DqnTimer_NowInS() { return DqnTimer_NowInMs() / 1000.0f; }
#endif // DQN_XPLATFORM_LAYER
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnLock Implementation // #Platform Implementation
////////////////////////////////////////////////////////////////////////////////
#ifdef DQN_WIN32_PLATFORM
////////////////////////////////////////////////////////////////////////////////
// #Win32Platform Implementation
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Win32Platform > #DqnLock Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool DqnLock_Init(DqnLock *const lock, const u32 spinCount) bool DqnLock_Init(DqnLock *const lock, const u32 spinCount)
{ {
@ -5896,7 +5927,7 @@ void DqnLock_Delete(DqnLock *const lock)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnAtomic Implementation // Win32Platform > #DqnAtomic Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *dest, u32 swapVal, u32 compareVal) DQN_FILE_SCOPE u32 DqnAtomic_CompareSwap32(u32 volatile *dest, u32 swapVal, u32 compareVal)
{ {
@ -5936,7 +5967,7 @@ DQN_FILE_SCOPE u32 DqnAtomic_Sub32(u32 volatile *src)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueue Implementation // Win32Platform > #DqnJobQueue Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
typedef struct DqnJobQueue typedef struct DqnJobQueue
{ {
@ -5953,7 +5984,7 @@ typedef struct DqnJobQueue
} DqnJobQueue; } DqnJobQueue;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueueInternal Implementation // Win32Platform > #DqnJobQueueInternal Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
size_t DQN_JOB_QUEUE_INTERNAL_THREAD_DEFAULT_STACK_SIZE = 0; size_t DQN_JOB_QUEUE_INTERNAL_THREAD_DEFAULT_STACK_SIZE = 0;
FILE_SCOPE u32 DqnJobQueueInternal_ThreadCreate(const size_t stackSize, void *threadCallback, FILE_SCOPE u32 DqnJobQueueInternal_ThreadCreate(const size_t stackSize, void *threadCallback,
@ -5998,7 +6029,7 @@ FILE_SCOPE u32 DqnJobQueueInternal_ThreadCallback(void *threadParam)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnJobQueue Implementation // Win32Platform > #DqnJobQueue Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_t *const memSize, DQN_FILE_SCOPE DqnJobQueue *DqnJobQueue_InitWithMem(const void *const mem, size_t *const memSize,
const u32 queueSize, const u32 numThreads) const u32 queueSize, const u32 numThreads)
@ -6095,7 +6126,7 @@ DQN_FILE_SCOPE bool DqnJobQueue_AllJobsComplete(DqnJobQueue *const queue)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Platform > Win32 > #DqnWin32 Implementation // Win32Platform > #DqnWin32 Implementation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
DQN_FILE_SCOPE bool DqnWin32_UTF8ToWChar(const char *const in, DQN_FILE_SCOPE bool DqnWin32_UTF8ToWChar(const char *const in,
wchar_t *const out, const i32 outLen) wchar_t *const out, const i32 outLen)
@ -6182,13 +6213,13 @@ DQN_FILE_SCOPE void DqnWin32_OutputDebugString(const char *const formatStr, ...)
} }
va_end(argList); va_end(argList);
OutputDebugString(str); OutputDebugStringA(str);
} }
DQN_FILE_SCOPE i32 DqnWin32_GetEXEDirectory(char *const buf, const u32 bufLen) DQN_FILE_SCOPE i32 DqnWin32_GetEXEDirectory(char *const buf, const u32 bufLen)
{ {
if (!buf || bufLen == 0) return 0; if (!buf || bufLen == 0) return 0;
u32 copiedLen = GetModuleFileName(NULL, buf, bufLen); u32 copiedLen = GetModuleFileNameA(NULL, buf, bufLen);
if (copiedLen == bufLen) return -1; if (copiedLen == bufLen) return -1;
// NOTE: Should always work if GetModuleFileName works and we're running an // NOTE: Should always work if GetModuleFileName works and we're running an

View File

@ -15,8 +15,8 @@
#define HANDMADE_MATH_CPP_MODE #define HANDMADE_MATH_CPP_MODE
#include "tests/HandmadeMath.h" #include "tests/HandmadeMath.h"
#include <stdio.h>
#include <limits.h> #include <limits.h>
#include <stdio.h>
void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat) void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat)
{ {
f32 *hmmMatf = (f32 *)&hmmMat; f32 *hmmMatf = (f32 *)&hmmMat;
@ -25,21 +25,23 @@ void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat)
const u32 EXPECTED_SIZE = 16; const u32 EXPECTED_SIZE = 16;
u32 totalSize = DQN_ARRAY_COUNT(dqnMat.e) * DQN_ARRAY_COUNT(dqnMat.e[0]); u32 totalSize = DQN_ARRAY_COUNT(dqnMat.e) * DQN_ARRAY_COUNT(dqnMat.e[0]);
DQN_ASSERT(totalSize == EXPECTED_SIZE); DQN_ASSERT(totalSize == EXPECTED_SIZE);
DQN_ASSERT(totalSize == (DQN_ARRAY_COUNT(hmmMat.Elements) * DQN_ARRAY_COUNT(hmmMat.Elements[0]))); DQN_ASSERT(totalSize ==
(DQN_ARRAY_COUNT(hmmMat.Elements) * DQN_ARRAY_COUNT(hmmMat.Elements[0])));
for (u32 i = 0; i < EXPECTED_SIZE; i++) for (u32 i = 0; i < EXPECTED_SIZE; i++)
{ {
const f32 EPSILON = 0.001f; const f32 EPSILON = 0.001f;
f32 diff = hmmMatf[i] - dqnMatf[i]; f32 diff = hmmMatf[i] - dqnMatf[i];
diff = DQN_ABS(diff); diff = DQN_ABS(diff);
DQN_ASSERT_MSG(diff < EPSILON, "hmmMatf[%d]: %f, dqnMatf[%d]: %f\n", i, DQN_ASSERT_MSG(diff < EPSILON, "hmmMatf[%d]: %f, dqnMatf[%d]: %f\n", i, hmmMatf[i], i,
hmmMatf[i], i, dqnMatf[i]); dqnMatf[i]);
} }
} }
void HandmadeMathTest() void HandmadeMathTest()
{ {
// Test Perspective/Projection matrix values // Test Perspective/Projection matrix values
if (1)
{ {
f32 aspectRatio = 1; f32 aspectRatio = 1;
DqnMat4 dqnPerspective = DqnMat4_Perspective(90, aspectRatio, 100, 1000); DqnMat4 dqnPerspective = DqnMat4_Perspective(90, aspectRatio, 100, 1000);
@ -50,6 +52,7 @@ void HandmadeMathTest()
} }
// Test Mat4 translate * scale // Test Mat4 translate * scale
if (1)
{ {
hmm_vec3 hmmVec = HMM_Vec3i(1, 2, 3); hmm_vec3 hmmVec = HMM_Vec3i(1, 2, 3);
DqnV3 dqnVec = DqnV3_3i(1, 2, 3); DqnV3 dqnVec = DqnV3_3i(1, 2, 3);
@ -77,8 +80,8 @@ void HandmadeMathTest()
hmm_mat4 hmmTSMatrix = HMM_MultiplyMat4(hmmTranslate, hmmScale); hmm_mat4 hmmTSMatrix = HMM_MultiplyMat4(hmmTranslate, hmmScale);
HandmadeMathVerifyMat4(dqnTSMatrix, hmmTSMatrix); HandmadeMathVerifyMat4(dqnTSMatrix, hmmTSMatrix);
// Test Mat4 * MulV4 // Test Mat4 * MulV4
if (1)
{ {
DqnV4 dqnV4 = DqnV4_4f(1, 2, 3, 4); DqnV4 dqnV4 = DqnV4_4f(1, 2, 3, 4);
hmm_vec4 hmmV4 = HMM_Vec4(1, 2, 3, 4); hmm_vec4 hmmV4 = HMM_Vec4(1, 2, 3, 4);
@ -91,14 +94,14 @@ void HandmadeMathTest()
DQN_ASSERT(dqnResult.z == hmmResult.Z); DQN_ASSERT(dqnResult.z == hmmResult.Z);
DQN_ASSERT(dqnResult.w == hmmResult.W); DQN_ASSERT(dqnResult.w == hmmResult.W);
printf( printf("HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n");
"HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n");
} }
printf("HandmadeMathTest(): Translate/Scale/Rotate Mat4_Mul: Completed successfully\n"); printf("HandmadeMathTest(): Translate/Scale/Rotate Mat4_Mul: Completed successfully\n");
} }
// Test LookAt/Camera/View matrix returns same results // Test LookAt/Camera/View matrix returns same results
if (1)
{ {
DqnMat4 dqnViewMatrix = DqnMat4_LookAt(DqnV3_3f(4, 3, 3), DqnV3_1f(0), DqnV3_3f(0, 1, 0)); DqnMat4 dqnViewMatrix = DqnMat4_LookAt(DqnV3_3f(4, 3, 3), DqnV3_1f(0), DqnV3_3f(0, 1, 0));
hmm_mat4 hmmViewMatrix = hmm_mat4 hmmViewMatrix =
@ -107,12 +110,13 @@ void HandmadeMathTest()
HandmadeMathVerifyMat4(dqnViewMatrix, hmmViewMatrix); HandmadeMathVerifyMat4(dqnViewMatrix, hmmViewMatrix);
printf("HandmadeMathTest(): LookAt: Completed successfully\n"); printf("HandmadeMathTest(): LookAt: Completed successfully\n");
} }
} }
void StringsTest() void StringsTest()
{ {
{ // Char Checks // Char Checks
if (1)
{
DQN_ASSERT(DqnChar_IsAlpha('a') == true); DQN_ASSERT(DqnChar_IsAlpha('a') == true);
DQN_ASSERT(DqnChar_IsAlpha('A') == true); DQN_ASSERT(DqnChar_IsAlpha('A') == true);
DQN_ASSERT(DqnChar_IsAlpha('0') == false); DQN_ASSERT(DqnChar_IsAlpha('0') == false);
@ -146,12 +150,15 @@ void StringsTest()
} }
// String Checks // String Checks
if (1)
{ {
// strcmp // strcmp
if (1)
{ {
const char *const a = "str_a"; const char *const a = "str_a";
// Check simple compares // Check simple compares
if (1)
{ {
DQN_ASSERT(DqnStr_Cmp(a, "str_a") == +0); DQN_ASSERT(DqnStr_Cmp(a, "str_a") == +0);
DQN_ASSERT(DqnStr_Cmp(a, "str_b") == -1); DQN_ASSERT(DqnStr_Cmp(a, "str_b") == -1);
@ -164,6 +171,7 @@ void StringsTest()
} }
// Check ops against null // Check ops against null
if (1)
{ {
DQN_ASSERT(DqnStr_Cmp(NULL, NULL) != +0); DQN_ASSERT(DqnStr_Cmp(NULL, NULL) != +0);
DQN_ASSERT(DqnStr_Cmp(a, NULL) != +0); DQN_ASSERT(DqnStr_Cmp(a, NULL) != +0);
@ -174,6 +182,7 @@ void StringsTest()
} }
// strlen // strlen
if (1)
{ {
const char *const a = "str_a"; const char *const a = "str_a";
DQN_ASSERT(DqnStr_Len(a) == 5); DQN_ASSERT(DqnStr_Len(a) == 5);
@ -190,11 +199,14 @@ void StringsTest()
} }
// strncpy // strncpy
if (1)
{ {
if (1)
{ {
const char *const a = "str_a"; const char *const a = "str_a";
char b[10] = {}; char b[10] = {};
// Check copy into empty array // Check copy into empty array
if (1)
{ {
char *result = DqnStr_Copy(b, a, DqnStr_Len(a)); char *result = DqnStr_Copy(b, a, DqnStr_Len(a));
DQN_ASSERT(DqnStr_Cmp(b, "str_a") == 0); DQN_ASSERT(DqnStr_Cmp(b, "str_a") == 0);
@ -204,6 +216,7 @@ void StringsTest()
} }
// Check copy into array offset, overlap with old results // Check copy into array offset, overlap with old results
if (1)
{ {
char *newResult = DqnStr_Copy(&b[1], a, DqnStr_Len(a)); char *newResult = DqnStr_Copy(&b[1], a, DqnStr_Len(a));
DQN_ASSERT(DqnStr_Cmp(newResult, "str_a") == 0); DQN_ASSERT(DqnStr_Cmp(newResult, "str_a") == 0);
@ -219,8 +232,10 @@ void StringsTest()
} }
// StrReverse // StrReverse
if (1)
{ {
// Basic reverse operations // Basic reverse operations
if (1)
{ {
char a[] = "aba"; char a[] = "aba";
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true); DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
@ -240,6 +255,7 @@ void StringsTest()
} }
// Try reverse empty string // Try reverse empty string
if (1)
{ {
char a[] = ""; char a[] = "";
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true); DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
@ -247,6 +263,7 @@ void StringsTest()
} }
// Try reverse single char string // Try reverse single char string
if (1)
{ {
char a[] = "a"; char a[] = "a";
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true); DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
@ -256,13 +273,13 @@ void StringsTest()
DQN_ASSERT(DqnStr_Cmp(a, "a") == 0); DQN_ASSERT(DqnStr_Cmp(a, "a") == 0);
} }
printf( printf("StringsTest(): StrReverse: Completed successfully\n");
"StringsTest(): StrReverse: Completed successfully\n");
} }
// const u64 LARGEST_NUM = (u64)-1; // const u64 LARGEST_NUM = (u64)-1;
const i64 SMALLEST_NUM = LLONG_MIN; const i64 SMALLEST_NUM = LLONG_MIN;
// StrToI64 // StrToI64
if (1)
{ {
const char *const a = "123"; const char *const a = "123";
DQN_ASSERT(Dqn_StrToI64(a, DqnStr_Len(a)) == 123); DQN_ASSERT(Dqn_StrToI64(a, DqnStr_Len(a)) == 123);
@ -290,6 +307,7 @@ void StringsTest()
} }
// i64 to str // i64 to str
if (1)
{ {
char a[DQN_64BIT_NUM_MAX_STR_SIZE] = {}; char a[DQN_64BIT_NUM_MAX_STR_SIZE] = {};
Dqn_I64ToStr(+100, a, DQN_ARRAY_COUNT(a)); Dqn_I64ToStr(+100, a, DQN_ARRAY_COUNT(a));
@ -318,6 +336,7 @@ void StringsTest()
} }
// StrToF32 // StrToF32
if (1)
{ {
const f32 EPSILON = 0.001f; const f32 EPSILON = 0.001f;
const char a[] = "-0.66248"; const char a[] = "-0.66248";
@ -394,24 +413,25 @@ void StringsTest()
printf("StringsTest(): StrToF32: Completed successfully\n"); printf("StringsTest(): StrToF32: Completed successfully\n");
} }
if (1)
{ {
if (1)
{ {
const char *const a = "Microsoft"; const char *const a = "Microsoft";
const char *const b = "icro"; const char *const b = "icro";
i32 lenA = DqnStr_Len(a); i32 lenA = DqnStr_Len(a);
i32 lenB = DqnStr_Len(b); i32 lenB = DqnStr_Len(b);
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, b, lenB) == true); DQN_ASSERT(DqnStr_HasSubstring(a, lenA, b, lenB) == true);
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, "iro", DQN_ASSERT(DqnStr_HasSubstring(a, lenA, "iro", DqnStr_Len("iro")) == false);
DqnStr_Len("iro")) == false);
DQN_ASSERT(DqnStr_HasSubstring(b, lenB, a, lenA) == false); DQN_ASSERT(DqnStr_HasSubstring(b, lenB, a, lenA) == false);
DQN_ASSERT(DqnStr_HasSubstring("iro", DqnStr_Len("iro"), a, DQN_ASSERT(DqnStr_HasSubstring("iro", DqnStr_Len("iro"), a, lenA) == false);
lenA) == false);
DQN_ASSERT(DqnStr_HasSubstring("", 0, "iro", 4) == false); DQN_ASSERT(DqnStr_HasSubstring("", 0, "iro", 4) == false);
DQN_ASSERT(DqnStr_HasSubstring("", 0, "", 0) == false); DQN_ASSERT(DqnStr_HasSubstring("", 0, "", 0) == false);
DQN_ASSERT(DqnStr_HasSubstring(NULL, 0, NULL, 0) == false); DQN_ASSERT(DqnStr_HasSubstring(NULL, 0, NULL, 0) == false);
} }
if (1)
{ {
const char *const a = "Micro"; const char *const a = "Micro";
const char *const b = "irob"; const char *const b = "irob";
@ -425,8 +445,10 @@ void StringsTest()
} }
// UCS <-> UTF8 Checks // UCS <-> UTF8 Checks
if (1)
{ {
// Test ascii characters // Test ascii characters
if (1)
{ {
u32 codepoint = '@'; u32 codepoint = '@';
u32 string[1] = {}; u32 string[1] = {};
@ -441,6 +463,7 @@ void StringsTest()
} }
// Test 2 byte characters // Test 2 byte characters
if (1)
{ {
u32 codepoint = 0x278; u32 codepoint = 0x278;
u32 string[1] = {}; u32 string[1] = {};
@ -455,6 +478,7 @@ void StringsTest()
} }
// Test 3 byte characters // Test 3 byte characters
if (1)
{ {
u32 codepoint = 0x0A0A; u32 codepoint = 0x0A0A;
u32 string[1] = {}; u32 string[1] = {};
@ -469,6 +493,7 @@ void StringsTest()
} }
// Test 4 byte characters // Test 4 byte characters
if (1)
{ {
u32 codepoint = 0x10912; u32 codepoint = 0x10912;
u32 string[1] = {}; u32 string[1] = {};
@ -482,6 +507,7 @@ void StringsTest()
DQN_ASSERT(bytesUsed == 4); DQN_ASSERT(bytesUsed == 4);
} }
if (1)
{ {
u32 codepoint = 0x10912; u32 codepoint = 0x10912;
u32 bytesUsed = Dqn_UCSToUTF8(NULL, codepoint); u32 bytesUsed = Dqn_UCSToUTF8(NULL, codepoint);
@ -497,26 +523,35 @@ void StringsTest()
printf("StringsTest(): Completed successfully\n"); printf("StringsTest(): Completed successfully\n");
} }
#ifdef DQN_WIN32_IMPLEMENTATION
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
void OtherTest() void OtherTest()
{ {
{ // Test Win32 Sleep
// NOTE: Win32 Sleep is not granular to a certain point so sleep excessively
u32 sleepInMs = 1000;
f64 startInMs = DqnTime_NowInMs();
Sleep(sleepInMs);
f64 endInMs = DqnTime_NowInMs();
DQN_ASSERT(startInMs < endInMs); if (1)
{
#if defined(DQN_UNIX_PLATFORM)
f64 startInS = DqnTimer_NowInS();
u32 sleepTimeInS = 1;
sleep(sleepTimeInS);
f64 endInS = DqnTimer_NowInS();
printf("start: %f, end: %f\n", startInS, endInS);
DQN_ASSERT((startInS + sleepTimeInS) <= endInS);
#elif defined(DQN_WIN32_PLATFORM)
f64 startInMs = DqnTimer_NowInMs();
u32 sleepTimeInMs = 1000;
Sleep(sleepTimeInMs);
f64 endInMs = DqnTimer_NowInMs();
printf("start: %f, end: %f\n", startInMs, endInMs);
DQN_ASSERT((startInMs + sleepTimeInMs) <= endInMs);
#endif
printf("OtherTest(): TimeNow: Completed successfully\n"); printf("OtherTest(): TimeNow: Completed successfully\n");
} }
printf("OtherTest(): Completed successfully\n"); printf("OtherTest(): Completed successfully\n");
} }
#endif
void RandomTest() { void RandomTest()
{
DqnRandPCGState pcg; DqnRandPCGState pcg;
DqnRnd_PCGInit(&pcg); DqnRnd_PCGInit(&pcg);
@ -537,7 +572,9 @@ void RandomTest() {
void MathTest() void MathTest()
{ {
if (1)
{ // Lerp { // Lerp
if (1)
{ {
f32 start = 10; f32 start = 10;
f32 t = 0.5f; f32 t = 0.5f;
@ -545,6 +582,7 @@ void MathTest()
DQN_ASSERT(DqnMath_Lerp(start, t, end) == 15); DQN_ASSERT(DqnMath_Lerp(start, t, end) == 15);
} }
if (1)
{ {
f32 start = 10; f32 start = 10;
f32 t = 2.0f; f32 t = 2.0f;
@ -555,6 +593,7 @@ void MathTest()
printf("MathTest(): Lerp: Completed successfully\n"); printf("MathTest(): Lerp: Completed successfully\n");
} }
if (1)
{ // sqrtf { // sqrtf
DQN_ASSERT(DqnMath_Sqrtf(4.0f) == 2.0f); DQN_ASSERT(DqnMath_Sqrtf(4.0f) == 2.0f);
printf("MathTest(): Sqrtf: Completed successfully\n"); printf("MathTest(): Sqrtf: Completed successfully\n");
@ -565,9 +604,11 @@ void MathTest()
void VecTest() void VecTest()
{ {
if (1)
{ // V2 { // V2
// V2 Creating // V2 Creating
if (1)
{ {
DqnV2 vec = DqnV2_2f(5.5f, 5.0f); DqnV2 vec = DqnV2_2f(5.5f, 5.0f);
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f); DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f);
@ -575,6 +616,7 @@ void VecTest()
} }
// V2 with 2 integers // V2 with 2 integers
if (1)
{ {
DqnV2 vec = DqnV2_2i(3, 5); DqnV2 vec = DqnV2_2i(3, 5);
DQN_ASSERT(vec.x == 3 && vec.y == 5.0f); DQN_ASSERT(vec.x == 3 && vec.y == 5.0f);
@ -582,6 +624,7 @@ void VecTest()
} }
// V2 Arithmetic // V2 Arithmetic
if (1)
{ {
DqnV2 vecA = DqnV2_2f(5, 10); DqnV2 vecA = DqnV2_2f(5, 10);
DqnV2 vecB = DqnV2_2i(2, 3); DqnV2 vecB = DqnV2_2i(2, 3);
@ -606,6 +649,7 @@ void VecTest()
} }
// Test operator overloading // Test operator overloading
if (1)
{ {
DqnV2 vecA = DqnV2_2f(5, 10); DqnV2 vecA = DqnV2_2f(5, 10);
DqnV2 vecB = DqnV2_2i(2, 3); DqnV2 vecB = DqnV2_2i(2, 3);
@ -633,6 +677,7 @@ void VecTest()
} }
// V2 Properties // V2 Properties
if (1)
{ {
const f32 EPSILON = 0.001f; const f32 EPSILON = 0.001f;
DqnV2 a = DqnV2_2f(0, 0); DqnV2 a = DqnV2_2f(0, 0);
@ -649,8 +694,10 @@ void VecTest()
f32 normY = b.y / 5.0f; f32 normY = b.y / 5.0f;
f32 diffNormX = normalised.x - normX; f32 diffNormX = normalised.x - normX;
f32 diffNormY = normalised.y - normY; f32 diffNormY = normalised.y - normY;
DQN_ASSERT_MSG(diffNormX < EPSILON, "normalised.x: %f, normX: %f\n", normalised.x, normX); DQN_ASSERT_MSG(diffNormX < EPSILON, "normalised.x: %f, normX: %f\n", normalised.x,
DQN_ASSERT_MSG(diffNormY < EPSILON, "normalised.y: %f, normY: %f\n", normalised.y, normY); normX);
DQN_ASSERT_MSG(diffNormY < EPSILON, "normalised.y: %f, normY: %f\n", normalised.y,
normY);
DqnV2 c = DqnV2_2f(3.5f, 8.0f); DqnV2 c = DqnV2_2f(3.5f, 8.0f);
DQN_ASSERT(DqnV2_Overlaps(b, c) == true); DQN_ASSERT(DqnV2_Overlaps(b, c) == true);
@ -660,6 +707,7 @@ void VecTest()
DQN_ASSERT(DqnV2_Dot(c, d) == 0); DQN_ASSERT(DqnV2_Dot(c, d) == 0);
} }
if (1)
{ // constrain_to_ratio { // constrain_to_ratio
DqnV2 ratio = DqnV2_2f(16, 9); DqnV2 ratio = DqnV2_2f(16, 9);
DqnV2 dim = DqnV2_2f(2000, 1080); DqnV2 dim = DqnV2_2f(2000, 1080);
@ -670,9 +718,11 @@ void VecTest()
printf("VecTest(): Vec2: Completed successfully\n"); printf("VecTest(): Vec2: Completed successfully\n");
} }
if (1)
{ // V3 { // V3
// V3i Creating // V3i Creating
if (1)
{ {
DqnV3 vec = DqnV3_3f(5.5f, 5.0f, 5.875f); DqnV3 vec = DqnV3_3f(5.5f, 5.0f, 5.875f);
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f); DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f);
@ -680,6 +730,7 @@ void VecTest()
} }
// V3i Creating // V3i Creating
if (1)
{ {
DqnV3 vec = DqnV3_3i(3, 4, 5); DqnV3 vec = DqnV3_3i(3, 4, 5);
DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5); DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5);
@ -687,6 +738,7 @@ void VecTest()
} }
// V3 Arithmetic // V3 Arithmetic
if (1)
{ {
DqnV3 vecA = DqnV3_3f(5, 10, 15); DqnV3 vecA = DqnV3_3f(5, 10, 15);
DqnV3 vecB = DqnV3_3f(2, 3, 6); DqnV3 vecB = DqnV3_3f(2, 3, 6);
@ -713,6 +765,7 @@ void VecTest()
DQN_ASSERT(DqnV3_Equals(cross, DqnV3_3f(15, 0, -5)) == true); DQN_ASSERT(DqnV3_Equals(cross, DqnV3_3f(15, 0, -5)) == true);
} }
if (1)
{ {
DqnV3 vecA = DqnV3_3f(5, 10, 15); DqnV3 vecA = DqnV3_3f(5, 10, 15);
DqnV3 vecB = DqnV3_3f(2, 3, 6); DqnV3 vecB = DqnV3_3f(2, 3, 6);
@ -742,9 +795,11 @@ void VecTest()
printf("VecTest(): Vec3: Completed successfully\n"); printf("VecTest(): Vec3: Completed successfully\n");
} }
if (1)
{ // V4 { // V4
// V4 Creating // V4 Creating
if (1)
{ {
DqnV4 vec = DqnV4_4f(5.5f, 5.0f, 5.875f, 5.928f); DqnV4 vec = DqnV4_4f(5.5f, 5.0f, 5.875f, 5.928f);
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f && vec.w == 5.928f); DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f && vec.w == 5.928f);
@ -752,6 +807,7 @@ void VecTest()
} }
// V4i Creating // V4i Creating
if (1)
{ {
DqnV4 vec = DqnV4_4i(3, 4, 5, 6); DqnV4 vec = DqnV4_4i(3, 4, 5, 6);
DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5 && vec.w == 6); DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5 && vec.w == 6);
@ -759,6 +815,7 @@ void VecTest()
} }
// V4 Arithmetic // V4 Arithmetic
if (1)
{ {
DqnV4 vecA = DqnV4_4f(5, 10, 15, 20); DqnV4 vecA = DqnV4_4f(5, 10, 15, 20);
DqnV4 vecB = DqnV4_4i(2, 3, 6, 8); DqnV4 vecB = DqnV4_4i(2, 3, 6, 8);
@ -782,6 +839,7 @@ void VecTest()
DQN_ASSERT(dotResult == 107); DQN_ASSERT(dotResult == 107);
} }
if (1)
{ {
DqnV4 vecA = DqnV4_4f(5, 10, 15, 20); DqnV4 vecA = DqnV4_4f(5, 10, 15, 20);
DqnV4 vecB = DqnV4_4i(2, 3, 6, 8); DqnV4 vecB = DqnV4_4i(2, 3, 6, 8);
@ -812,8 +870,10 @@ void VecTest()
} }
// Rect // Rect
if (1)
{ {
// Test rect init functions // Test rect init functions
if (1)
{ {
DqnRect rect4f = DqnRect_4f(1.1f, 2.2f, 3.3f, 4.4f); DqnRect rect4f = DqnRect_4f(1.1f, 2.2f, 3.3f, 4.4f);
DqnRect rect4i = DqnRect_4i(1, 2, 3, 4); DqnRect rect4i = DqnRect_4i(1, 2, 3, 4);
@ -829,11 +889,12 @@ void VecTest()
} }
// Test rect get size function // Test rect get size function
if (1)
{ {
// Test float rect // Test float rect
if (1)
{ {
DqnRect rect = DqnRect rect = DqnRect_Init(DqnV2_2f(-10, -10), DqnV2_2f(20, 20));
DqnRect_Init(DqnV2_2f(-10, -10), DqnV2_2f(20, 20));
f32 width, height; f32 width, height;
DqnRect_GetSize2f(rect, &width, &height); DqnRect_GetSize2f(rect, &width, &height);
@ -845,9 +906,9 @@ void VecTest()
} }
// Test rect with float values and GetSize as 2 integers // Test rect with float values and GetSize as 2 integers
if (1)
{ {
DqnRect rect = DqnRect_Init(DqnV2_2f(-10.5f, -10.5f), DqnRect rect = DqnRect_Init(DqnV2_2f(-10.5f, -10.5f), DqnV2_2f(20.5f, 20.5f));
DqnV2_2f(20.5f, 20.5f));
i32 width, height; i32 width, height;
DqnRect_GetSize2i(rect, &width, &height); DqnRect_GetSize2i(rect, &width, &height);
DQN_ASSERT(width == 20); DQN_ASSERT(width == 20);
@ -867,12 +928,14 @@ void VecTest()
DQN_ASSERT(clipResult.max.x == 10 && clipResult.max.y == 10); DQN_ASSERT(clipResult.max.x == 10 && clipResult.max.y == 10);
// Test shifting rect // Test shifting rect
if (1)
{ {
DqnRect shiftedRect = DqnRect_Move(rect, DqnV2_2f(10, 0)); DqnRect shiftedRect = DqnRect_Move(rect, DqnV2_2f(10, 0));
DQN_ASSERT(DqnV2_Equals(shiftedRect.min, DqnV2_2f(0, -10))); DQN_ASSERT(DqnV2_Equals(shiftedRect.min, DqnV2_2f(0, -10)));
DQN_ASSERT(DqnV2_Equals(shiftedRect.max, DqnV2_2f(20, 10))); DQN_ASSERT(DqnV2_Equals(shiftedRect.max, DqnV2_2f(20, 10)));
// Ensure dimensions have remained the same // Ensure dimensions have remained the same
if (1)
{ {
f32 width, height; f32 width, height;
DqnRect_GetSize2f(shiftedRect, &width, &height); DqnRect_GetSize2f(shiftedRect, &width, &height);
@ -884,6 +947,7 @@ void VecTest()
} }
// Test rect contains p // Test rect contains p
if (1)
{ {
DqnV2 inP = DqnV2_2f(5, 5); DqnV2 inP = DqnV2_2f(5, 5);
DqnV2 outP = DqnV2_2f(100, 100); DqnV2 outP = DqnV2_2f(100, 100);
@ -900,12 +964,14 @@ void VecTest()
void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI) void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
{ {
if (1)
{ {
DQN_ASSERT(DqnArray_Init(array, 1, memAPI)); DQN_ASSERT(DqnArray_Init(array, 1, memAPI));
DQN_ASSERT(array->capacity == 1); DQN_ASSERT(array->capacity == 1);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array->count == 0);
// Test basic insert // Test basic insert
if (1)
{ {
DqnV2 va = DqnV2_2f(5, 10); DqnV2 va = DqnV2_2f(5, 10);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(DqnArray_Push(array, va));
@ -918,6 +984,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
} }
// Test array resizing and freeing // Test array resizing and freeing
if (1)
{ {
DqnV2 va = DqnV2_2f(10, 15); DqnV2 va = DqnV2_2f(10, 15);
DQN_ASSERT(DqnArray_Push(array, va)); DQN_ASSERT(DqnArray_Push(array, va));
@ -976,6 +1043,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(DqnArray_Free(array));
if (1)
{ {
DQN_ASSERT(DqnArray_Init(array, 1, memAPI)); DQN_ASSERT(DqnArray_Init(array, 1, memAPI));
DQN_ASSERT(array->capacity == 1); DQN_ASSERT(array->capacity == 1);
@ -983,6 +1051,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(DqnArray_Free(array));
if (1)
{ {
DqnV2 a = DqnV2_2f(1, 2); DqnV2 a = DqnV2_2f(1, 2);
DqnV2 b = DqnV2_2f(3, 4); DqnV2 b = DqnV2_2f(3, 4);
@ -1027,10 +1096,10 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
DQN_ASSERT(DqnArray_Clear(array)); DQN_ASSERT(DqnArray_Clear(array));
DQN_ASSERT(array->capacity == 16); DQN_ASSERT(array->capacity == 16);
DQN_ASSERT(array->count == 0); DQN_ASSERT(array->count == 0);
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(DqnArray_Free(array));
if (1)
{ {
DqnV2 a = DqnV2_2f(1, 2); DqnV2 a = DqnV2_2f(1, 2);
DqnV2 b = DqnV2_2f(3, 4); DqnV2 b = DqnV2_2f(3, 4);
@ -1066,7 +1135,6 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
} }
DQN_ASSERT(DqnArray_Free(array)); DQN_ASSERT(DqnArray_Free(array));
printf("ArrayTestMemAPIInternal(): Completed successfully\n"); printf("ArrayTestMemAPIInternal(): Completed successfully\n");
} }
void ArrayTest() void ArrayTest()
@ -1079,6 +1147,7 @@ void ArrayTest()
void MemStackTest() void MemStackTest()
{ {
// Test over allocation, alignments, temp regions // Test over allocation, alignments, temp regions
if (1)
{ {
size_t allocSize = DQN_KILOBYTE(1); size_t allocSize = DQN_KILOBYTE(1);
DqnMemStack stack = {}; DqnMemStack stack = {};
@ -1096,8 +1165,7 @@ void MemStackTest()
DQN_ASSERT(resultAddrA % ALIGNMENT == 0); DQN_ASSERT(resultAddrA % ALIGNMENT == 0);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == allocSize); DQN_ASSERT(stack.block->size == allocSize);
DQN_ASSERT(stack.block->used >= sizeA + 0 && DQN_ASSERT(stack.block->used >= sizeA + 0 && stack.block->used <= sizeA + 3);
stack.block->used <= sizeA + 3);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
DQN_ASSERT(resultA); DQN_ASSERT(resultA);
u8 *ptrA = (u8 *)resultA; u8 *ptrA = (u8 *)resultA;
@ -1116,8 +1184,7 @@ void MemStackTest()
// Since we alignment the pointers we return they can be within 0-3 // Since we alignment the pointers we return they can be within 0-3
// bytes of what we expect and since this is in a new block as well used // bytes of what we expect and since this is in a new block as well used
// will reflect just this allocation. // will reflect just this allocation.
DQN_ASSERT(stack.block->used >= sizeB + 0 && DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
stack.block->used <= sizeB + 3);
DQN_ASSERT(resultB); DQN_ASSERT(resultB);
u8 *ptrB = (u8 *)resultB; u8 *ptrB = (u8 *)resultB;
for (u32 i = 0; i < sizeB; i++) for (u32 i = 0; i < sizeB; i++)
@ -1139,8 +1206,7 @@ void MemStackTest()
u64 resultAddrC = *((u64 *)resultC); u64 resultAddrC = *((u64 *)resultC);
DQN_ASSERT(resultAddrC % ALIGNMENT == 0); DQN_ASSERT(resultAddrC % ALIGNMENT == 0);
DQN_ASSERT(stack.block != blockB && stack.block != blockA); DQN_ASSERT(stack.block != blockB && stack.block != blockA);
DQN_ASSERT(stack.block->used >= sizeC + 0 && DQN_ASSERT(stack.block->used >= sizeC + 0 && stack.block->used <= sizeC + 3);
stack.block->used <= sizeC + 3);
DQN_ASSERT(stack.tempRegionCount == 1); DQN_ASSERT(stack.tempRegionCount == 1);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
@ -1166,8 +1232,7 @@ void MemStackTest()
DqnMemStackTempRegion_End(tempBuffer); DqnMemStackTempRegion_End(tempBuffer);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == sizeB); DQN_ASSERT(stack.block->size == sizeB);
DQN_ASSERT(stack.block->used >= sizeB + 0 && DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
stack.block->used <= sizeB + 3);
DQN_ASSERT(stack.tempRegionCount == 0); DQN_ASSERT(stack.tempRegionCount == 0);
DQN_ASSERT(resultB); DQN_ASSERT(resultB);
@ -1194,15 +1259,14 @@ void MemStackTest()
} }
// Test stack with fixed memory does not allocate more // Test stack with fixed memory does not allocate more
if (1)
{ {
u8 memory[DQN_KILOBYTE(1)] = {}; u8 memory[DQN_KILOBYTE(1)] = {};
DqnMemStack stack = {}; DqnMemStack stack = {};
const u32 ALIGNMENT = 4; const u32 ALIGNMENT = 4;
DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory), DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory), ALIGNMENT);
ALIGNMENT);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
@ -1213,14 +1277,14 @@ void MemStackTest()
DqnMemStack_Free(&stack); DqnMemStack_Free(&stack);
DqnMemStack_FreeLastBlock(&stack); DqnMemStack_FreeLastBlock(&stack);
DQN_ASSERT(stack.block && stack.block->memory); DQN_ASSERT(stack.block && stack.block->memory);
DQN_ASSERT(stack.block->size == DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
DQN_ASSERT(stack.block->used == 0); DQN_ASSERT(stack.block->used == 0);
DQN_ASSERT(stack.byteAlign == ALIGNMENT); DQN_ASSERT(stack.byteAlign == ALIGNMENT);
} }
// Test stack with fixed size, allocates once from platform but does not // Test stack with fixed size, allocates once from platform but does not
// grow further // grow further
if (1)
{ {
size_t allocSize = DQN_KILOBYTE(1); size_t allocSize = DQN_KILOBYTE(1);
DqnMemStack stack = {}; DqnMemStack stack = {};
@ -1243,6 +1307,7 @@ void MemStackTest()
} }
// Test freeing/clear block and alignment // Test freeing/clear block and alignment
if (1)
{ {
size_t firstBlockSize = DQN_KILOBYTE(1); size_t firstBlockSize = DQN_KILOBYTE(1);
DqnMemStack stack = {}; DqnMemStack stack = {};
@ -1320,7 +1385,8 @@ void MemStackTest()
for (u32 i = 0; i < fourthBlockSize; i++) for (u32 i = 0; i < fourthBlockSize; i++)
fourth[i] = 'f'; fourth[i] = 'f';
DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) && (thirdBlock != fourthBlock)); DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) &&
(thirdBlock != fourthBlock));
DQN_ASSERT(firstBlock->prevBlock == NULL); DQN_ASSERT(firstBlock->prevBlock == NULL);
DQN_ASSERT(secondBlock->prevBlock == firstBlock); DQN_ASSERT(secondBlock->prevBlock == firstBlock);
DQN_ASSERT(thirdBlock->prevBlock == secondBlock); DQN_ASSERT(thirdBlock->prevBlock == secondBlock);
@ -1346,7 +1412,8 @@ void MemStackTest()
DQN_ASSERT(thirdBlock->used == thirdBlockSize); DQN_ASSERT(thirdBlock->used == thirdBlockSize);
DQN_ASSERT(fourthBlock->used == fourthBlockSize); DQN_ASSERT(fourthBlock->used == fourthBlockSize);
DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) && (thirdBlock != fourthBlock)); DQN_ASSERT((firstBlock != secondBlock) && (secondBlock != thirdBlock) &&
(thirdBlock != fourthBlock));
DQN_ASSERT(firstBlock->prevBlock == NULL); DQN_ASSERT(firstBlock->prevBlock == NULL);
DQN_ASSERT(secondBlock->prevBlock == firstBlock); DQN_ASSERT(secondBlock->prevBlock == firstBlock);
DQN_ASSERT(thirdBlock->prevBlock == secondBlock); DQN_ASSERT(thirdBlock->prevBlock == secondBlock);
@ -1427,6 +1494,7 @@ void MemStackTest()
} }
// Test pop // Test pop
if (1)
{ {
DqnMemStack stack = {}; DqnMemStack stack = {};
DqnMemStack_Init(&stack, DQN_KILOBYTE(1), true); DqnMemStack_Init(&stack, DQN_KILOBYTE(1), true);
@ -1440,14 +1508,15 @@ void MemStackTest()
} }
} }
#ifdef DQN_XPLATFORM_LAYER
#ifdef DQN_PLATFORM_LAYER
void FileTest() void FileTest()
{ {
// File i/o // File i/o
if (1)
{ {
// Test file open // Test file open
if (1)
{ {
const char *const FILE_TO_OPEN = ".clang-format"; const char *const FILE_TO_OPEN = ".clang-format";
u32 expectedSize = 0; u32 expectedSize = 0;
@ -1460,9 +1529,8 @@ void FileTest()
#elif defined(DQN_WIN32_IMPLEMENTATION) #elif defined(DQN_WIN32_IMPLEMENTATION)
{ {
HANDLE handle = HANDLE handle = CreateFile(FILE_TO_OPEN, GENERIC_READ, 0, NULL, OPEN_EXISTING,
CreateFile(FILE_TO_OPEN, GENERIC_READ, 0, NULL, FILE_ATTRIBUTE_NORMAL, NULL);
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) if (handle == INVALID_HANDLE_VALUE)
{ {
DqnWin32_DisplayLastError("CreateFile() failed"); DqnWin32_DisplayLastError("CreateFile() failed");
@ -1478,29 +1546,27 @@ void FileTest()
#endif #endif
DqnFile file = {}; DqnFile file = {};
DQN_ASSERT(DqnFile_Open( DQN_ASSERT(DqnFile_Open(".clang-format", &file,
".clang-format", &file,
(DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read), (DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read),
DqnFileAction_OpenOnly)); DqnFileAction_OpenOnly));
DQN_ASSERT_MSG(file.size == expectedSize, DQN_ASSERT_MSG(file.size == expectedSize,
"DqnFileOpen() failed: file.size: %d, expected:%d\n", "DqnFileOpen() failed: file.size: %d, expected:%d\n", file.size,
file.size, expectedSize); expectedSize);
u8 *buffer = (u8 *)calloc(1, (size_t)file.size * sizeof(u8)); u8 *buffer = (u8 *)calloc(1, (size_t)file.size * sizeof(u8));
DQN_ASSERT(DqnFile_Read(file, buffer, (u32)file.size) == file.size); DQN_ASSERT(DqnFile_Read(file, buffer, (u32)file.size) == file.size);
free(buffer); free(buffer);
DqnFile_Close(&file); DqnFile_Close(&file);
DQN_ASSERT(!file.handle && file.size == 0 && DQN_ASSERT(!file.handle && file.size == 0 && file.permissionFlags == 0);
file.permissionFlags == 0);
} }
// Test invalid file // Test invalid file
if (1)
{ {
DqnFile file = {}; DqnFile file = {};
DQN_ASSERT(!DqnFile_Open( DQN_ASSERT(!DqnFile_Open("asdljasdnel;kajdf", &file,
"asdljasdnel;kajdf", &file,
(DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read), (DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read),
DqnFileAction_OpenOnly)); DqnFileAction_OpenOnly));
DQN_ASSERT(file.size == 0); DQN_ASSERT(file.size == 0);
@ -1508,25 +1574,22 @@ void FileTest()
DQN_ASSERT(!file.handle); DQN_ASSERT(!file.handle);
printf("FileTest(): FileIO: Completed successfully\n"); printf("FileTest(): FileIO: Completed successfully\n");
} }
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// Write Test // Write Test
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
if (1)
{ {
const char *fileNames[] = {"dqn_1", "dqn_2", "dqn_3", "dqn_4", "dqn_5"}; const char *fileNames[] = {"dqn_1", "dqn_2", "dqn_3", "dqn_4", "dqn_5"};
const char *writeData[] = {"1234", "2468", "36912", "481216", const char *writeData[] = {"1234", "2468", "36912", "481216", "5101520"};
"5101520"};
DqnFile files[DQN_ARRAY_COUNT(fileNames)] = {}; DqnFile files[DQN_ARRAY_COUNT(fileNames)] = {};
// Write data out to some files // Write data out to some files
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++) for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
{ {
u32 permissions = u32 permissions = DqnFilePermissionFlag_Read | DqnFilePermissionFlag_Write;
DqnFilePermissionFlag_Read | DqnFilePermissionFlag_Write; if (!DqnFile_Open(fileNames[i], files + i, permissions, DqnFileAction_ClearIfExist))
if (!DqnFile_Open(fileNames[i], files + i, permissions,
DqnFileAction_ClearIfExist))
{ {
bool result = DqnFile_Open(fileNames[i], files + i, permissions, bool result = DqnFile_Open(fileNames[i], files + i, permissions,
DqnFileAction_CreateIfNotExist); DqnFileAction_CreateIfNotExist);
@ -1547,8 +1610,7 @@ void FileTest()
{ {
u32 permissions = DqnFilePermissionFlag_Read; u32 permissions = DqnFilePermissionFlag_Read;
DqnFile *file = files + i; DqnFile *file = files + i;
bool result = DqnFile_Open(fileNames[i], file, permissions, bool result = DqnFile_Open(fileNames[i], file, permissions, DqnFileAction_OpenOnly);
DqnFileAction_OpenOnly);
DQN_ASSERT(result); DQN_ASSERT(result);
u8 *buffer = (u8 *)DqnMemStack_Push(&memStack, file->size); u8 *buffer = (u8 *)DqnMemStack_Push(&memStack, file->size);
@ -1572,13 +1634,14 @@ void FileTest()
{ {
DqnFile dummy = {}; DqnFile dummy = {};
u32 permissions = DqnFilePermissionFlag_Read; u32 permissions = DqnFilePermissionFlag_Read;
bool fileExists = DqnFile_Open(fileNames[i], &dummy, permissions, bool fileExists =
DqnFileAction_OpenOnly); DqnFile_Open(fileNames[i], &dummy, permissions, DqnFileAction_OpenOnly);
DQN_ASSERT(!fileExists); DQN_ASSERT(!fileExists);
} }
DqnMemStack_Free(&memStack); DqnMemStack_Free(&memStack);
} }
if (1)
{ {
u32 numFiles; u32 numFiles;
#if defined(DQN_UNIX_IMPLEMENTATION) #if defined(DQN_UNIX_IMPLEMENTATION)
@ -1612,8 +1675,8 @@ FILE_SCOPE void JobQueueDebugCallbackIncrementCounter(DqnJobQueue *const queue,
u32 number = globalDebugCounter; u32 number = globalDebugCounter;
DqnLock_Release(&globalJobQueueLock); DqnLock_Release(&globalJobQueueLock);
printf("JobQueueDebugCallbackIncrementCounter(): Thread %d: Incrementing Number: %d\n", GetCurrentThreadId(), printf("JobQueueDebugCallbackIncrementCounter(): Thread %d: Incrementing Number: %d\n",
number); GetCurrentThreadId(), number);
} }
FILE_SCOPE void JobQueueTest() FILE_SCOPE void JobQueueTest()
@ -1632,8 +1695,8 @@ FILE_SCOPE void JobQueueTest()
void *jobQueueMem = DqnMemStack_Push(&memStack, requiredSize); void *jobQueueMem = DqnMemStack_Push(&memStack, requiredSize);
DQN_ASSERT_HARD(jobQueueMem); DQN_ASSERT_HARD(jobQueueMem);
DqnJobQueue *jobQueue = DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize, DqnJobQueue *jobQueue =
QUEUE_SIZE, totalThreads); DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize, QUEUE_SIZE, totalThreads);
DQN_ASSERT_HARD(jobQueue); DQN_ASSERT_HARD(jobQueue);
DQN_ASSERT(DqnLock_Init(&globalJobQueueLock)); DQN_ASSERT(DqnLock_Init(&globalJobQueueLock));
@ -1653,8 +1716,7 @@ FILE_SCOPE void JobQueueTest()
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++) for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
DQN_ASSERT(globalDebugCounterMemoize[i]); DQN_ASSERT(globalDebugCounterMemoize[i]);
while (DqnJobQueue_TryExecuteNextJob(jobQueue) && while (DqnJobQueue_TryExecuteNextJob(jobQueue) && !DqnJobQueue_AllJobsComplete(jobQueue))
!DqnJobQueue_AllJobsComplete(jobQueue))
; ;
printf("\nJobQueueTest(): Final incremented value: %d\n", globalDebugCounter); printf("\nJobQueueTest(): Final incremented value: %d\n", globalDebugCounter);
@ -1672,12 +1734,12 @@ int main(void)
ArrayTest(); ArrayTest();
MemStackTest(); MemStackTest();
#ifdef DQN_PLATFORM_LAYER #ifdef DQN_XPLATFORM_LAYER
FileTest(); FileTest();
OtherTest();
#endif #endif
#ifdef DQN_WIN32_IMPLEMENTATION #ifdef DQN_WIN32_IMPLEMENTATION
OtherTest();
JobQueueTest(); JobQueueTest();
#endif #endif