DqnTimer unix implementation
This commit is contained in:
parent
f464e869ec
commit
187fc14d02
175
dqn.h
175
dqn.h
@ -18,7 +18,7 @@
|
||||
// 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
|
||||
|
||||
// API > Portable Code
|
||||
// #Portable Code
|
||||
// #DqnAssert Assertions
|
||||
// #DqnMem Memory Allocation
|
||||
// #DqnMemStack Memory Allocator, Push, Pop Style
|
||||
@ -36,18 +36,19 @@
|
||||
// #DqnWStr WStr Operations (WStr_Len() etc)
|
||||
// #DqnRnd Random Number Generator (ints and floats)
|
||||
|
||||
// API > Cross Platform Code
|
||||
// #XPlatform (Win32 & Unix)
|
||||
// #DqnFile File I/O (Read, Write, Delete)
|
||||
// #DqnDir Directory Querying
|
||||
// #DqnTimer High Resolution Timer
|
||||
|
||||
// API > Win32 Only
|
||||
// #DqnTime Platform High Resolution Timer
|
||||
// #DqnLock Mutex Synchronisation
|
||||
// #DqnAtomic Interlocks/Atomic Operations
|
||||
// #DqnJobQueue Multithreaded Job Queue
|
||||
// #DqnWin32 Common Win32 API Helpers
|
||||
// #Platform
|
||||
// - #Win32Platform
|
||||
// - #DqnLock Mutex Synchronisation
|
||||
// - #DqnAtomic Interlocks/Atomic Operations
|
||||
// - #DqnJobQueue Multithreaded Job Queue
|
||||
// - #DqnWin32 Common Win32 API Helpers
|
||||
|
||||
// API > External Code
|
||||
// #External Code
|
||||
// #DqnIni Simple INI Config File API (Public Domain lib by Mattias Gustavsson)
|
||||
// #DqnSprintf Cross-platform Sprintf Implementation (Public Domain lib stb_sprintf)
|
||||
|
||||
@ -58,15 +59,15 @@
|
||||
// a platform implementation, platform specific implementations in the portable
|
||||
// layer will get activated.
|
||||
#if (defined(_WIN32) || defined(_WIN64)) && defined(DQN_WIN32_IMPLEMENTATION)
|
||||
#define DQN_PLATFORM_LAYER
|
||||
#define DQN_XPLATFORM_LAYER
|
||||
#define DQN_WIN32_PLATFORM
|
||||
#elif defined(__linux__) && defined(DQN_UNIX_IMPLEMENTATION)
|
||||
#define DQN_PLATFORM_LAYER
|
||||
#define DQN_XPLATFORM_LAYER
|
||||
#define DQN_UNIX_PLATFORM
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Portable Layer
|
||||
// #Portable Code
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef DQN_H
|
||||
#define DQN_H
|
||||
@ -893,26 +894,13 @@ DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max);
|
||||
#endif /* DQN_H */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Cross-Platform Layer
|
||||
// #XPlatform (Win32 & Unix) Public API
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions in the Cross Platform are guaranteed to be supported in both Unix
|
||||
// and Win32
|
||||
#ifdef DQN_PLATFORM_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
|
||||
|
||||
#ifdef DQN_XPLATFORM_LAYER
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Cross-Platform > #DqnFile Public API - File I/O
|
||||
// XPlatform > #DqnFile Public API - File I/O
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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_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.
|
||||
// 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()
|
||||
@ -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);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// DQN_WIN32_PLATFORM only have a valid implementation in Win32.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// #Win32Platform Public API
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef DQN_WIN32_PLATFORM
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Platform > Win32 > #DqnTimer Public API - High Resolution Timer
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_FILE_SCOPE f64 DqnTime_NowInS();
|
||||
DQN_FILE_SCOPE f64 DqnTime_NowInMs();
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Platform > Win32 > #DqnLock Public API - Mutex Synchronisation
|
||||
// Win32Platform > #DqnLock Public API - Mutex Synchronisation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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_Add32 (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
|
||||
// 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);
|
||||
#endif // DQN_WIN32_PLATFORM
|
||||
|
||||
#ifdef DQN_UNIX_PLATFORM
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Platform > Unix
|
||||
// #External Code
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
#endif // DQN_PLATFORM_LAYER
|
||||
|
||||
#ifndef 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// #External Code
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// #DqnSprintf Implementation - STB_Sprintf
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -5349,14 +5345,24 @@ void DqnIni_PropertyValueSet(DqnIni *ini, int section, int property,
|
||||
#endif
|
||||
#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
|
||||
// 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
|
||||
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
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Cross-Platform > #DqnFile Implementation
|
||||
// XPlatform > #DqnFile Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_FILE_SCOPE
|
||||
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;
|
||||
|
||||
#ifdef DQN_WIN32_PLATFORM
|
||||
#if defined(DQN_WIN32_PLATFORM)
|
||||
return DqnFileInternal_Win32OpenW(path, file, permissionFlags, action);
|
||||
#else
|
||||
DQN_ASSERT(DQN_INVALID_CODE_PATH);
|
||||
@ -5780,7 +5786,7 @@ DQN_FILE_SCOPE bool DqnFile_Delete(const char *const path)
|
||||
|
||||
// TODO(doyle): Logging
|
||||
#if defined(DQN_WIN32_PLATFORM)
|
||||
return DeleteFile(path);
|
||||
return DeleteFileA(path);
|
||||
|
||||
#elif defined(DQN_UNIX_PLATFORM)
|
||||
i32 result = unlink(path);
|
||||
@ -5791,6 +5797,9 @@ DQN_FILE_SCOPE bool DqnFile_Delete(const char *const path)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// XPlatform > #DqnDir Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
DQN_FILE_SCOPE char **DqnDir_Read(const char *const dir, u32 *const 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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Platform > Win32 > #DqnTimer Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
FILE_SCOPE f64 DqnTimeInternal_Win32QueryPerfCounterTimeInS()
|
||||
#if defined (DQN_WIN32_PLATFORM)
|
||||
FILE_SCOPE f64 DqnTimerInternal_Win32QueryPerfCounterTimeInMs()
|
||||
{
|
||||
LOCAL_PERSIST LARGE_INTEGER queryPerformanceFrequency = {0};
|
||||
if (queryPerformanceFrequency.QuadPart == 0)
|
||||
@ -5830,28 +5836,53 @@ FILE_SCOPE f64 DqnTimeInternal_Win32QueryPerfCounterTimeInS()
|
||||
LARGE_INTEGER qpcResult;
|
||||
QueryPerformanceCounter(&qpcResult);
|
||||
|
||||
// Convert to ms
|
||||
f64 timestamp =
|
||||
qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart;
|
||||
// Convert to microseconds first then divide by ticks per second then to milliseconds
|
||||
qpcResult.QuadPart *= 1000000;
|
||||
f64 timestamp = qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart;
|
||||
timestamp /= 1000.0f;
|
||||
return timestamp;
|
||||
}
|
||||
#endif
|
||||
|
||||
f64 DqnTime_NowInS()
|
||||
DQN_FILE_SCOPE f64 DqnTimer_NowInMs()
|
||||
{
|
||||
f64 result;
|
||||
#ifdef DQN_WIN32_PLATFORM
|
||||
result = DQN_MAX(DqnTimeInternal_Win32QueryPerfCounterTimeInS(), 0);
|
||||
f64 result = 0;
|
||||
#if defined(DQN_WIN32_PLATFORM)
|
||||
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
|
||||
result = 0;
|
||||
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Win32 path not implemented yet");
|
||||
DQN_ASSERT_MSG(DQN_INVALID_CODE_PATH, "Non Unix/Win32 path not implemented yet");
|
||||
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -5936,7 +5967,7 @@ DQN_FILE_SCOPE u32 DqnAtomic_Sub32(u32 volatile *src)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Platform > Win32 > #DqnJobQueue Implementation
|
||||
// Win32Platform > #DqnJobQueue Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
typedef struct DqnJobQueue
|
||||
{
|
||||
@ -5953,7 +5984,7 @@ typedef struct DqnJobQueue
|
||||
} DqnJobQueue;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Platform > Win32 > #DqnJobQueueInternal Implementation
|
||||
// Win32Platform > #DqnJobQueueInternal Implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
size_t DQN_JOB_QUEUE_INTERNAL_THREAD_DEFAULT_STACK_SIZE = 0;
|
||||
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,
|
||||
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,
|
||||
wchar_t *const out, const i32 outLen)
|
||||
@ -6182,13 +6213,13 @@ DQN_FILE_SCOPE void DqnWin32_OutputDebugString(const char *const formatStr, ...)
|
||||
}
|
||||
va_end(argList);
|
||||
|
||||
OutputDebugString(str);
|
||||
OutputDebugStringA(str);
|
||||
}
|
||||
|
||||
DQN_FILE_SCOPE i32 DqnWin32_GetEXEDirectory(char *const buf, const u32 bufLen)
|
||||
{
|
||||
if (!buf || bufLen == 0) return 0;
|
||||
u32 copiedLen = GetModuleFileName(NULL, buf, bufLen);
|
||||
u32 copiedLen = GetModuleFileNameA(NULL, buf, bufLen);
|
||||
if (copiedLen == bufLen) return -1;
|
||||
|
||||
// NOTE: Should always work if GetModuleFileName works and we're running an
|
||||
|
@ -15,8 +15,8 @@
|
||||
#define HANDMADE_MATH_CPP_MODE
|
||||
#include "tests/HandmadeMath.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat)
|
||||
{
|
||||
f32 *hmmMatf = (f32 *)&hmmMat;
|
||||
@ -25,21 +25,23 @@ void HandmadeMathVerifyMat4(DqnMat4 dqnMat, hmm_mat4 hmmMat)
|
||||
const u32 EXPECTED_SIZE = 16;
|
||||
u32 totalSize = DQN_ARRAY_COUNT(dqnMat.e) * DQN_ARRAY_COUNT(dqnMat.e[0]);
|
||||
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++)
|
||||
{
|
||||
const f32 EPSILON = 0.001f;
|
||||
f32 diff = hmmMatf[i] - dqnMatf[i];
|
||||
diff = DQN_ABS(diff);
|
||||
DQN_ASSERT_MSG(diff < EPSILON, "hmmMatf[%d]: %f, dqnMatf[%d]: %f\n", i,
|
||||
hmmMatf[i], i, dqnMatf[i]);
|
||||
DQN_ASSERT_MSG(diff < EPSILON, "hmmMatf[%d]: %f, dqnMatf[%d]: %f\n", i, hmmMatf[i], i,
|
||||
dqnMatf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void HandmadeMathTest()
|
||||
{
|
||||
// Test Perspective/Projection matrix values
|
||||
if (1)
|
||||
{
|
||||
f32 aspectRatio = 1;
|
||||
DqnMat4 dqnPerspective = DqnMat4_Perspective(90, aspectRatio, 100, 1000);
|
||||
@ -50,6 +52,7 @@ void HandmadeMathTest()
|
||||
}
|
||||
|
||||
// Test Mat4 translate * scale
|
||||
if (1)
|
||||
{
|
||||
hmm_vec3 hmmVec = HMM_Vec3i(1, 2, 3);
|
||||
DqnV3 dqnVec = DqnV3_3i(1, 2, 3);
|
||||
@ -77,8 +80,8 @@ void HandmadeMathTest()
|
||||
hmm_mat4 hmmTSMatrix = HMM_MultiplyMat4(hmmTranslate, hmmScale);
|
||||
HandmadeMathVerifyMat4(dqnTSMatrix, hmmTSMatrix);
|
||||
|
||||
|
||||
// Test Mat4 * MulV4
|
||||
if (1)
|
||||
{
|
||||
DqnV4 dqnV4 = DqnV4_4f(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.w == hmmResult.W);
|
||||
|
||||
printf(
|
||||
"HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n");
|
||||
printf("HandmadeMathTest(): Mat4 * MulV4: Completed successfully\n");
|
||||
}
|
||||
|
||||
printf("HandmadeMathTest(): Translate/Scale/Rotate Mat4_Mul: Completed successfully\n");
|
||||
}
|
||||
|
||||
// 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));
|
||||
hmm_mat4 hmmViewMatrix =
|
||||
@ -107,12 +110,13 @@ void HandmadeMathTest()
|
||||
HandmadeMathVerifyMat4(dqnViewMatrix, hmmViewMatrix);
|
||||
printf("HandmadeMathTest(): LookAt: Completed successfully\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void StringsTest()
|
||||
{
|
||||
{ // Char Checks
|
||||
// Char Checks
|
||||
if (1)
|
||||
{
|
||||
DQN_ASSERT(DqnChar_IsAlpha('a') == true);
|
||||
DQN_ASSERT(DqnChar_IsAlpha('A') == true);
|
||||
DQN_ASSERT(DqnChar_IsAlpha('0') == false);
|
||||
@ -146,12 +150,15 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// String Checks
|
||||
if (1)
|
||||
{
|
||||
// strcmp
|
||||
if (1)
|
||||
{
|
||||
const char *const a = "str_a";
|
||||
|
||||
// Check simple compares
|
||||
if (1)
|
||||
{
|
||||
DQN_ASSERT(DqnStr_Cmp(a, "str_a") == +0);
|
||||
DQN_ASSERT(DqnStr_Cmp(a, "str_b") == -1);
|
||||
@ -164,6 +171,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Check ops against null
|
||||
if (1)
|
||||
{
|
||||
DQN_ASSERT(DqnStr_Cmp(NULL, NULL) != +0);
|
||||
DQN_ASSERT(DqnStr_Cmp(a, NULL) != +0);
|
||||
@ -174,6 +182,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// strlen
|
||||
if (1)
|
||||
{
|
||||
const char *const a = "str_a";
|
||||
DQN_ASSERT(DqnStr_Len(a) == 5);
|
||||
@ -190,11 +199,14 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// strncpy
|
||||
if (1)
|
||||
{
|
||||
if (1)
|
||||
{
|
||||
const char *const a = "str_a";
|
||||
char b[10] = {};
|
||||
// Check copy into empty array
|
||||
if (1)
|
||||
{
|
||||
char *result = DqnStr_Copy(b, a, DqnStr_Len(a));
|
||||
DQN_ASSERT(DqnStr_Cmp(b, "str_a") == 0);
|
||||
@ -204,6 +216,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Check copy into array offset, overlap with old results
|
||||
if (1)
|
||||
{
|
||||
char *newResult = DqnStr_Copy(&b[1], a, DqnStr_Len(a));
|
||||
DQN_ASSERT(DqnStr_Cmp(newResult, "str_a") == 0);
|
||||
@ -219,8 +232,10 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// StrReverse
|
||||
if (1)
|
||||
{
|
||||
// Basic reverse operations
|
||||
if (1)
|
||||
{
|
||||
char a[] = "aba";
|
||||
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
|
||||
@ -240,6 +255,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Try reverse empty string
|
||||
if (1)
|
||||
{
|
||||
char a[] = "";
|
||||
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
|
||||
@ -247,6 +263,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Try reverse single char string
|
||||
if (1)
|
||||
{
|
||||
char a[] = "a";
|
||||
DQN_ASSERT(DqnStr_Reverse(a, DqnStr_Len(a)) == true);
|
||||
@ -256,13 +273,13 @@ void StringsTest()
|
||||
DQN_ASSERT(DqnStr_Cmp(a, "a") == 0);
|
||||
}
|
||||
|
||||
printf(
|
||||
"StringsTest(): StrReverse: Completed successfully\n");
|
||||
printf("StringsTest(): StrReverse: Completed successfully\n");
|
||||
}
|
||||
|
||||
// const u64 LARGEST_NUM = (u64)-1;
|
||||
const i64 SMALLEST_NUM = LLONG_MIN;
|
||||
// StrToI64
|
||||
if (1)
|
||||
{
|
||||
const char *const a = "123";
|
||||
DQN_ASSERT(Dqn_StrToI64(a, DqnStr_Len(a)) == 123);
|
||||
@ -277,7 +294,7 @@ void StringsTest()
|
||||
const char *const d = "+123";
|
||||
DQN_ASSERT(Dqn_StrToI64(d, DqnStr_Len(d)) == 123);
|
||||
|
||||
// TODO(doyle): Unsigned conversion
|
||||
// TODO(doyle): Unsigned conversion
|
||||
#if 0
|
||||
char *e = "18446744073709551615";
|
||||
DQN_ASSERT((u64)(Dqn_StrToI64(e, DqnStr_Len(e))) == LARGEST_NUM);
|
||||
@ -290,6 +307,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// i64 to str
|
||||
if (1)
|
||||
{
|
||||
char a[DQN_64BIT_NUM_MAX_STR_SIZE] = {};
|
||||
Dqn_I64ToStr(+100, a, DQN_ARRAY_COUNT(a));
|
||||
@ -318,6 +336,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// StrToF32
|
||||
if (1)
|
||||
{
|
||||
const f32 EPSILON = 0.001f;
|
||||
const char a[] = "-0.66248";
|
||||
@ -394,24 +413,25 @@ void StringsTest()
|
||||
printf("StringsTest(): StrToF32: Completed successfully\n");
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
|
||||
if (1)
|
||||
{
|
||||
const char *const a = "Microsoft";
|
||||
const char *const b = "icro";
|
||||
i32 lenA = DqnStr_Len(a);
|
||||
i32 lenB = DqnStr_Len(b);
|
||||
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, b, lenB) == true);
|
||||
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, "iro",
|
||||
DqnStr_Len("iro")) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring(a, lenA, "iro", DqnStr_Len("iro")) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring(b, lenB, a, lenA) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring("iro", DqnStr_Len("iro"), a,
|
||||
lenA) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring("iro", DqnStr_Len("iro"), a, lenA) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring("", 0, "iro", 4) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring("", 0, "", 0) == false);
|
||||
DQN_ASSERT(DqnStr_HasSubstring(NULL, 0, NULL, 0) == false);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
const char *const a = "Micro";
|
||||
const char *const b = "irob";
|
||||
@ -425,8 +445,10 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// UCS <-> UTF8 Checks
|
||||
if (1)
|
||||
{
|
||||
// Test ascii characters
|
||||
if (1)
|
||||
{
|
||||
u32 codepoint = '@';
|
||||
u32 string[1] = {};
|
||||
@ -441,6 +463,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Test 2 byte characters
|
||||
if (1)
|
||||
{
|
||||
u32 codepoint = 0x278;
|
||||
u32 string[1] = {};
|
||||
@ -455,6 +478,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Test 3 byte characters
|
||||
if (1)
|
||||
{
|
||||
u32 codepoint = 0x0A0A;
|
||||
u32 string[1] = {};
|
||||
@ -469,6 +493,7 @@ void StringsTest()
|
||||
}
|
||||
|
||||
// Test 4 byte characters
|
||||
if (1)
|
||||
{
|
||||
u32 codepoint = 0x10912;
|
||||
u32 string[1] = {};
|
||||
@ -482,6 +507,7 @@ void StringsTest()
|
||||
DQN_ASSERT(bytesUsed == 4);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
u32 codepoint = 0x10912;
|
||||
u32 bytesUsed = Dqn_UCSToUTF8(NULL, codepoint);
|
||||
@ -497,26 +523,35 @@ void StringsTest()
|
||||
printf("StringsTest(): Completed successfully\n");
|
||||
}
|
||||
|
||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
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(): Completed successfully\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void RandomTest() {
|
||||
void RandomTest()
|
||||
{
|
||||
|
||||
DqnRandPCGState pcg;
|
||||
DqnRnd_PCGInit(&pcg);
|
||||
@ -537,7 +572,9 @@ void RandomTest() {
|
||||
|
||||
void MathTest()
|
||||
{
|
||||
if (1)
|
||||
{ // Lerp
|
||||
if (1)
|
||||
{
|
||||
f32 start = 10;
|
||||
f32 t = 0.5f;
|
||||
@ -545,6 +582,7 @@ void MathTest()
|
||||
DQN_ASSERT(DqnMath_Lerp(start, t, end) == 15);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
f32 start = 10;
|
||||
f32 t = 2.0f;
|
||||
@ -555,6 +593,7 @@ void MathTest()
|
||||
printf("MathTest(): Lerp: Completed successfully\n");
|
||||
}
|
||||
|
||||
if (1)
|
||||
{ // sqrtf
|
||||
DQN_ASSERT(DqnMath_Sqrtf(4.0f) == 2.0f);
|
||||
printf("MathTest(): Sqrtf: Completed successfully\n");
|
||||
@ -565,9 +604,11 @@ void MathTest()
|
||||
|
||||
void VecTest()
|
||||
{
|
||||
if (1)
|
||||
{ // V2
|
||||
|
||||
// V2 Creating
|
||||
if (1)
|
||||
{
|
||||
DqnV2 vec = DqnV2_2f(5.5f, 5.0f);
|
||||
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f);
|
||||
@ -575,6 +616,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V2 with 2 integers
|
||||
if (1)
|
||||
{
|
||||
DqnV2 vec = DqnV2_2i(3, 5);
|
||||
DQN_ASSERT(vec.x == 3 && vec.y == 5.0f);
|
||||
@ -582,6 +624,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V2 Arithmetic
|
||||
if (1)
|
||||
{
|
||||
DqnV2 vecA = DqnV2_2f(5, 10);
|
||||
DqnV2 vecB = DqnV2_2i(2, 3);
|
||||
@ -606,6 +649,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// Test operator overloading
|
||||
if (1)
|
||||
{
|
||||
DqnV2 vecA = DqnV2_2f(5, 10);
|
||||
DqnV2 vecB = DqnV2_2i(2, 3);
|
||||
@ -633,6 +677,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V2 Properties
|
||||
if (1)
|
||||
{
|
||||
const f32 EPSILON = 0.001f;
|
||||
DqnV2 a = DqnV2_2f(0, 0);
|
||||
@ -649,8 +694,10 @@ void VecTest()
|
||||
f32 normY = b.y / 5.0f;
|
||||
f32 diffNormX = normalised.x - normX;
|
||||
f32 diffNormY = normalised.y - normY;
|
||||
DQN_ASSERT_MSG(diffNormX < EPSILON, "normalised.x: %f, normX: %f\n", normalised.x, normX);
|
||||
DQN_ASSERT_MSG(diffNormY < EPSILON, "normalised.y: %f, normY: %f\n", normalised.y, normY);
|
||||
DQN_ASSERT_MSG(diffNormX < EPSILON, "normalised.x: %f, normX: %f\n", normalised.x,
|
||||
normX);
|
||||
DQN_ASSERT_MSG(diffNormY < EPSILON, "normalised.y: %f, normY: %f\n", normalised.y,
|
||||
normY);
|
||||
|
||||
DqnV2 c = DqnV2_2f(3.5f, 8.0f);
|
||||
DQN_ASSERT(DqnV2_Overlaps(b, c) == true);
|
||||
@ -660,6 +707,7 @@ void VecTest()
|
||||
DQN_ASSERT(DqnV2_Dot(c, d) == 0);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{ // constrain_to_ratio
|
||||
DqnV2 ratio = DqnV2_2f(16, 9);
|
||||
DqnV2 dim = DqnV2_2f(2000, 1080);
|
||||
@ -670,9 +718,11 @@ void VecTest()
|
||||
printf("VecTest(): Vec2: Completed successfully\n");
|
||||
}
|
||||
|
||||
if (1)
|
||||
{ // V3
|
||||
|
||||
// V3i Creating
|
||||
if (1)
|
||||
{
|
||||
DqnV3 vec = DqnV3_3f(5.5f, 5.0f, 5.875f);
|
||||
DQN_ASSERT(vec.x == 5.5f && vec.y == 5.0f && vec.z == 5.875f);
|
||||
@ -680,6 +730,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V3i Creating
|
||||
if (1)
|
||||
{
|
||||
DqnV3 vec = DqnV3_3i(3, 4, 5);
|
||||
DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5);
|
||||
@ -687,6 +738,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V3 Arithmetic
|
||||
if (1)
|
||||
{
|
||||
DqnV3 vecA = DqnV3_3f(5, 10, 15);
|
||||
DqnV3 vecB = DqnV3_3f(2, 3, 6);
|
||||
@ -713,6 +765,7 @@ void VecTest()
|
||||
DQN_ASSERT(DqnV3_Equals(cross, DqnV3_3f(15, 0, -5)) == true);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
DqnV3 vecA = DqnV3_3f(5, 10, 15);
|
||||
DqnV3 vecB = DqnV3_3f(2, 3, 6);
|
||||
@ -742,9 +795,11 @@ void VecTest()
|
||||
printf("VecTest(): Vec3: Completed successfully\n");
|
||||
}
|
||||
|
||||
if (1)
|
||||
{ // V4
|
||||
|
||||
// V4 Creating
|
||||
if (1)
|
||||
{
|
||||
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);
|
||||
@ -752,6 +807,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V4i Creating
|
||||
if (1)
|
||||
{
|
||||
DqnV4 vec = DqnV4_4i(3, 4, 5, 6);
|
||||
DQN_ASSERT(vec.x == 3 && vec.y == 4 && vec.z == 5 && vec.w == 6);
|
||||
@ -759,6 +815,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// V4 Arithmetic
|
||||
if (1)
|
||||
{
|
||||
DqnV4 vecA = DqnV4_4f(5, 10, 15, 20);
|
||||
DqnV4 vecB = DqnV4_4i(2, 3, 6, 8);
|
||||
@ -782,6 +839,7 @@ void VecTest()
|
||||
DQN_ASSERT(dotResult == 107);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
DqnV4 vecA = DqnV4_4f(5, 10, 15, 20);
|
||||
DqnV4 vecB = DqnV4_4i(2, 3, 6, 8);
|
||||
@ -812,8 +870,10 @@ void VecTest()
|
||||
}
|
||||
|
||||
// Rect
|
||||
if (1)
|
||||
{
|
||||
// Test rect init functions
|
||||
if (1)
|
||||
{
|
||||
DqnRect rect4f = DqnRect_4f(1.1f, 2.2f, 3.3f, 4.4f);
|
||||
DqnRect rect4i = DqnRect_4i(1, 2, 3, 4);
|
||||
@ -829,11 +889,12 @@ void VecTest()
|
||||
}
|
||||
|
||||
// Test rect get size function
|
||||
if (1)
|
||||
{
|
||||
// Test float rect
|
||||
if (1)
|
||||
{
|
||||
DqnRect rect =
|
||||
DqnRect_Init(DqnV2_2f(-10, -10), DqnV2_2f(20, 20));
|
||||
DqnRect rect = DqnRect_Init(DqnV2_2f(-10, -10), DqnV2_2f(20, 20));
|
||||
|
||||
f32 width, height;
|
||||
DqnRect_GetSize2f(rect, &width, &height);
|
||||
@ -845,9 +906,9 @@ void VecTest()
|
||||
}
|
||||
|
||||
// Test rect with float values and GetSize as 2 integers
|
||||
if (1)
|
||||
{
|
||||
DqnRect rect = DqnRect_Init(DqnV2_2f(-10.5f, -10.5f),
|
||||
DqnV2_2f(20.5f, 20.5f));
|
||||
DqnRect rect = DqnRect_Init(DqnV2_2f(-10.5f, -10.5f), DqnV2_2f(20.5f, 20.5f));
|
||||
i32 width, height;
|
||||
DqnRect_GetSize2i(rect, &width, &height);
|
||||
DQN_ASSERT(width == 20);
|
||||
@ -867,12 +928,14 @@ void VecTest()
|
||||
DQN_ASSERT(clipResult.max.x == 10 && clipResult.max.y == 10);
|
||||
|
||||
// Test shifting rect
|
||||
if (1)
|
||||
{
|
||||
DqnRect shiftedRect = DqnRect_Move(rect, DqnV2_2f(10, 0));
|
||||
DQN_ASSERT(DqnV2_Equals(shiftedRect.min, DqnV2_2f(0, -10)));
|
||||
DQN_ASSERT(DqnV2_Equals(shiftedRect.max, DqnV2_2f(20, 10)));
|
||||
|
||||
// Ensure dimensions have remained the same
|
||||
if (1)
|
||||
{
|
||||
f32 width, height;
|
||||
DqnRect_GetSize2f(shiftedRect, &width, &height);
|
||||
@ -884,6 +947,7 @@ void VecTest()
|
||||
}
|
||||
|
||||
// Test rect contains p
|
||||
if (1)
|
||||
{
|
||||
DqnV2 inP = DqnV2_2f(5, 5);
|
||||
DqnV2 outP = DqnV2_2f(100, 100);
|
||||
@ -900,12 +964,14 @@ void VecTest()
|
||||
|
||||
void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
|
||||
{
|
||||
if (1)
|
||||
{
|
||||
DQN_ASSERT(DqnArray_Init(array, 1, memAPI));
|
||||
DQN_ASSERT(array->capacity == 1);
|
||||
DQN_ASSERT(array->count == 0);
|
||||
|
||||
// Test basic insert
|
||||
if (1)
|
||||
{
|
||||
DqnV2 va = DqnV2_2f(5, 10);
|
||||
DQN_ASSERT(DqnArray_Push(array, va));
|
||||
@ -918,6 +984,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
|
||||
}
|
||||
|
||||
// Test array resizing and freeing
|
||||
if (1)
|
||||
{
|
||||
DqnV2 va = DqnV2_2f(10, 15);
|
||||
DQN_ASSERT(DqnArray_Push(array, va));
|
||||
@ -976,6 +1043,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
|
||||
}
|
||||
DQN_ASSERT(DqnArray_Free(array));
|
||||
|
||||
if (1)
|
||||
{
|
||||
DQN_ASSERT(DqnArray_Init(array, 1, memAPI));
|
||||
DQN_ASSERT(array->capacity == 1);
|
||||
@ -983,6 +1051,7 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
|
||||
}
|
||||
DQN_ASSERT(DqnArray_Free(array));
|
||||
|
||||
if (1)
|
||||
{
|
||||
DqnV2 a = DqnV2_2f(1, 2);
|
||||
DqnV2 b = DqnV2_2f(3, 4);
|
||||
@ -1027,10 +1096,10 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
|
||||
DQN_ASSERT(DqnArray_Clear(array));
|
||||
DQN_ASSERT(array->capacity == 16);
|
||||
DQN_ASSERT(array->count == 0);
|
||||
|
||||
}
|
||||
DQN_ASSERT(DqnArray_Free(array));
|
||||
|
||||
if (1)
|
||||
{
|
||||
DqnV2 a = DqnV2_2f(1, 2);
|
||||
DqnV2 b = DqnV2_2f(3, 4);
|
||||
@ -1066,7 +1135,6 @@ void ArrayTestMemAPIInternal(DqnArray<DqnV2> *array, DqnMemAPI memAPI)
|
||||
}
|
||||
DQN_ASSERT(DqnArray_Free(array));
|
||||
printf("ArrayTestMemAPIInternal(): Completed successfully\n");
|
||||
|
||||
}
|
||||
|
||||
void ArrayTest()
|
||||
@ -1079,6 +1147,7 @@ void ArrayTest()
|
||||
void MemStackTest()
|
||||
{
|
||||
// Test over allocation, alignments, temp regions
|
||||
if (1)
|
||||
{
|
||||
size_t allocSize = DQN_KILOBYTE(1);
|
||||
DqnMemStack stack = {};
|
||||
@ -1096,8 +1165,7 @@ void MemStackTest()
|
||||
DQN_ASSERT(resultAddrA % ALIGNMENT == 0);
|
||||
DQN_ASSERT(stack.block && stack.block->memory);
|
||||
DQN_ASSERT(stack.block->size == allocSize);
|
||||
DQN_ASSERT(stack.block->used >= sizeA + 0 &&
|
||||
stack.block->used <= sizeA + 3);
|
||||
DQN_ASSERT(stack.block->used >= sizeA + 0 && stack.block->used <= sizeA + 3);
|
||||
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
|
||||
DQN_ASSERT(resultA);
|
||||
u8 *ptrA = (u8 *)resultA;
|
||||
@ -1116,8 +1184,7 @@ void MemStackTest()
|
||||
// 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
|
||||
// will reflect just this allocation.
|
||||
DQN_ASSERT(stack.block->used >= sizeB + 0 &&
|
||||
stack.block->used <= sizeB + 3);
|
||||
DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
|
||||
DQN_ASSERT(resultB);
|
||||
u8 *ptrB = (u8 *)resultB;
|
||||
for (u32 i = 0; i < sizeB; i++)
|
||||
@ -1139,8 +1206,7 @@ void MemStackTest()
|
||||
u64 resultAddrC = *((u64 *)resultC);
|
||||
DQN_ASSERT(resultAddrC % ALIGNMENT == 0);
|
||||
DQN_ASSERT(stack.block != blockB && stack.block != blockA);
|
||||
DQN_ASSERT(stack.block->used >= sizeC + 0 &&
|
||||
stack.block->used <= sizeC + 3);
|
||||
DQN_ASSERT(stack.block->used >= sizeC + 0 && stack.block->used <= sizeC + 3);
|
||||
DQN_ASSERT(stack.tempRegionCount == 1);
|
||||
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
|
||||
|
||||
@ -1166,8 +1232,7 @@ void MemStackTest()
|
||||
DqnMemStackTempRegion_End(tempBuffer);
|
||||
DQN_ASSERT(stack.block && stack.block->memory);
|
||||
DQN_ASSERT(stack.block->size == sizeB);
|
||||
DQN_ASSERT(stack.block->used >= sizeB + 0 &&
|
||||
stack.block->used <= sizeB + 3);
|
||||
DQN_ASSERT(stack.block->used >= sizeB + 0 && stack.block->used <= sizeB + 3);
|
||||
DQN_ASSERT(stack.tempRegionCount == 0);
|
||||
DQN_ASSERT(resultB);
|
||||
|
||||
@ -1194,15 +1259,14 @@ void MemStackTest()
|
||||
}
|
||||
|
||||
// Test stack with fixed memory does not allocate more
|
||||
if (1)
|
||||
{
|
||||
u8 memory[DQN_KILOBYTE(1)] = {};
|
||||
DqnMemStack stack = {};
|
||||
const u32 ALIGNMENT = 4;
|
||||
DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory),
|
||||
ALIGNMENT);
|
||||
DqnMemStack_InitWithFixedMem(&stack, memory, DQN_ARRAY_COUNT(memory), ALIGNMENT);
|
||||
DQN_ASSERT(stack.block && stack.block->memory);
|
||||
DQN_ASSERT(stack.block->size ==
|
||||
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
|
||||
DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
|
||||
DQN_ASSERT(stack.block->used == 0);
|
||||
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
|
||||
|
||||
@ -1213,14 +1277,14 @@ void MemStackTest()
|
||||
DqnMemStack_Free(&stack);
|
||||
DqnMemStack_FreeLastBlock(&stack);
|
||||
DQN_ASSERT(stack.block && stack.block->memory);
|
||||
DQN_ASSERT(stack.block->size ==
|
||||
DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
|
||||
DQN_ASSERT(stack.block->size == DQN_ARRAY_COUNT(memory) - sizeof(DqnMemStackBlock));
|
||||
DQN_ASSERT(stack.block->used == 0);
|
||||
DQN_ASSERT(stack.byteAlign == ALIGNMENT);
|
||||
}
|
||||
|
||||
// Test stack with fixed size, allocates once from platform but does not
|
||||
// grow further
|
||||
if (1)
|
||||
{
|
||||
size_t allocSize = DQN_KILOBYTE(1);
|
||||
DqnMemStack stack = {};
|
||||
@ -1243,6 +1307,7 @@ void MemStackTest()
|
||||
}
|
||||
|
||||
// Test freeing/clear block and alignment
|
||||
if (1)
|
||||
{
|
||||
size_t firstBlockSize = DQN_KILOBYTE(1);
|
||||
DqnMemStack stack = {};
|
||||
@ -1320,7 +1385,8 @@ void MemStackTest()
|
||||
for (u32 i = 0; i < fourthBlockSize; i++)
|
||||
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(secondBlock->prevBlock == firstBlock);
|
||||
DQN_ASSERT(thirdBlock->prevBlock == secondBlock);
|
||||
@ -1335,7 +1401,7 @@ void MemStackTest()
|
||||
fakeBlock.used = 0;
|
||||
DQN_ASSERT(!DqnMemStack_FreeStackBlock(&stack, &fakeBlock));
|
||||
|
||||
//Ensure that the actual blocks are still valid and freeing did nothing
|
||||
// Ensure that the actual blocks are still valid and freeing did nothing
|
||||
DQN_ASSERT(firstBlock->size == firstBlockSize);
|
||||
DQN_ASSERT(secondBlock->size == secondBlockSize);
|
||||
DQN_ASSERT(thirdBlock->size == thirdBlockSize);
|
||||
@ -1346,7 +1412,8 @@ void MemStackTest()
|
||||
DQN_ASSERT(thirdBlock->used == thirdBlockSize);
|
||||
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(secondBlock->prevBlock == firstBlock);
|
||||
DQN_ASSERT(thirdBlock->prevBlock == secondBlock);
|
||||
@ -1427,6 +1494,7 @@ void MemStackTest()
|
||||
}
|
||||
|
||||
// Test pop
|
||||
if (1)
|
||||
{
|
||||
DqnMemStack stack = {};
|
||||
DqnMemStack_Init(&stack, DQN_KILOBYTE(1), true);
|
||||
@ -1440,14 +1508,15 @@ void MemStackTest()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DQN_PLATFORM_LAYER
|
||||
#ifdef DQN_XPLATFORM_LAYER
|
||||
void FileTest()
|
||||
{
|
||||
// File i/o
|
||||
if (1)
|
||||
{
|
||||
|
||||
// Test file open
|
||||
if (1)
|
||||
{
|
||||
const char *const FILE_TO_OPEN = ".clang-format";
|
||||
u32 expectedSize = 0;
|
||||
@ -1460,9 +1529,8 @@ void FileTest()
|
||||
|
||||
#elif defined(DQN_WIN32_IMPLEMENTATION)
|
||||
{
|
||||
HANDLE handle =
|
||||
CreateFile(FILE_TO_OPEN, GENERIC_READ, 0, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
HANDLE handle = CreateFile(FILE_TO_OPEN, GENERIC_READ, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DqnWin32_DisplayLastError("CreateFile() failed");
|
||||
@ -1478,29 +1546,27 @@ void FileTest()
|
||||
#endif
|
||||
|
||||
DqnFile file = {};
|
||||
DQN_ASSERT(DqnFile_Open(
|
||||
".clang-format", &file,
|
||||
DQN_ASSERT(DqnFile_Open(".clang-format", &file,
|
||||
(DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read),
|
||||
DqnFileAction_OpenOnly));
|
||||
|
||||
DQN_ASSERT_MSG(file.size == expectedSize,
|
||||
"DqnFileOpen() failed: file.size: %d, expected:%d\n",
|
||||
file.size, expectedSize);
|
||||
"DqnFileOpen() failed: file.size: %d, expected:%d\n", file.size,
|
||||
expectedSize);
|
||||
|
||||
u8 *buffer = (u8 *)calloc(1, (size_t)file.size * sizeof(u8));
|
||||
DQN_ASSERT(DqnFile_Read(file, buffer, (u32)file.size) == file.size);
|
||||
free(buffer);
|
||||
|
||||
DqnFile_Close(&file);
|
||||
DQN_ASSERT(!file.handle && file.size == 0 &&
|
||||
file.permissionFlags == 0);
|
||||
DQN_ASSERT(!file.handle && file.size == 0 && file.permissionFlags == 0);
|
||||
}
|
||||
|
||||
// Test invalid file
|
||||
if (1)
|
||||
{
|
||||
DqnFile file = {};
|
||||
DQN_ASSERT(!DqnFile_Open(
|
||||
"asdljasdnel;kajdf", &file,
|
||||
DQN_ASSERT(!DqnFile_Open("asdljasdnel;kajdf", &file,
|
||||
(DqnFilePermissionFlag_Write | DqnFilePermissionFlag_Read),
|
||||
DqnFileAction_OpenOnly));
|
||||
DQN_ASSERT(file.size == 0);
|
||||
@ -1508,25 +1574,22 @@ void FileTest()
|
||||
DQN_ASSERT(!file.handle);
|
||||
printf("FileTest(): FileIO: Completed successfully\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Write Test
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
if (1)
|
||||
{
|
||||
const char *fileNames[] = {"dqn_1", "dqn_2", "dqn_3", "dqn_4", "dqn_5"};
|
||||
const char *writeData[] = {"1234", "2468", "36912", "481216",
|
||||
"5101520"};
|
||||
const char *writeData[] = {"1234", "2468", "36912", "481216", "5101520"};
|
||||
DqnFile files[DQN_ARRAY_COUNT(fileNames)] = {};
|
||||
|
||||
// Write data out to some files
|
||||
for (u32 i = 0; i < DQN_ARRAY_COUNT(fileNames); i++)
|
||||
{
|
||||
u32 permissions =
|
||||
DqnFilePermissionFlag_Read | DqnFilePermissionFlag_Write;
|
||||
if (!DqnFile_Open(fileNames[i], files + i, permissions,
|
||||
DqnFileAction_ClearIfExist))
|
||||
u32 permissions = DqnFilePermissionFlag_Read | DqnFilePermissionFlag_Write;
|
||||
if (!DqnFile_Open(fileNames[i], files + i, permissions, DqnFileAction_ClearIfExist))
|
||||
{
|
||||
bool result = DqnFile_Open(fileNames[i], files + i, permissions,
|
||||
DqnFileAction_CreateIfNotExist);
|
||||
@ -1547,8 +1610,7 @@ void FileTest()
|
||||
{
|
||||
u32 permissions = DqnFilePermissionFlag_Read;
|
||||
DqnFile *file = files + i;
|
||||
bool result = DqnFile_Open(fileNames[i], file, permissions,
|
||||
DqnFileAction_OpenOnly);
|
||||
bool result = DqnFile_Open(fileNames[i], file, permissions, DqnFileAction_OpenOnly);
|
||||
DQN_ASSERT(result);
|
||||
|
||||
u8 *buffer = (u8 *)DqnMemStack_Push(&memStack, file->size);
|
||||
@ -1572,13 +1634,14 @@ void FileTest()
|
||||
{
|
||||
DqnFile dummy = {};
|
||||
u32 permissions = DqnFilePermissionFlag_Read;
|
||||
bool fileExists = DqnFile_Open(fileNames[i], &dummy, permissions,
|
||||
DqnFileAction_OpenOnly);
|
||||
bool fileExists =
|
||||
DqnFile_Open(fileNames[i], &dummy, permissions, DqnFileAction_OpenOnly);
|
||||
DQN_ASSERT(!fileExists);
|
||||
}
|
||||
DqnMemStack_Free(&memStack);
|
||||
}
|
||||
|
||||
if (1)
|
||||
{
|
||||
u32 numFiles;
|
||||
#if defined(DQN_UNIX_IMPLEMENTATION)
|
||||
@ -1612,8 +1675,8 @@ FILE_SCOPE void JobQueueDebugCallbackIncrementCounter(DqnJobQueue *const queue,
|
||||
u32 number = globalDebugCounter;
|
||||
DqnLock_Release(&globalJobQueueLock);
|
||||
|
||||
printf("JobQueueDebugCallbackIncrementCounter(): Thread %d: Incrementing Number: %d\n", GetCurrentThreadId(),
|
||||
number);
|
||||
printf("JobQueueDebugCallbackIncrementCounter(): Thread %d: Incrementing Number: %d\n",
|
||||
GetCurrentThreadId(), number);
|
||||
}
|
||||
|
||||
FILE_SCOPE void JobQueueTest()
|
||||
@ -1632,8 +1695,8 @@ FILE_SCOPE void JobQueueTest()
|
||||
|
||||
void *jobQueueMem = DqnMemStack_Push(&memStack, requiredSize);
|
||||
DQN_ASSERT_HARD(jobQueueMem);
|
||||
DqnJobQueue *jobQueue = DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize,
|
||||
QUEUE_SIZE, totalThreads);
|
||||
DqnJobQueue *jobQueue =
|
||||
DqnJobQueue_InitWithMem(jobQueueMem, &requiredSize, QUEUE_SIZE, totalThreads);
|
||||
DQN_ASSERT_HARD(jobQueue);
|
||||
|
||||
DQN_ASSERT(DqnLock_Init(&globalJobQueueLock));
|
||||
@ -1653,8 +1716,7 @@ FILE_SCOPE void JobQueueTest()
|
||||
for (i32 i = 0; i < DQN_ARRAY_COUNT(globalDebugCounterMemoize); i++)
|
||||
DQN_ASSERT(globalDebugCounterMemoize[i]);
|
||||
|
||||
while (DqnJobQueue_TryExecuteNextJob(jobQueue) &&
|
||||
!DqnJobQueue_AllJobsComplete(jobQueue))
|
||||
while (DqnJobQueue_TryExecuteNextJob(jobQueue) && !DqnJobQueue_AllJobsComplete(jobQueue))
|
||||
;
|
||||
|
||||
printf("\nJobQueueTest(): Final incremented value: %d\n", globalDebugCounter);
|
||||
@ -1672,12 +1734,12 @@ int main(void)
|
||||
ArrayTest();
|
||||
MemStackTest();
|
||||
|
||||
#ifdef DQN_PLATFORM_LAYER
|
||||
#ifdef DQN_XPLATFORM_LAYER
|
||||
FileTest();
|
||||
OtherTest();
|
||||
#endif
|
||||
|
||||
#ifdef DQN_WIN32_IMPLEMENTATION
|
||||
OtherTest();
|
||||
JobQueueTest();
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user