Add darray remove operations
This commit is contained in:
parent
15220a9646
commit
9106f185a3
270
dqn.h
270
dqn.h
@ -72,6 +72,23 @@ typedef float f32;
|
|||||||
dqn_darray_free(uintArray);
|
dqn_darray_free(uintArray);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Typical operations should not require using the header directly, and it's
|
||||||
|
// recommended to use the API, but it can be used to have a faster way to track
|
||||||
|
// metadata.
|
||||||
|
typedef struct DqnDArrayHeader
|
||||||
|
{
|
||||||
|
u32 index;
|
||||||
|
u32 itemSize;
|
||||||
|
u32 capacity;
|
||||||
|
u32 signature;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
} DqnDArrayHeader;
|
||||||
|
|
||||||
|
// Returns the DArray header IF is a valid DArray
|
||||||
|
// Returns NULL IF not a valid DArray
|
||||||
|
DQN_FILE_SCOPE DqnDArrayHeader *dqn_darray_get_header(void *array);
|
||||||
|
|
||||||
// The init macro RETURNS a pointer to your type, you can index this as normal
|
// The init macro RETURNS a pointer to your type, you can index this as normal
|
||||||
// with array notation [].
|
// with array notation [].
|
||||||
// u32 type - The data type to initiate a dynamic array with
|
// u32 type - The data type to initiate a dynamic array with
|
||||||
@ -81,14 +98,36 @@ typedef float f32;
|
|||||||
|
|
||||||
// Pass in the pointer returned by DQN_DARRAY_INIT. If the pointer is not
|
// Pass in the pointer returned by DQN_DARRAY_INIT. If the pointer is not
|
||||||
// a valid DArray pointer, this will return 0.
|
// a valid DArray pointer, this will return 0.
|
||||||
DQN_FILE_SCOPE u32 dqn_darray_get_capacity(void *array);
|
DQN_FILE_SCOPE u32 dqn_darray_get_capacity(void *array);
|
||||||
DQN_FILE_SCOPE u32 dqn_darray_get_num_items(void *array);
|
DQN_FILE_SCOPE u32 dqn_darray_get_num_items(void *array);
|
||||||
|
|
||||||
|
// Returns true and array modified in-place IF
|
||||||
|
// - The capacity change was successful OR
|
||||||
|
// - The newCapacity is equal to current capacity (no changes).
|
||||||
|
// Returns false and array is unmodified IF
|
||||||
|
// - Invalid DArray passed in OR realloc failed OR
|
||||||
|
// - More items in array than new capacity
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_capacity_change(void **array, i32 newCapacity);
|
||||||
|
|
||||||
|
// WARNING: This macro currently asserts if it's unable to push elements
|
||||||
// void **array - the address of the pointer returned by DQN_DARRAY_INIT
|
// void **array - the address of the pointer returned by DQN_DARRAY_INIT
|
||||||
// void *item - a pointer to the object to insert
|
// void item - the object to insert
|
||||||
// The push macro RETURNS true/false if the push was successful or not.
|
#define DQN_DARRAY_PUSH(array, item) \
|
||||||
#define DQN_DARRAY_PUSH(array, item) \
|
{ \
|
||||||
dqn_darray_push_internal((void **)array, (void *)item, sizeof(*item))
|
if (dqn_darray_capacity_grow_if_need_internal((void **)array)) \
|
||||||
|
{ \
|
||||||
|
DqnDArrayHeader *header = dqn_darray_get_header(*array); \
|
||||||
|
*array[header->index++] = item; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
DQN_ASSERT(DQN_INVALID_CODE_PATH); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_clear (void *array);
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_remove (void *array, u32 index);
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_remove_stable(void *array, u32 index);
|
||||||
|
|
||||||
// Pass in the pointer returned by DQN_DARRAY_INIT. Returns if the free was
|
// Pass in the pointer returned by DQN_DARRAY_INIT. Returns if the free was
|
||||||
// successful. This will return false if the array is not a valid DArray and
|
// successful. This will return false if the array is not a valid DArray and
|
||||||
@ -165,7 +204,7 @@ typedef union DqnV4
|
|||||||
} DqnV4;
|
} DqnV4;
|
||||||
|
|
||||||
// Create a vector using ints and typecast to floats
|
// Create a vector using ints and typecast to floats
|
||||||
DQN_FILE_SCOPE DqnV4 dqn_v4i(i32 x, i32 y, i32 z);
|
DQN_FILE_SCOPE DqnV4 dqn_v4i(i32 x, i32 y, i32 z, f32 w);
|
||||||
DQN_FILE_SCOPE DqnV4 dqn_v4 (f32 x, f32 y, f32 z, f32 w);
|
DQN_FILE_SCOPE DqnV4 dqn_v4 (f32 x, f32 y, f32 z, f32 w);
|
||||||
|
|
||||||
DQN_FILE_SCOPE DqnV4 dqn_v4_add (DqnV4 a, DqnV4 b);
|
DQN_FILE_SCOPE DqnV4 dqn_v4_add (DqnV4 a, DqnV4 b);
|
||||||
@ -230,6 +269,12 @@ DQN_FILE_SCOPE void dqn_i32_to_str (i32 value, char *buf, i32 bufSize);
|
|||||||
DQN_FILE_SCOPE u32 dqn_ucs_to_utf8(u32 *dest, u32 character);
|
DQN_FILE_SCOPE u32 dqn_ucs_to_utf8(u32 *dest, u32 character);
|
||||||
DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character);
|
DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Win32 Specific
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
DQN_FILE_SCOPE bool dqn_win32_utf8_to_wchar(char *in, wchar_t *out, i32 outLen);
|
||||||
|
DQN_FILE_SCOPE bool dqn_win32_wchar_to_utf8(wchar_t *in, char *out, i32 outLen);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// File Operations
|
// File Operations
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -301,27 +346,17 @@ DQN_FILE_SCOPE i32 dqn_rnd_pcg_range(DqnRandPCGState *pcg, i32 min, i32 max);
|
|||||||
// DArray - Dynamic Array
|
// DArray - Dynamic Array
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#define DQN_DARRAY_SIGNATURE_INTERNAL 0xAC83DB81
|
#define DQN_DARRAY_SIGNATURE_INTERNAL 0xAC83DB81
|
||||||
typedef struct DqnDArrayInternal
|
|
||||||
{
|
|
||||||
u32 index;
|
|
||||||
u32 itemSize;
|
|
||||||
u32 capacity;
|
|
||||||
u32 signature;
|
|
||||||
|
|
||||||
void *data;
|
|
||||||
} DqnDArrayInternal;
|
|
||||||
|
|
||||||
FILE_SCOPE void *dqn_darray_init_internal(u32 itemSize, u32 startingCapacity)
|
FILE_SCOPE void *dqn_darray_init_internal(u32 itemSize, u32 startingCapacity)
|
||||||
{
|
{
|
||||||
if (startingCapacity <= 0 || itemSize == 0) return NULL;
|
if (startingCapacity <= 0 || itemSize == 0) return NULL;
|
||||||
|
|
||||||
u32 metadataSize = sizeof(DqnDArrayInternal);
|
u32 metadataSize = sizeof(DqnDArrayHeader);
|
||||||
u32 storageSize = itemSize * startingCapacity;
|
u32 storageSize = itemSize * startingCapacity;
|
||||||
|
|
||||||
void *memory = calloc(1, metadataSize + storageSize);
|
void *memory = calloc(1, metadataSize + storageSize);
|
||||||
if (!memory) return NULL;
|
if (!memory) return NULL;
|
||||||
|
|
||||||
DqnDArrayInternal *array = (DqnDArrayInternal *)memory;
|
DqnDArrayHeader *array = (DqnDArrayHeader *)memory;
|
||||||
array->signature = DQN_DARRAY_SIGNATURE_INTERNAL;
|
array->signature = DQN_DARRAY_SIGNATURE_INTERNAL;
|
||||||
array->itemSize = itemSize;
|
array->itemSize = itemSize;
|
||||||
array->capacity = startingCapacity;
|
array->capacity = startingCapacity;
|
||||||
@ -330,36 +365,65 @@ FILE_SCOPE void *dqn_darray_init_internal(u32 itemSize, u32 startingCapacity)
|
|||||||
return array->data;
|
return array->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_SCOPE DqnDArrayInternal *dqn_darray_get_header_internal(void *array)
|
DQN_FILE_SCOPE DqnDArrayHeader *dqn_darray_get_header(void *array)
|
||||||
{
|
{
|
||||||
if (!array) return NULL;
|
if (!array) return NULL;
|
||||||
|
|
||||||
DqnDArrayInternal *result = (DqnDArrayInternal *)((u8 *)array - sizeof(DqnDArrayInternal));
|
DqnDArrayHeader *result = (DqnDArrayHeader *)((u8 *)array - sizeof(DqnDArrayHeader));
|
||||||
if (result->signature != DQN_DARRAY_SIGNATURE_INTERNAL) return 0;
|
if (result->signature != DQN_DARRAY_SIGNATURE_INTERNAL) return NULL;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE u32 dqn_darray_get_capacity(void *array)
|
DQN_FILE_SCOPE u32 dqn_darray_get_capacity(void *array)
|
||||||
{
|
{
|
||||||
DqnDArrayInternal *header = dqn_darray_get_header_internal(array);
|
DqnDArrayHeader *header = dqn_darray_get_header(array);
|
||||||
if (!header) return 0;
|
if (!header) return 0;
|
||||||
return header->capacity;
|
return header->capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE u32 dqn_darray_get_num_items(void *array)
|
DQN_FILE_SCOPE u32 dqn_darray_get_num_items(void *array)
|
||||||
{
|
{
|
||||||
DqnDArrayInternal *header = dqn_darray_get_header_internal(array);
|
DqnDArrayHeader *header = dqn_darray_get_header(array);
|
||||||
if (!header) return 0;
|
if (!header) return 0;
|
||||||
return header->index;
|
return header->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dqn_darray_push_internal(void **array, void *element, u32 itemSize)
|
DQN_FILE_SCOPE bool dqn_darray_capacity_change(void **array, u32 newCapacity)
|
||||||
{
|
{
|
||||||
if (!element || !array) return false;
|
DqnDArrayHeader *header = dqn_darray_get_header(*array);
|
||||||
|
if (!header) return false;
|
||||||
|
if (header->capacity == newCapacity) return true;
|
||||||
|
|
||||||
DqnDArrayInternal *header = dqn_darray_get_header_internal(*array);
|
if (newCapacity > header->index)
|
||||||
if (!header || header->itemSize != itemSize) return false;
|
{
|
||||||
|
u32 metadataSize = sizeof(DqnDArrayHeader);
|
||||||
|
u32 storageSize = header->itemSize * newCapacity;
|
||||||
|
void *newMem = realloc(header, metadataSize + storageSize);
|
||||||
|
if (newMem)
|
||||||
|
{
|
||||||
|
header = (DqnDArrayHeader *)newMem;
|
||||||
|
header->capacity = newCapacity;
|
||||||
|
header->data = (u8 *)newMem + metadataSize;
|
||||||
|
*array = header->data;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE_SCOPE bool dqn_darray_capacity_grow_if_need_internal(void **array)
|
||||||
|
{
|
||||||
|
DqnDArrayHeader *header = dqn_darray_get_header(*array);
|
||||||
|
if (!header) return false;
|
||||||
|
|
||||||
if (header->index >= header->capacity)
|
if (header->index >= header->capacity)
|
||||||
{
|
{
|
||||||
@ -367,22 +431,24 @@ bool dqn_darray_push_internal(void **array, void *element, u32 itemSize)
|
|||||||
u32 newCapacity = (i32)(header->capacity * GROWTH_FACTOR);
|
u32 newCapacity = (i32)(header->capacity * GROWTH_FACTOR);
|
||||||
if (newCapacity == header->capacity) newCapacity++;
|
if (newCapacity == header->capacity) newCapacity++;
|
||||||
|
|
||||||
u32 metadataSize = sizeof(DqnDArrayInternal);
|
return dqn_darray_capacity_change(array, newCapacity);
|
||||||
u32 storageSize = header->itemSize * newCapacity;
|
|
||||||
void *newMem = realloc(header, metadataSize + storageSize);
|
|
||||||
if (newMem)
|
|
||||||
{
|
|
||||||
header = (DqnDArrayInternal *)newMem;
|
|
||||||
header->capacity = newCapacity;
|
|
||||||
header->data = (u8 *)newMem + metadataSize;
|
|
||||||
*array = header->data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dqn_darray_push_internal(void **array, void *element, u32 itemSize)
|
||||||
|
{
|
||||||
|
if (!element || !array) return false;
|
||||||
|
|
||||||
|
DqnDArrayHeader *header = dqn_darray_get_header(*array);
|
||||||
|
if (!header || header->itemSize != itemSize) return false;
|
||||||
|
|
||||||
|
// NOTE: Array is grown before this step happens. If at this point it still
|
||||||
|
// doesn't fit then we've had a mem alloc problem.
|
||||||
|
if (header->index >= header->capacity)
|
||||||
|
return false;
|
||||||
|
|
||||||
u32 arrayOffset = header->itemSize * header->index++;
|
u32 arrayOffset = header->itemSize * header->index++;
|
||||||
DQN_ASSERT(header->index <= header->capacity);
|
DQN_ASSERT(header->index <= header->capacity);
|
||||||
u8 *dataPtr = (u8 *)header->data;
|
u8 *dataPtr = (u8 *)header->data;
|
||||||
@ -394,9 +460,108 @@ bool dqn_darray_push_internal(void **array, void *element, u32 itemSize)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_clear(void *array)
|
||||||
|
{
|
||||||
|
DqnDArrayHeader *header = dqn_darray_get_header(array);
|
||||||
|
if (header)
|
||||||
|
{
|
||||||
|
header->index = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_remove(void *array, u32 index)
|
||||||
|
{
|
||||||
|
DqnDArrayHeader *header = dqn_darray_get_header(array);
|
||||||
|
if (header)
|
||||||
|
{
|
||||||
|
// NOTE: header->index is the index where the next entry will be push to
|
||||||
|
// Array is empty, or index is out of bounds
|
||||||
|
if (header->index == 0 || index >= header->index) return false;
|
||||||
|
|
||||||
|
// If it's the first entry we just need to decrement index
|
||||||
|
if (index == 0 && header->index == 1)
|
||||||
|
{
|
||||||
|
header->index--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's the last entry we just need to decrement index
|
||||||
|
if (index == (header->index - 1))
|
||||||
|
{
|
||||||
|
header->index--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 lastEntryIndex = header->index - 1;
|
||||||
|
u32 lastEntryByteOffset = lastEntryIndex * header->itemSize;
|
||||||
|
u32 removeEntryIndex = index;
|
||||||
|
u32 removeEntryByteOffset = removeEntryIndex * header->itemSize;
|
||||||
|
|
||||||
|
u8 *dataPtr = (u8 *)header->data;
|
||||||
|
void *dest = (void *)&dataPtr[removeEntryByteOffset];
|
||||||
|
void *src = (void *)&dataPtr[lastEntryByteOffset];
|
||||||
|
memcpy(dest, src, header->itemSize);
|
||||||
|
|
||||||
|
header->index--;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DQN_FILE_SCOPE bool dqn_darray_remove_stable(void *array, u32 index)
|
||||||
|
{
|
||||||
|
DqnDArrayHeader *header = dqn_darray_get_header(array);
|
||||||
|
if (header)
|
||||||
|
{
|
||||||
|
// NOTE: header->index is the index where the next entry will be push to
|
||||||
|
// Array is empty, or index is out of bounds
|
||||||
|
if (header->index == 0 || index >= header->index) return false;
|
||||||
|
|
||||||
|
// If it's the last entry we just need to decrement index
|
||||||
|
if (index == (header->index - 1))
|
||||||
|
{
|
||||||
|
header->index--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's the first entry we just need to decrement index
|
||||||
|
if (index == 0 && header->index == 1)
|
||||||
|
{
|
||||||
|
header->index--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 removeEntryIndex = index;
|
||||||
|
u32 removeEntryByteOffset = removeEntryIndex * header->itemSize;
|
||||||
|
|
||||||
|
u32 oneAfterRemove = index + 1;
|
||||||
|
u32 oneAfterRemoveByteOffset = oneAfterRemove * header->itemSize;
|
||||||
|
u32 endOfListIndex = header->index - 1;
|
||||||
|
u32 endOfListByteOffset = endOfListIndex * header->itemSize;
|
||||||
|
|
||||||
|
u32 numBytesToShift = endOfListByteOffset - oneAfterRemoveByteOffset;
|
||||||
|
DQN_ASSERT(numBytesToShift <= (header->itemSize * header->capacity));
|
||||||
|
|
||||||
|
u8 *dataPtr = (u8 *)header->data;
|
||||||
|
void *dest = (void *)&dataPtr[removeEntryByteOffset];
|
||||||
|
void *src = (void *)&dataPtr[oneAfterRemoveByteOffset];
|
||||||
|
memmove(dest, src, endOfListByteOffset);
|
||||||
|
|
||||||
|
header->index--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE inline bool dqn_darray_free(void *array)
|
DQN_FILE_SCOPE inline bool dqn_darray_free(void *array)
|
||||||
{
|
{
|
||||||
DqnDArrayInternal *header = dqn_darray_get_header_internal(array);
|
DqnDArrayHeader *header = dqn_darray_get_header(array);
|
||||||
if (header)
|
if (header)
|
||||||
{
|
{
|
||||||
header->index = 0;
|
header->index = 0;
|
||||||
@ -1224,8 +1389,7 @@ DQN_FILE_SCOPE u32 dqn_utf8_to_ucs(u32 *dest, u32 character)
|
|||||||
#ifdef DQN_WIN32
|
#ifdef DQN_WIN32
|
||||||
#define DQN_WIN32_ERROR_BOX(text, title) MessageBoxA(NULL, text, title, MB_OK);
|
#define DQN_WIN32_ERROR_BOX(text, title) MessageBoxA(NULL, text, title, MB_OK);
|
||||||
|
|
||||||
FILE_SCOPE bool dqn_win32_utf8_to_wchar_internal(char *in, wchar_t *out,
|
DQN_FILE_SCOPE bool dqn_win32_utf8_to_wchar(char *in, wchar_t *out, i32 outLen)
|
||||||
i32 outLen)
|
|
||||||
{
|
{
|
||||||
u32 result = MultiByteToWideChar(CP_UTF8, 0, in, -1, out, outLen-1);
|
u32 result = MultiByteToWideChar(CP_UTF8, 0, in, -1, out, outLen-1);
|
||||||
|
|
||||||
@ -1238,8 +1402,7 @@ FILE_SCOPE bool dqn_win32_utf8_to_wchar_internal(char *in, wchar_t *out,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_SCOPE bool dqn_win32_wchar_to_utf8_internal(wchar_t *in, char *out,
|
DQN_FILE_SCOPE bool dqn_win32_wchar_to_utf8(wchar_t *in, char *out, i32 outLen)
|
||||||
i32 outLen)
|
|
||||||
{
|
{
|
||||||
u32 result =
|
u32 result =
|
||||||
WideCharToMultiByte(CP_UTF8, 0, in, -1, out, outLen, NULL, NULL);
|
WideCharToMultiByte(CP_UTF8, 0, in, -1, out, outLen, NULL, NULL);
|
||||||
@ -1260,8 +1423,7 @@ DQN_FILE_SCOPE bool dqn_file_open(char *const path, DqnFile *file)
|
|||||||
|
|
||||||
#ifdef DQN_WIN32
|
#ifdef DQN_WIN32
|
||||||
wchar_t widePath[MAX_PATH] = {};
|
wchar_t widePath[MAX_PATH] = {};
|
||||||
dqn_win32_utf8_to_wchar_internal(path, widePath,
|
dqn_win32_utf8_to_wchar(path, widePath, DQN_ARRAY_COUNT(widePath));
|
||||||
DQN_ARRAY_COUNT(widePath));
|
|
||||||
|
|
||||||
HANDLE handle = CreateFileW(widePath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
HANDLE handle = CreateFileW(widePath, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
@ -1333,7 +1495,7 @@ DQN_FILE_SCOPE char **dqn_dir_read(char *dir, u32 *numFiles)
|
|||||||
|
|
||||||
u32 currNumFiles = 0;
|
u32 currNumFiles = 0;
|
||||||
wchar_t wideDir[MAX_PATH] = {};
|
wchar_t wideDir[MAX_PATH] = {};
|
||||||
dqn_win32_utf8_to_wchar_internal(dir, wideDir, DQN_ARRAY_COUNT(wideDir));
|
dqn_win32_utf8_to_wchar(dir, wideDir, DQN_ARRAY_COUNT(wideDir));
|
||||||
|
|
||||||
// Enumerate number of files first
|
// Enumerate number of files first
|
||||||
{
|
{
|
||||||
@ -1388,8 +1550,8 @@ DQN_FILE_SCOPE char **dqn_dir_read(char *dir, u32 *numFiles)
|
|||||||
WIN32_FIND_DATAW findData = {};
|
WIN32_FIND_DATAW findData = {};
|
||||||
while (FindNextFileW(findHandle, &findData) != 0)
|
while (FindNextFileW(findHandle, &findData) != 0)
|
||||||
{
|
{
|
||||||
dqn_win32_wchar_to_utf8_internal(
|
dqn_win32_wchar_to_utf8(findData.cFileName, list[listIndex++],
|
||||||
findData.cFileName, list[listIndex++], MAX_PATH);
|
MAX_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
*numFiles = currNumFiles;
|
*numFiles = currNumFiles;
|
||||||
@ -1430,9 +1592,9 @@ inline FILE_SCOPE f64 dqn_win32_query_perf_counter_time_in_s_internal()
|
|||||||
LARGE_INTEGER qpcResult;
|
LARGE_INTEGER qpcResult;
|
||||||
QueryPerformanceCounter(&qpcResult);
|
QueryPerformanceCounter(&qpcResult);
|
||||||
|
|
||||||
// Convert to seconds
|
// Convert to ms
|
||||||
f64 timestamp =
|
f64 timestamp =
|
||||||
(f64)(qpcResult.QuadPart / queryPerformanceFrequency.QuadPart);
|
qpcResult.QuadPart / (f64)queryPerformanceFrequency.QuadPart;
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -561,24 +561,19 @@ void dqn_darray_test()
|
|||||||
// Test basic insert
|
// Test basic insert
|
||||||
{
|
{
|
||||||
DqnV2 va = dqn_v2(5, 10);
|
DqnV2 va = dqn_v2(5, 10);
|
||||||
DQN_ASSERT(DQN_DARRAY_PUSH(&vecDArray, &va));
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
|
|
||||||
DqnV2 vb = vecDArray[0];
|
DqnV2 vb = vecDArray[0];
|
||||||
DQN_ASSERT(dqn_v2_equals(va, vb));
|
DQN_ASSERT(dqn_v2_equals(va, vb));
|
||||||
|
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 1);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 1);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 1);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 1);
|
||||||
|
|
||||||
DqnV2 *empty = NULL;
|
|
||||||
DQN_ASSERT(DQN_DARRAY_PUSH(NULL, empty) == false);
|
|
||||||
DQN_ASSERT(DQN_DARRAY_PUSH(NULL, &va) == false);
|
|
||||||
DQN_ASSERT(DQN_DARRAY_PUSH(&vecDArray, empty) == false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test array resizing and freeing
|
// Test array resizing and freeing
|
||||||
{
|
{
|
||||||
DqnV2 va = dqn_v2(10, 15);
|
DqnV2 va = dqn_v2(10, 15);
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
|
|
||||||
DqnV2 vb = vecDArray[0];
|
DqnV2 vb = vecDArray[0];
|
||||||
DQN_ASSERT(dqn_v2_equals(va, vb) == false);
|
DQN_ASSERT(dqn_v2_equals(va, vb) == false);
|
||||||
@ -589,44 +584,44 @@ void dqn_darray_test()
|
|||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 2);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 2);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 2);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 2);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 3);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 3);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 3);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 3);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 4);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 4);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 4);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 4);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 5);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 5);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 5);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 5);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 6);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 6);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 6);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 6);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 7);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 7);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 7);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 7);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 8);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 8);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 8);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 8);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 9);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 9);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 9);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 9);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 10);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 10);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 10);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 10);
|
||||||
|
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &va);
|
DQN_DARRAY_PUSH(&vecDArray, va);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 12);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 12);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 11);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 11);
|
||||||
|
|
||||||
DqnV2 vc = dqn_v2(90, 100);
|
DqnV2 vc = dqn_v2(90, 100);
|
||||||
DQN_DARRAY_PUSH(&vecDArray, &vc);
|
DQN_DARRAY_PUSH(&vecDArray, vc);
|
||||||
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 12);
|
DQN_ASSERT(dqn_darray_get_capacity(vecDArray) == 12);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 12);
|
DQN_ASSERT(dqn_darray_get_num_items(vecDArray) == 12);
|
||||||
DQN_ASSERT(dqn_v2_equals(vc, vecDArray[11]));
|
DQN_ASSERT(dqn_v2_equals(vc, vecDArray[11]));
|
||||||
@ -641,11 +636,101 @@ void dqn_darray_test()
|
|||||||
DQN_ASSERT(dqn_darray_get_capacity(array) == 1);
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 1);
|
||||||
DQN_ASSERT(dqn_darray_get_num_items(array) == 0);
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 0);
|
||||||
|
|
||||||
f32 *empty = NULL;
|
dqn_darray_free(array);
|
||||||
DQN_ASSERT(DQN_DARRAY_PUSH(NULL, empty) == false);
|
|
||||||
DQN_ASSERT(DQN_DARRAY_PUSH(&array, empty) == false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DqnV2 a = dqn_v2(1, 2);
|
||||||
|
DqnV2 b = dqn_v2(3, 4);
|
||||||
|
DqnV2 c = dqn_v2(5, 6);
|
||||||
|
DqnV2 d = dqn_v2(7, 8);
|
||||||
|
|
||||||
|
DqnV2 *array = DQN_DARRAY_INIT(DqnV2, 16);
|
||||||
|
DQN_ASSERT(array);
|
||||||
|
DQN_ASSERT(dqn_darray_remove(array, 0) == false);
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 0);
|
||||||
|
|
||||||
|
DQN_ASSERT(dqn_darray_clear(array));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 0);
|
||||||
|
|
||||||
|
DQN_DARRAY_PUSH(&array, a);
|
||||||
|
DQN_DARRAY_PUSH(&array, b);
|
||||||
|
DQN_DARRAY_PUSH(&array, c);
|
||||||
|
DQN_DARRAY_PUSH(&array, d);
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 4);
|
||||||
|
|
||||||
|
DQN_ASSERT(dqn_darray_remove(array, 0));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[0], d));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[1], b));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[2], c));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 3);
|
||||||
|
|
||||||
|
DQN_ASSERT(dqn_darray_remove(array, 2));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[0], d));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[1], b));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 2);
|
||||||
|
|
||||||
|
DQN_ASSERT(dqn_darray_remove(array, 100) == false);
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[0], d));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[1], b));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 2);
|
||||||
|
|
||||||
|
DQN_ASSERT(dqn_darray_clear(array));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 0);
|
||||||
|
|
||||||
|
dqn_darray_free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DqnV2 a = dqn_v2(1, 2);
|
||||||
|
DqnV2 b = dqn_v2(3, 4);
|
||||||
|
DqnV2 c = dqn_v2(5, 6);
|
||||||
|
DqnV2 d = dqn_v2(7, 8);
|
||||||
|
|
||||||
|
DqnV2 *array = DQN_DARRAY_INIT(DqnV2, 16);
|
||||||
|
DQN_ASSERT(array);
|
||||||
|
|
||||||
|
DQN_DARRAY_PUSH(&array, a);
|
||||||
|
DQN_DARRAY_PUSH(&array, b);
|
||||||
|
DQN_DARRAY_PUSH(&array, c);
|
||||||
|
DQN_DARRAY_PUSH(&array, d);
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 4);
|
||||||
|
|
||||||
|
dqn_darray_remove_stable(array, 0);
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[0], b));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[1], c));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[2], d));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 3);
|
||||||
|
|
||||||
|
dqn_darray_remove_stable(array, 1);
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[0], b));
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[1], d));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 2);
|
||||||
|
|
||||||
|
dqn_darray_remove_stable(array, 1);
|
||||||
|
DQN_ASSERT(dqn_v2_equals(array[0], b));
|
||||||
|
DQN_ASSERT(dqn_darray_get_capacity(array) == 16);
|
||||||
|
DQN_ASSERT(dqn_darray_get_num_items(array) == 1);
|
||||||
|
dqn_darray_free(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
DQN_ASSERT(dqn_darray_clear(NULL) == false);
|
||||||
|
DQN_ASSERT(dqn_darray_clear(NULL) == false);
|
||||||
|
DQN_ASSERT(dqn_darray_free(NULL) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
printf("dqn_darray_test(): Completed successfully\n");
|
printf("dqn_darray_test(): Completed successfully\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ Global
|
|||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{87785192-6F49-4F85-AA0D-F0AFA5CCCDDA}.Release|x86.ActiveCfg = Release
|
{87785192-6F49-4F85-AA0D-F0AFA5CCCDDA}.Release|x86.ActiveCfg = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
Loading…
Reference in New Issue
Block a user