dqn: Cleanup more documentation
This commit is contained in:
parent
55dbc25110
commit
2bbc49242e
125
dqn_containers.h
125
dqn_containers.h
@ -28,24 +28,26 @@
|
|||||||
//
|
//
|
||||||
// In addition to no realloc on expansion or shrinking.
|
// In addition to no realloc on expansion or shrinking.
|
||||||
//
|
//
|
||||||
// NOTE: API
|
// TODO(doyle): Add an API for shrinking the array by decomitting pages back to
|
||||||
|
// the OS.
|
||||||
//
|
//
|
||||||
|
// NOTE: API
|
||||||
// @proc Dqn_VArray_InitByteSize, Dqn_VArray_Init
|
// @proc Dqn_VArray_InitByteSize, Dqn_VArray_Init
|
||||||
// @desc Initialise an array with the requested byte size or item capacity
|
// @desc Initialise an array with the requested byte size or item capacity
|
||||||
// respectively. The returned array may have a higher capacity than the
|
// respectively. The returned array may have a higher capacity than the
|
||||||
// requested amount since requested memory from the OS may have a certain
|
// requested amount since requested memory from the OS may have a certain
|
||||||
// alignment requirement (e.g. on Windows reserve/commit are 64k/4k aligned).
|
// alignment requirement (e.g. on Windows reserve/commit are 64k/4k aligned).
|
||||||
//
|
|
||||||
// @proc Dqn_VArray_IsValid
|
// @proc Dqn_VArray_IsValid
|
||||||
// @desc Verify if the array has been initialised
|
// @desc Verify if the array has been initialised
|
||||||
//
|
|
||||||
// @proc Dqn_VArray_Make, Dqn_VArray_Add
|
// @proc Dqn_VArray_Make, Dqn_VArray_Add
|
||||||
// @desc Allocate items into the array
|
// @desc Allocate items into the array
|
||||||
// 'Make' creates the `count` number of requested items
|
// 'Make' creates the `count` number of requested items
|
||||||
// 'Add' adds the array of items into the array
|
// 'Add' adds the array of items into the array
|
||||||
// @return The array of items allocated. Null pointer if the array is invalid
|
// @return The array of items allocated. Null pointer if the array is invalid
|
||||||
// or the array has insufficient space for the requested items.
|
// or the array has insufficient space for the requested items.
|
||||||
//
|
|
||||||
// @proc Dqn_VArray_EraseRange
|
// @proc Dqn_VArray_EraseRange
|
||||||
// @desc Erase the next `count` items at `begin_index` in the array. `count`
|
// @desc Erase the next `count` items at `begin_index` in the array. `count`
|
||||||
// can be positive or negative which dictates the if we erase forward from the
|
// can be positive or negative which dictates the if we erase forward from the
|
||||||
@ -56,10 +58,10 @@
|
|||||||
// @param erase The erase method, stable erase will shift all elements after
|
// @param erase The erase method, stable erase will shift all elements after
|
||||||
// the erase ranged into the range. Unstable erase will copy the tail elements
|
// the erase ranged into the range. Unstable erase will copy the tail elements
|
||||||
// into the range to delete.
|
// into the range to delete.
|
||||||
//
|
|
||||||
// @proc Dqn_VArray_Clear
|
// @proc Dqn_VArray_Clear
|
||||||
// @desc Set the size of the array to 0
|
// @desc Set the size of the array to 0
|
||||||
//
|
|
||||||
// @proc Dqn_VArray_Reserve
|
// @proc Dqn_VArray_Reserve
|
||||||
// @desc Ensure that the requested number of items are backed by physical
|
// @desc Ensure that the requested number of items are backed by physical
|
||||||
// pages from the OS. Calling this pre-emptively will minimise syscalls into
|
// pages from the OS. Calling this pre-emptively will minimise syscalls into
|
||||||
@ -67,17 +69,13 @@
|
|||||||
// in bytes to the allocation granularity of OS allocation APIs hence the
|
// in bytes to the allocation granularity of OS allocation APIs hence the
|
||||||
// reserved space may be greater than the requested amount (e.g. this is 4k
|
// reserved space may be greater than the requested amount (e.g. this is 4k
|
||||||
// on Windows).
|
// on Windows).
|
||||||
//
|
|
||||||
// TODO(doyle)
|
|
||||||
//
|
|
||||||
// Add an API for shrinking the array by decomitting pages back to the OS.
|
|
||||||
|
|
||||||
template <typename T> struct Dqn_VArray
|
template <typename T> struct Dqn_VArray
|
||||||
{
|
{
|
||||||
Dqn_ArenaBlock *block; ///< Block of memory from the allocator for this array
|
Dqn_ArenaBlock *block; // Block of memory from the allocator for this array
|
||||||
T *data; ///< Pointer to the start of the array items in the block of memory
|
T *data; // Pointer to the start of the array items in the block of memory
|
||||||
Dqn_usize size; ///< Number of items currently in the array
|
Dqn_usize size; // Number of items currently in the array
|
||||||
Dqn_usize max; ///< Maximum number of items this array can store
|
Dqn_usize max; // Maximum number of items this array can store
|
||||||
|
|
||||||
T *begin() { return data; }
|
T *begin() { return data; }
|
||||||
T *end () { return data + size; }
|
T *end () { return data + size; }
|
||||||
@ -91,14 +89,19 @@ enum Dqn_VArrayErase
|
|||||||
Dqn_VArrayErase_Stable,
|
Dqn_VArrayErase_Stable,
|
||||||
};
|
};
|
||||||
|
|
||||||
DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize(Dqn_Arena *arena, Dqn_usize byte_size);
|
// NOTE: Setup =====================================================================================
|
||||||
DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_Init (Dqn_Arena *arena, Dqn_usize max);
|
DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize(Dqn_Arena *arena, Dqn_usize byte_size);
|
||||||
DQN_API template <typename T> bool Dqn_VArray_IsValid (Dqn_VArray<T> const *array);
|
DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_Init (Dqn_Arena *arena, Dqn_usize max);
|
||||||
DQN_API template <typename T> T * Dqn_VArray_Make (Dqn_VArray<T> *array, Dqn_usize count, Dqn_ZeroMem zero_mem);
|
DQN_API template <typename T> bool Dqn_VArray_IsValid (Dqn_VArray<T> const *array);
|
||||||
DQN_API template <typename T> T * Dqn_VArray_Add (Dqn_VArray<T> *array, T const *items, Dqn_usize count);
|
DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<T> *array, Dqn_usize count);
|
||||||
DQN_API template <typename T> void Dqn_VArray_EraseRange (Dqn_VArray<T> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_VArrayErase erase);
|
|
||||||
DQN_API template <typename T> void Dqn_VArray_Clear (Dqn_VArray<T> *array);
|
// NOTE: Insert ====================================================================================
|
||||||
DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<T> *array, Dqn_usize count);
|
DQN_API template <typename T> T * Dqn_VArray_Make (Dqn_VArray<T> *array, Dqn_usize count, Dqn_ZeroMem zero_mem);
|
||||||
|
DQN_API template <typename T> T * Dqn_VArray_Add (Dqn_VArray<T> *array, T const *items, Dqn_usize count);
|
||||||
|
|
||||||
|
// NOTE: Modify ====================================================================================
|
||||||
|
DQN_API template <typename T> void Dqn_VArray_EraseRange (Dqn_VArray<T> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_VArrayErase erase);
|
||||||
|
DQN_API template <typename T> void Dqn_VArray_Clear (Dqn_VArray<T> *array);
|
||||||
#endif // !defined(DQN_NO_VARRAY)
|
#endif // !defined(DQN_NO_VARRAY)
|
||||||
|
|
||||||
#if !defined(DQN_NO_DSMAP)
|
#if !defined(DQN_NO_DSMAP)
|
||||||
@ -149,27 +152,27 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
|
|||||||
//
|
//
|
||||||
// - Functions that return a pointer or boolean will always return null or false
|
// - Functions that return a pointer or boolean will always return null or false
|
||||||
// if the passed in map is invalid e.g. `DSMap_IsValid()` returns false.
|
// if the passed in map is invalid e.g. `DSMap_IsValid()` returns false.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_Init
|
// @proc Dqn_DSMap_Init
|
||||||
// @param size[in] The number of slots in the table. This size must be a
|
// @param size[in] The number of slots in the table. This size must be a
|
||||||
// power-of-two or otherwise an assert will be triggered.
|
// power-of-two or otherwise an assert will be triggered.
|
||||||
// @return The hash table. On memory allocation failure, the table will be
|
// @return The hash table. On memory allocation failure, the table will be
|
||||||
// zero initialised whereby calling Dqn_DSMap_IsValid() will return false.
|
// zero initialised whereby calling Dqn_DSMap_IsValid() will return false.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_Deinit
|
// @proc Dqn_DSMap_Deinit
|
||||||
// @desc Free the memory allocated by the table
|
// @desc Free the memory allocated by the table
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_IsValid
|
// @proc Dqn_DSMap_IsValid
|
||||||
// @desc Verify that the table is in a valid state (e.g. initialised
|
// @desc Verify that the table is in a valid state (e.g. initialised
|
||||||
// correctly).
|
// correctly).
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_Hash
|
// @proc Dqn_DSMap_Hash
|
||||||
// @desc Hash the input key using the custom hash function if it's set on the
|
// @desc Hash the input key using the custom hash function if it's set on the
|
||||||
// map, otherwise uses the default hashing function (32bit Murmur3).
|
// map, otherwise uses the default hashing function (32bit Murmur3).
|
||||||
//
|
//
|
||||||
// @proc Dqn_DSMap_HashToSlotIndex
|
// @proc Dqn_DSMap_HashToSlotIndex
|
||||||
// @desc Calculate the index into the map's `slots` array from the given hash.
|
// @desc Calculate the index into the map's `slots` array from the given hash.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_FindSlot, Dqn_DSMap_Find
|
// @proc Dqn_DSMap_FindSlot, Dqn_DSMap_Find
|
||||||
// @desc Find the slot in the map's `slots` array corresponding to the given
|
// @desc Find the slot in the map's `slots` array corresponding to the given
|
||||||
// key and hash. If the map does not contain the key, a null pointer is
|
// key and hash. If the map does not contain the key, a null pointer is
|
||||||
@ -177,7 +180,7 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
|
|||||||
//
|
//
|
||||||
// `Find` returns the value.
|
// `Find` returns the value.
|
||||||
// `FindSlot` returns the map's hash table slot.
|
// `FindSlot` returns the map's hash table slot.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_MakeSlot, Dqn_DSMap_Make, Dqn_DSMap_Set, Dqn_DSMap_SetSlot
|
// @proc Dqn_DSMap_MakeSlot, Dqn_DSMap_Make, Dqn_DSMap_Set, Dqn_DSMap_SetSlot
|
||||||
// @desc Same as `DSMap_Find*` except if the key does not exist in the table,
|
// @desc Same as `DSMap_Find*` except if the key does not exist in the table,
|
||||||
// a hash-table slot will be made.
|
// a hash-table slot will be made.
|
||||||
@ -194,20 +197,20 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
|
|||||||
// @param found[out] Pass a pointer to a bool. The bool will be set to true
|
// @param found[out] Pass a pointer to a bool. The bool will be set to true
|
||||||
// if the item already existed in the map before, or false if the item was
|
// if the item already existed in the map before, or false if the item was
|
||||||
// just created by this call.
|
// just created by this call.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_Resize
|
// @proc Dqn_DSMap_Resize
|
||||||
// @desc Resize the table and move all elements to the new map.
|
// @desc Resize the table and move all elements to the new map.
|
||||||
// the elements currently set in the
|
// the elements currently set in the
|
||||||
// @param size[in] New size of the table, must be a power of two.
|
// @param size[in] New size of the table, must be a power of two.
|
||||||
// @return False if memory allocation fails, or the requested size is smaller
|
// @return False if memory allocation fails, or the requested size is smaller
|
||||||
// than the current number of elements in the map to resize. True otherwise.
|
// than the current number of elements in the map to resize. True otherwise.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_Erase
|
// @proc Dqn_DSMap_Erase
|
||||||
// @desc Remove the key-value pair from the table. If by erasing the key-value
|
// @desc Remove the key-value pair from the table. If by erasing the key-value
|
||||||
// pair from the table puts the table under 25% load, the table will be shrunk
|
// pair from the table puts the table under 25% load, the table will be shrunk
|
||||||
// by 1/2 the current size after erasing. The table will not shrink below the
|
// by 1/2 the current size after erasing. The table will not shrink below the
|
||||||
// initial size that the table was initialised as.
|
// initial size that the table was initialised as.
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_KeyCStringLit, Dqn_DSMap_KeyU64, Dqn_DSMap_KeyBuffer,
|
// @proc Dqn_DSMap_KeyCStringLit, Dqn_DSMap_KeyU64, Dqn_DSMap_KeyBuffer,
|
||||||
// Dqn_DSMap_KeyString8 Dqn_DSMap_KeyString8Copy
|
// Dqn_DSMap_KeyString8 Dqn_DSMap_KeyString8Copy
|
||||||
// @desc Create a hash-table key given
|
// @desc Create a hash-table key given
|
||||||
@ -221,7 +224,7 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
|
|||||||
// If the key points to an array of bytes, the lifetime of those bytes *must*
|
// If the key points to an array of bytes, the lifetime of those bytes *must*
|
||||||
// remain valid throughout the lifetime of the map as the pointers are value
|
// remain valid throughout the lifetime of the map as the pointers are value
|
||||||
// copied into the hash table!
|
// copied into the hash table!
|
||||||
//
|
|
||||||
// @proc Dqn_DSMap_KeyU64NoHash
|
// @proc Dqn_DSMap_KeyU64NoHash
|
||||||
// @desc Create a hash-table key given the uint64. This u64 is *not* hashed to
|
// @desc Create a hash-table key given the uint64. This u64 is *not* hashed to
|
||||||
// map values into the table. This is useful if you already have a source of
|
// map values into the table. This is useful if you already have a source of
|
||||||
@ -234,9 +237,9 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
|
|||||||
enum Dqn_DSMapKeyType
|
enum Dqn_DSMapKeyType
|
||||||
{
|
{
|
||||||
Dqn_DSMapKeyType_Invalid,
|
Dqn_DSMapKeyType_Invalid,
|
||||||
Dqn_DSMapKeyType_U64, ///< Use a U64 key that is `hash(u64) % size` to map into the table
|
Dqn_DSMapKeyType_U64, // Use a U64 key that is `hash(u64) % size` to map into the table
|
||||||
Dqn_DSMapKeyType_U64NoHash, ///< Use a U64 key that is `u64 % size` to map into the table
|
Dqn_DSMapKeyType_U64NoHash, // Use a U64 key that is `u64 % size` to map into the table
|
||||||
Dqn_DSMapKeyType_Buffer, ///< Use a buffer key that is `hash(buffer) % size` to map into the table
|
Dqn_DSMapKeyType_Buffer, // Use a buffer key that is `hash(buffer) % size` to map into the table
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_DSMapKey
|
struct Dqn_DSMapKey
|
||||||
@ -261,14 +264,14 @@ template <typename T> struct Dqn_DSMapSlot
|
|||||||
using Dqn_DSMapHashFunction = uint32_t(Dqn_DSMapKey key, uint32_t seed);
|
using Dqn_DSMapHashFunction = uint32_t(Dqn_DSMapKey key, uint32_t seed);
|
||||||
template <typename T> struct Dqn_DSMap
|
template <typename T> struct Dqn_DSMap
|
||||||
{
|
{
|
||||||
uint32_t *hash_to_slot; ///< Mapping from hash to a index in the slots array
|
uint32_t *hash_to_slot; // Mapping from hash to a index in the slots array
|
||||||
Dqn_DSMapSlot<T> *slots; ///< Values of the array stored contiguously, non-sorted order
|
Dqn_DSMapSlot<T> *slots; // Values of the array stored contiguously, non-sorted order
|
||||||
uint32_t size; ///< Total capacity of the map and is a power of two
|
uint32_t size; // Total capacity of the map and is a power of two
|
||||||
uint32_t occupied; ///< Number of slots used in the hash table
|
uint32_t occupied; // Number of slots used in the hash table
|
||||||
Dqn_Allocator allocator; ///< Backing allocator for the hash table
|
Dqn_Allocator allocator; // Backing allocator for the hash table
|
||||||
uint32_t initial_size; ///< Initial map size, map cannot shrink on erase below this size
|
uint32_t initial_size; // Initial map size, map cannot shrink on erase below this size
|
||||||
Dqn_DSMapHashFunction *hash_function; ///< Custom hashing function to use if field is set
|
Dqn_DSMapHashFunction *hash_function; // Custom hashing function to use if field is set
|
||||||
uint32_t hash_seed; ///< Seed for the hashing function, when 0, DQN_DS_MAP_DEFAULT_HASH_SEED is used
|
uint32_t hash_seed; // Seed for the hashing function, when 0, DQN_DS_MAP_DEFAULT_HASH_SEED is used
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: Setup =====================================================================================
|
// NOTE: Setup =====================================================================================
|
||||||
@ -305,8 +308,8 @@ DQN_API bool operator== (Dqn_DS
|
|||||||
// NOTE: [$FARR] Dqn_FArray ========================================================================
|
// NOTE: [$FARR] Dqn_FArray ========================================================================
|
||||||
template <typename T, Dqn_usize N> struct Dqn_FArray
|
template <typename T, Dqn_usize N> struct Dqn_FArray
|
||||||
{
|
{
|
||||||
T data[N]; ///< Pointer to the start of the array items in the block of memory
|
T data[N]; // Pointer to the start of the array items in the block of memory
|
||||||
Dqn_usize size; ///< Number of items currently in the array
|
Dqn_usize size; // Number of items currently in the array
|
||||||
|
|
||||||
T *begin() { return data; }
|
T *begin() { return data; }
|
||||||
T *end () { return data + size; }
|
T *end () { return data + size; }
|
||||||
@ -320,35 +323,40 @@ enum Dqn_FArrayErase
|
|||||||
Dqn_FArrayErase_Stable,
|
Dqn_FArrayErase_Stable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// NOTE: Setup =====================================================================================
|
||||||
DQN_API template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init (T const *array, Dqn_usize count);
|
DQN_API template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init (T const *array, Dqn_usize count);
|
||||||
DQN_API template <typename T, Dqn_usize N> bool Dqn_FArray_IsValid (Dqn_FArray<T, N> const *array);
|
DQN_API template <typename T, Dqn_usize N> bool Dqn_FArray_IsValid (Dqn_FArray<T, N> const *array);
|
||||||
|
|
||||||
|
// NOTE: Insert ====================================================================================
|
||||||
DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Make (Dqn_FArray<T, N> *array, Dqn_usize count, Dqn_ZeroMem zero_mem);
|
DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Make (Dqn_FArray<T, N> *array, Dqn_usize count, Dqn_ZeroMem zero_mem);
|
||||||
DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Add (Dqn_FArray<T, N> *array, T const *items, Dqn_usize count);
|
DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Add (Dqn_FArray<T, N> *array, T const *items, Dqn_usize count);
|
||||||
|
|
||||||
|
// NOTE: Modify ====================================================================================
|
||||||
DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_EraseRange(Dqn_FArray<T, N> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_FArrayErase erase);
|
DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_EraseRange(Dqn_FArray<T, N> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_FArrayErase erase);
|
||||||
DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_Clear (Dqn_FArray<T, N> *array);
|
DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_Clear (Dqn_FArray<T, N> *array);
|
||||||
#endif // !defined(DQN_NO_FARRAY)
|
#endif // !defined(DQN_NO_FARRAY)
|
||||||
|
|
||||||
#if !defined(DQN_NO_LIST)
|
#if !defined(DQN_NO_LIST)
|
||||||
// NOTE: [$LIST] Dqn_List ==========================================================================
|
// NOTE: [$LIST] Dqn_List ==========================================================================
|
||||||
// NOTE: API
|
|
||||||
//
|
//
|
||||||
|
// NOTE: API
|
||||||
// @proc Dqn_List_At
|
// @proc Dqn_List_At
|
||||||
// @param at_chunk[out] (Optional) The chunk that the index belongs to will
|
// @param at_chunk[out] (Optional) The chunk that the index belongs to will
|
||||||
// be set in this parameter if given
|
// be set in this parameter if given
|
||||||
// @return The element, or null pointer if it is not a valid index.
|
// @return The element, or null pointer if it is not a valid index.
|
||||||
//
|
|
||||||
// @proc Dqn_List_Iterate
|
// @proc Dqn_List_Iterate
|
||||||
// @desc Produce an iterator for the data in the list
|
// @desc Produce an iterator for the data in the list
|
||||||
//
|
//
|
||||||
// @param[in] start_index The index to start iterating from
|
// @param[in] start_index The index to start iterating from
|
||||||
//
|
//
|
||||||
// @begincode
|
#if 0
|
||||||
// Dqn_List<int> list = {};
|
Dqn_List<int> list = {};
|
||||||
// for (Dqn_ListIterator<int> it = {}; Dqn_List_Iterate(&list, &it, 0);)
|
for (Dqn_ListIterator<int> it = {}; Dqn_List_Iterate(&list, &it, 0);)
|
||||||
// {
|
{
|
||||||
// int *item = it.data;
|
int *item = it.data;
|
||||||
// }
|
}
|
||||||
// @endcode
|
#endif
|
||||||
|
|
||||||
template <typename T> struct Dqn_ListChunk
|
template <typename T> struct Dqn_ListChunk
|
||||||
{
|
{
|
||||||
@ -361,10 +369,10 @@ template <typename T> struct Dqn_ListChunk
|
|||||||
|
|
||||||
template <typename T> struct Dqn_ListIterator
|
template <typename T> struct Dqn_ListIterator
|
||||||
{
|
{
|
||||||
Dqn_b32 init; // (Internal): True if Dqn_List_Iterate has been called at-least once on this iterator
|
Dqn_b32 init; // True if Dqn_List_Iterate has been called at-least once on this iterator
|
||||||
Dqn_ListChunk<T> *chunk; // (Internal): The chunk that the iterator is reading from
|
Dqn_ListChunk<T> *chunk; // The chunk that the iterator is reading from
|
||||||
Dqn_usize chunk_data_index; // (Internal): The index in the chunk the iterator is referencing
|
Dqn_usize chunk_data_index; // The index in the chunk the iterator is referencing
|
||||||
T *data; // (Read): Pointer to the data the iterator is referencing. Nullptr if invalid.
|
T *data; // Pointer to the data the iterator is referencing. Nullptr if invalid.
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct Dqn_List
|
template <typename T> struct Dqn_List
|
||||||
@ -1064,4 +1072,3 @@ template <typename T> DQN_API T *Dqn_List_At(Dqn_List<T> *list, Dqn_usize index,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // !defined(DQN_NO_LIST)
|
#endif // !defined(DQN_NO_LIST)
|
||||||
|
|
||||||
|
40
dqn_core.h
40
dqn_core.h
@ -234,11 +234,9 @@ int main()
|
|||||||
DQN_DEFER { printf("Three ..\n"); };
|
DQN_DEFER { printf("Three ..\n"); };
|
||||||
printf("One ..\n");
|
printf("One ..\n");
|
||||||
printf("Two ..\n");
|
printf("Two ..\n");
|
||||||
|
|
||||||
// One ..
|
// One ..
|
||||||
// Two ..
|
// Two ..
|
||||||
// Three ..
|
// Three ..
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -278,16 +276,16 @@ typedef int32_t Dqn_b32;
|
|||||||
#define DQN_ISIZE_MIN INTPTR_MIN
|
#define DQN_ISIZE_MIN INTPTR_MIN
|
||||||
|
|
||||||
// NOTE [$GSTR] Global Structs =====================================================================
|
// NOTE [$GSTR] Global Structs =====================================================================
|
||||||
struct Dqn_String8 ///< Pointer and length style UTF8 strings
|
struct Dqn_String8
|
||||||
{
|
{
|
||||||
char *data; ///< The UTF8 bytes of the string
|
char *data; // The bytes of the string
|
||||||
Dqn_usize size; ///< The number of bytes in the string
|
Dqn_usize size; // The number of bytes in the string
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
char const *begin() const { return data; } ///< Const begin iterator for range-for loops
|
char const *begin() const { return data; } // Const begin iterator for range-for loops
|
||||||
char const *end () const { return data + size; } ///< Const end iterator for range-for loops
|
char const *end () const { return data + size; } // Const end iterator for range-for loops
|
||||||
char *begin() { return data; } ///< Begin iterator for range-for loops
|
char *begin() { return data; } // Begin iterator for range-for loops
|
||||||
char *end () { return data + size; } ///< End iterator for range-for loops
|
char *end () { return data + size; } // End iterator for range-for loops
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -401,22 +399,22 @@ Dqn_CPUIDRegisters Dqn_CPUID(int function_id);
|
|||||||
//
|
//
|
||||||
// @proc Dqn_TicketMutex_Begin, End
|
// @proc Dqn_TicketMutex_Begin, End
|
||||||
// @desc Lock and unlock the mutex respectively
|
// @desc Lock and unlock the mutex respectively
|
||||||
//
|
|
||||||
// @proc Dqn_TicketMutex_MakeTicket
|
// @proc Dqn_TicketMutex_MakeTicket
|
||||||
// @desc Allocate the next available ticket from the mutex for locking using
|
// @desc Allocate the next available ticket from the mutex for locking using
|
||||||
// Dqn_TicketMutex_BeginTicket().
|
// Dqn_TicketMutex_BeginTicket().
|
||||||
// @param[in] mutex The mutex
|
// @param[in] mutex The mutex
|
||||||
// @code
|
#if 0
|
||||||
// Dqn_TicketMutex mutex = {};
|
Dqn_TicketMutex mutex = {};
|
||||||
// unsigned int ticket = Dqn_TicketMutex_MakeTicket(&mutex);
|
unsigned int ticket = Dqn_TicketMutex_MakeTicket(&mutex);
|
||||||
// Dqn_TicketMutex_BeginTicket(&mutex, ticket); // Blocking call until we attain the lock
|
Dqn_TicketMutex_BeginTicket(&mutex, ticket); // Blocking call until we attain the lock
|
||||||
// Dqn_TicketMutex_End(&mutex);
|
Dqn_TicketMutex_End(&mutex);
|
||||||
// @endcode
|
#endif
|
||||||
//
|
|
||||||
// @proc Dqn_TicketMutex_BeginTicket
|
// @proc Dqn_TicketMutex_BeginTicket
|
||||||
// @desc Lock the mutex using the given ticket if possible, otherwise block
|
// @desc Lock the mutex using the given ticket if possible, otherwise block
|
||||||
// waiting until the mutex can be locked.
|
// waiting until the mutex can be locked.
|
||||||
//
|
|
||||||
// @proc Dqn_TicketMutex_CanLock
|
// @proc Dqn_TicketMutex_CanLock
|
||||||
// @desc Determine if the mutex can be locked using the given ticket number
|
// @desc Determine if the mutex can be locked using the given ticket number
|
||||||
|
|
||||||
@ -433,10 +431,10 @@ void Dqn_TicketMutex_BeginTicket(Dqn_TicketMutex const *mutex, Dqn_uint tick
|
|||||||
bool Dqn_TicketMutex_CanLock (Dqn_TicketMutex const *mutex, Dqn_uint ticket);
|
bool Dqn_TicketMutex_CanLock (Dqn_TicketMutex const *mutex, Dqn_uint ticket);
|
||||||
|
|
||||||
// NOTE: [$CALL] Dqn_CallSite ======================================================================
|
// NOTE: [$CALL] Dqn_CallSite ======================================================================
|
||||||
typedef struct Dqn_CallSite {
|
struct Dqn_CallSite
|
||||||
|
{
|
||||||
Dqn_String8 file;
|
Dqn_String8 file;
|
||||||
Dqn_String8 function;
|
Dqn_String8 function;
|
||||||
unsigned int line;
|
unsigned int line;
|
||||||
} Dqn_CalSite;
|
};
|
||||||
|
|
||||||
#define DQN_CALL_SITE Dqn_CallSite{DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__}
|
#define DQN_CALL_SITE Dqn_CallSite{DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__}
|
||||||
|
18
dqn_hash.h
18
dqn_hash.h
@ -6,20 +6,22 @@
|
|||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
|
||||||
// NOTE: [$FNV1] Dqn_FNV1A =========================================================================
|
// NOTE: [$FNV1] Dqn_FNV1A =========================================================================
|
||||||
#ifndef DQN_FNV1A32_SEED
|
// NOTE: API =======================================================================================
|
||||||
|
#if 0
|
||||||
|
char buffer1[128] = {random bytes};
|
||||||
|
char buffer2[128] = {random bytes};
|
||||||
|
uint64_t hash = Dqn_FNV1A64_Hash(buffer1, sizeof(buffer1));
|
||||||
|
hash = Dqn_FNV1A64_Iterate(buffer2, sizeof(buffer2), hash); // subsequent hashing
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(DQN_FNV1A32_SEED)
|
||||||
#define DQN_FNV1A32_SEED 2166136261U
|
#define DQN_FNV1A32_SEED 2166136261U
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DQN_FNV1A64_SEED
|
#if !defined(DQN_FNV1A64_SEED)
|
||||||
#define DQN_FNV1A64_SEED 14695981039346656037ULL
|
#define DQN_FNV1A64_SEED 14695981039346656037ULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @begincode
|
|
||||||
/// char buffer1[128] = {random bytes};
|
|
||||||
/// char buffer2[128] = {random bytes};
|
|
||||||
/// uint64_t hash = Dqn_FNV1A64_Hash(buffer1, sizeof(buffer1));
|
|
||||||
/// hash = Dqn_FNV1A64_Iterate(buffer2, sizeof(buffer2), hash); // subsequent hashing
|
|
||||||
/// @endcode
|
|
||||||
DQN_API uint32_t Dqn_FNV1A32_Hash (void const *bytes, Dqn_usize size);
|
DQN_API uint32_t Dqn_FNV1A32_Hash (void const *bytes, Dqn_usize size);
|
||||||
DQN_API uint64_t Dqn_FNV1A64_Hash (void const *bytes, Dqn_usize size);
|
DQN_API uint64_t Dqn_FNV1A64_Hash (void const *bytes, Dqn_usize size);
|
||||||
DQN_API uint32_t Dqn_FNV1A32_Iterate(void const *bytes, Dqn_usize size, uint32_t hash);
|
DQN_API uint32_t Dqn_FNV1A32_Iterate(void const *bytes, Dqn_usize size, uint32_t hash);
|
||||||
|
30
dqn_math.cpp
30
dqn_math.cpp
@ -1,5 +1,5 @@
|
|||||||
#if !defined(DQN_NO_MATH)
|
#if !defined(DQN_NO_V2)
|
||||||
// NOTE: [$MATH] Math ==============================================================================
|
// NOTE: [$VEC2] Vector2 ===========================================================================
|
||||||
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a)
|
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a)
|
||||||
{
|
{
|
||||||
Dqn_V2I result = Dqn_V2I(DQN_CAST(int32_t)a.x, DQN_CAST(int32_t)a.y);
|
Dqn_V2I result = Dqn_V2I(DQN_CAST(int32_t)a.x, DQN_CAST(int32_t)a.y);
|
||||||
@ -51,9 +51,10 @@ DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a)
|
|||||||
Dqn_V2 result = Dqn_V2(-a.y, a.x);
|
Dqn_V2 result = Dqn_V2(-a.y, a.x);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif // !defined(DQN_NO_V2)
|
||||||
|
|
||||||
// NOTE: Dqn_V3 Implementation
|
#if !defined(DQN_NO_V3)
|
||||||
// -------------------------------------------------------------------------------------------------
|
// NOTE: [$VEC3] Vector3 ===========================================================================
|
||||||
DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a)
|
DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a)
|
||||||
{
|
{
|
||||||
Dqn_f32 result = DQN_SQUARED(a.x) + DQN_SQUARED(a.y) + DQN_SQUARED(a.z);
|
Dqn_f32 result = DQN_SQUARED(a.x) + DQN_SQUARED(a.y) + DQN_SQUARED(a.z);
|
||||||
@ -73,17 +74,19 @@ DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a)
|
|||||||
Dqn_V3 result = a / length;
|
Dqn_V3 result = a / length;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif // !defined(DQN_NO_V3)
|
||||||
|
|
||||||
// NOTE: Dqn_V4 Implementation
|
#if !defined(DQN_NO_V4)
|
||||||
// -------------------------------------------------------------------------------------------------
|
// NOTE: [$VEC4] Vector4 ===========================================================================
|
||||||
DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b)
|
DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b)
|
||||||
{
|
{
|
||||||
Dqn_f32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
|
Dqn_f32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif // !defined(DQN_NO_V4)
|
||||||
|
|
||||||
// NOTE: Dqn_M4 Implementation
|
#if !defined(DQN_NO_M4)
|
||||||
// -------------------------------------------------------------------------------------------------
|
// NOTE: [$MAT4] Dqn_M4 ============================================================================
|
||||||
DQN_API Dqn_M4 Dqn_M4_Identity()
|
DQN_API Dqn_M4 Dqn_M4_Identity()
|
||||||
{
|
{
|
||||||
Dqn_M4 result =
|
Dqn_M4 result =
|
||||||
@ -331,9 +334,10 @@ DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif // !defined(DQN_M4)
|
||||||
|
|
||||||
// NOTE: Dqn_Rect
|
#if !defined(DQN_NO_RECT)
|
||||||
// -------------------------------------------------------------------------------------------------
|
// NOTE: [$RECT] Dqn_Rect ==========================================================================
|
||||||
DQN_API Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size)
|
DQN_API Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size)
|
||||||
{
|
{
|
||||||
Dqn_Rect result = {};
|
Dqn_Rect result = {};
|
||||||
@ -428,9 +432,9 @@ DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect)
|
|||||||
Dqn_V2I result = rect.max - rect.min;
|
Dqn_V2I result = rect.max - rect.min;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif // !defined(DQN_NO_RECT)
|
||||||
|
|
||||||
// NOTE: Math Utils
|
// NOTE: [$MATH] Other =============================================================================
|
||||||
// -------------------------------------------------------------------------------------------------
|
|
||||||
DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b)
|
DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b)
|
||||||
{
|
{
|
||||||
Dqn_V2 result = {};
|
Dqn_V2 result = {};
|
||||||
@ -444,5 +448,3 @@ DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b)
|
|||||||
Dqn_f32 result = a + ((b - a) * t);
|
Dqn_f32 result = a + ((b - a) * t);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif // !defined(DQN_NO_MATH)
|
|
||||||
|
|
||||||
|
61
dqn_math.h
61
dqn_math.h
@ -1,11 +1,16 @@
|
|||||||
// NOTE: Table Of Contents =========================================================================
|
// NOTE: Table Of Contents =========================================================================
|
||||||
// Index | Disable #define | Description
|
// Index | Disable #define | Description
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
// [$MATH] Math | DQN_NO_MATH | v2i, V2, V3, V4, Mat4, Rect, RectI32, Lerp
|
// [$VEC2] Dqn_V2, V2i | DQN_NO_V2 |
|
||||||
|
// [$VEC3] Dqn_V3, V3i | DQN_NO_V3 |
|
||||||
|
// [$VEC4] Dqn_V4, V4i | DQN_NO_V4 |
|
||||||
|
// [$MAT4] Dqn_M4 | DQN_NO_M4 |
|
||||||
|
// [$RECT] Dqn_Rect | DQN_NO_RECT |
|
||||||
|
// [$MATH] Other | |
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
|
||||||
#if !defined(DQN_NO_MATH)
|
#if !defined(DQN_NO_V2)
|
||||||
// NOTE: [$MATH] Math ==============================================================================
|
// NOTE: [$VEC2] Vector2 ===========================================================================
|
||||||
struct Dqn_V2I
|
struct Dqn_V2I
|
||||||
{
|
{
|
||||||
int32_t x, y;
|
int32_t x, y;
|
||||||
@ -71,6 +76,18 @@ struct Dqn_V2
|
|||||||
Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; }
|
Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a);
|
||||||
|
DQN_API Dqn_V2 Dqn_V2Min(Dqn_V2 a, Dqn_V2 b);
|
||||||
|
DQN_API Dqn_V2 Dqn_V2Max(Dqn_V2 a, Dqn_V2 b);
|
||||||
|
DQN_API Dqn_V2 Dqn_V2Abs(Dqn_V2 a);
|
||||||
|
DQN_API Dqn_f32 Dqn_V2Dot(Dqn_V2 a, Dqn_V2 b);
|
||||||
|
DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b);
|
||||||
|
DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a);
|
||||||
|
DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a);
|
||||||
|
#endif // !defined(DQN_NO_V2)
|
||||||
|
|
||||||
|
#if !defined(DQN_NO_V3)
|
||||||
|
// NOTE: [$VEC3] Vector3 ===========================================================================
|
||||||
struct Dqn_V3
|
struct Dqn_V3
|
||||||
{
|
{
|
||||||
Dqn_f32 x, y, z;
|
Dqn_f32 x, y, z;
|
||||||
@ -106,6 +123,18 @@ struct Dqn_V3
|
|||||||
Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; }
|
Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a);
|
||||||
|
DQN_API Dqn_f32 Dqn_V3Length(Dqn_V3 a);
|
||||||
|
DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a);
|
||||||
|
#endif // !defined(DQN_NO_V3)
|
||||||
|
|
||||||
|
#if !defined(DQN_NO_V4)
|
||||||
|
// NOTE: [$VEC4] Vector4 ===========================================================================
|
||||||
|
|
||||||
|
#if defined(DQN_NO_V3)
|
||||||
|
#error "Dqn_Rect requires Dqn_V3 hence DQN_NO_V3 must *not* be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
union Dqn_V4
|
union Dqn_V4
|
||||||
{
|
{
|
||||||
struct { Dqn_f32 x, y, z, w; };
|
struct { Dqn_f32 x, y, z, w; };
|
||||||
@ -139,26 +168,16 @@ union Dqn_V4
|
|||||||
Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; }
|
Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; }
|
||||||
Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; }
|
Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; }
|
||||||
};
|
};
|
||||||
|
#endif // !defined(DQN_NO_V4)
|
||||||
|
|
||||||
|
#if !defined(DQN_NO_M4)
|
||||||
|
// NOTE: [$MAT4] Dqn_M4 ============================================================================
|
||||||
// NOTE: Column major matrix
|
// NOTE: Column major matrix
|
||||||
struct Dqn_M4
|
struct Dqn_M4
|
||||||
{
|
{
|
||||||
Dqn_f32 columns[4][4];
|
Dqn_f32 columns[4][4];
|
||||||
};
|
};
|
||||||
|
|
||||||
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a);
|
|
||||||
DQN_API Dqn_V2 Dqn_V2Min(Dqn_V2 a, Dqn_V2 b);
|
|
||||||
DQN_API Dqn_V2 Dqn_V2Max(Dqn_V2 a, Dqn_V2 b);
|
|
||||||
DQN_API Dqn_V2 Dqn_V2Abs(Dqn_V2 a);
|
|
||||||
DQN_API Dqn_f32 Dqn_V2Dot(Dqn_V2 a, Dqn_V2 b);
|
|
||||||
DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b);
|
|
||||||
DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a);
|
|
||||||
DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a);
|
|
||||||
|
|
||||||
DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a);
|
|
||||||
DQN_API Dqn_f32 Dqn_V3Length(Dqn_V3 a);
|
|
||||||
DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a);
|
|
||||||
|
|
||||||
DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b);
|
DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b);
|
||||||
|
|
||||||
DQN_API Dqn_M4 Dqn_M4_Identity();
|
DQN_API Dqn_M4 Dqn_M4_Identity();
|
||||||
@ -182,6 +201,13 @@ DQN_API Dqn_M4 Dqn_M4_DivF(Dqn_M4 lhs, Dqn_f32 rhs);
|
|||||||
#if !defined(DQN_NO_FSTRING8)
|
#if !defined(DQN_NO_FSTRING8)
|
||||||
DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat);
|
DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat);
|
||||||
#endif
|
#endif
|
||||||
|
#endif // !defined(DQN_M4)
|
||||||
|
|
||||||
|
// NOTE: [$RECT] Dqn_Rect ==========================================================================
|
||||||
|
#if !defined(DQN_NO_RECT)
|
||||||
|
#if defined(DQN_NO_V2)
|
||||||
|
#error "Dqn_Rect requires Dqn_V2 hence DQN_NO_V2 must *not* be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
struct Dqn_Rect
|
struct Dqn_Rect
|
||||||
{
|
{
|
||||||
@ -212,8 +238,9 @@ DQN_API Dqn_Rect Dqn_Rect_Intersection(Dqn_Rect a, Dqn_Rect b);
|
|||||||
DQN_API Dqn_Rect Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b);
|
DQN_API Dqn_Rect Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b);
|
||||||
DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a);
|
DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a);
|
||||||
DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect);
|
DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect);
|
||||||
|
#endif // !defined(DQN_NO_RECT)
|
||||||
|
|
||||||
|
// NOTE: [$MATH] Other =============================================================================
|
||||||
DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b);
|
DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b);
|
||||||
DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b);
|
DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b);
|
||||||
#endif // !defined(DQN_NO_MATH)
|
|
||||||
|
|
||||||
|
159
dqn_memory.h
159
dqn_memory.h
@ -29,54 +29,36 @@
|
|||||||
#define DQN_LEAK_TRACE_UNUSED
|
#define DQN_LEAK_TRACE_UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct Dqn_LeakTrace {
|
struct Dqn_LeakTrace
|
||||||
void *ptr; ///< The pointer we are tracking
|
{
|
||||||
Dqn_usize size; ///< Size of the allocation
|
void *ptr; // The pointer we are tracking
|
||||||
Dqn_CallSite call_site; ///< Call site where the allocation was allocated
|
Dqn_usize size; // Size of the allocation
|
||||||
bool freed; ///< True if this pointer has been freed
|
Dqn_CallSite call_site; // Call site where the allocation was allocated
|
||||||
Dqn_usize freed_size; ///< Size of the allocation that has been freed
|
bool freed; // True if this pointer has been freed
|
||||||
Dqn_CallSite freed_call_site; ///< Call site where the allocation was freed
|
Dqn_usize freed_size; // Size of the allocation that has been freed
|
||||||
} Dqn_LeakTrace;
|
Dqn_CallSite freed_call_site; // Call site where the allocation was freed
|
||||||
|
};
|
||||||
|
|
||||||
/// Allocate memory
|
|
||||||
/// @param size The number of bytes to allocate
|
|
||||||
/// @param zero_mem Flag to indicate if the allocated memory should be zero-ed out
|
|
||||||
/// @param user_context The user assigned pointer in the allocator
|
|
||||||
typedef void *Dqn_Allocator_AllocProc(DQN_LEAK_TRACE_FUNCTION size_t size, uint8_t align, Dqn_ZeroMem zero_mem, void *user_context);
|
typedef void *Dqn_Allocator_AllocProc(DQN_LEAK_TRACE_FUNCTION size_t size, uint8_t align, Dqn_ZeroMem zero_mem, void *user_context);
|
||||||
|
typedef void Dqn_Allocator_DeallocProc(DQN_LEAK_TRACE_FUNCTION void *ptr, size_t size, void *user_context);
|
||||||
|
|
||||||
/// Deallocate memory
|
struct Dqn_Allocator
|
||||||
/// @param ptr The pointer to deallocate memory for
|
{
|
||||||
/// @param size The number of bytes to deallocate
|
void *user_context; // User assigned pointer that is passed into the allocator functions
|
||||||
/// @param user_context The user assigned pointer in the allocator
|
Dqn_Allocator_AllocProc *alloc; // Memory allocating routine
|
||||||
typedef void Dqn_Allocator_DeallocProc(DQN_LEAK_TRACE_FUNCTION void *ptr, size_t size, void *user_context);
|
Dqn_Allocator_DeallocProc *dealloc; // Memory deallocating routine
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct Dqn_Allocator {
|
// NOTE: Macros ==================================================================================
|
||||||
void *user_context; ///< User assigned pointer that is passed into the allocator functions
|
|
||||||
Dqn_Allocator_AllocProc *alloc; ///< Memory allocating routine
|
|
||||||
Dqn_Allocator_DeallocProc *dealloc; ///< Memory deallocating routine
|
|
||||||
} Dqn_Allocator;
|
|
||||||
|
|
||||||
/// Allocate bytes from the given allocator
|
|
||||||
/// @param[in] allocator The allocator to allocate bytes from
|
|
||||||
/// @param[in] size The amount of bytes to allocator
|
|
||||||
/// @param[in] zero_mem Flag to indicate if the allocated must be zero-ed out
|
|
||||||
#define Dqn_Allocator_Alloc(allocator, size, align, zero_mem) Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, size, align, zero_mem)
|
#define Dqn_Allocator_Alloc(allocator, size, align, zero_mem) Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, size, align, zero_mem)
|
||||||
void *Dqn_Allocator_Alloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, size_t size, uint8_t align, Dqn_ZeroMem zero_mem);
|
|
||||||
|
|
||||||
/// Deallocate the memory from the pointer using the allocator
|
|
||||||
///
|
|
||||||
/// The pointer must originally have been allocated from the passed in
|
|
||||||
/// allocator. The size must also match the size that was originally allocated.
|
|
||||||
///
|
|
||||||
/// @param[in] allocator The allocator to allocate bytes from
|
|
||||||
/// @param[in] ptr The pointer to deallocate
|
|
||||||
/// @param[in] size The amount of bytes to deallocate.
|
|
||||||
#define Dqn_Allocator_Dealloc(allocator, ptr, size) Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE allocator, ptr, size)
|
#define Dqn_Allocator_Dealloc(allocator, ptr, size) Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE allocator, ptr, size)
|
||||||
void Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, void *ptr, size_t size);
|
|
||||||
|
|
||||||
#define Dqn_Allocator_NewArray(allocator, Type, count, zero_mem) (Type *)Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, sizeof(Type) * count, alignof(Type), zero_mem)
|
#define Dqn_Allocator_NewArray(allocator, Type, count, zero_mem) (Type *)Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, sizeof(Type) * count, alignof(Type), zero_mem)
|
||||||
#define Dqn_Allocator_New(allocator, Type, zero_mem) (Type *)Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, sizeof(Type), alignof(Type), zero_mem)
|
#define Dqn_Allocator_New(allocator, Type, zero_mem) (Type *)Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, sizeof(Type), alignof(Type), zero_mem)
|
||||||
|
|
||||||
|
// NOTE: Internal ==================================================================================
|
||||||
|
void *Dqn_Allocator_Alloc_ (DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, size_t size, uint8_t align, Dqn_ZeroMem zero_mem);
|
||||||
|
void Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, void *ptr, size_t size);
|
||||||
|
|
||||||
// NOTE: [$VMEM] Dqn_VMem ==========================================================================
|
// NOTE: [$VMEM] Dqn_VMem ==========================================================================
|
||||||
enum Dqn_VMemCommit
|
enum Dqn_VMemCommit
|
||||||
{
|
{
|
||||||
@ -86,21 +68,23 @@ enum Dqn_VMemCommit
|
|||||||
|
|
||||||
enum Dqn_VMemPage
|
enum Dqn_VMemPage
|
||||||
{
|
{
|
||||||
/// Exception on read/write with a page. This flag overrides the read/write access.
|
// Exception on read/write with a page. This flag overrides the read/write
|
||||||
|
// access.
|
||||||
Dqn_VMemPage_NoAccess = 1 << 0,
|
Dqn_VMemPage_NoAccess = 1 << 0,
|
||||||
|
|
||||||
/// Only read permitted on the page.
|
// Only read permitted on the page.
|
||||||
Dqn_VMemPage_Read = 1 << 1,
|
Dqn_VMemPage_Read = 1 << 1,
|
||||||
|
|
||||||
/// Only write permitted on the page. On Windows this is not supported and will be promoted to
|
// Only write permitted on the page. On Windows this is not supported and
|
||||||
/// read+write permissions.
|
// will be promoted to read+write permissions.
|
||||||
Dqn_VMemPage_Write = 1 << 2,
|
Dqn_VMemPage_Write = 1 << 2,
|
||||||
|
|
||||||
Dqn_VMemPage_ReadWrite = Dqn_VMemPage_Read | Dqn_VMemPage_Write,
|
Dqn_VMemPage_ReadWrite = Dqn_VMemPage_Read | Dqn_VMemPage_Write,
|
||||||
|
|
||||||
/// Modifier used in conjunction with previous flags. Raises exception on first access to the
|
// Modifier used in conjunction with previous flags. Raises exception on
|
||||||
/// page, then, the underlying protection flags are active. This is supported on Windows, on
|
// first access to the page, then, the underlying protection flags are
|
||||||
/// other OS's using this flag will set the OS equivalent of Dqn_VMemPage_NoAccess.
|
// active. This is supported on Windows, on other OS's using this flag will
|
||||||
|
// set the OS equivalent of Dqn_VMemPage_NoAccess.
|
||||||
Dqn_VMemPage_Guard = 1 << 3,
|
Dqn_VMemPage_Guard = 1 << 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -149,7 +133,6 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags);
|
|||||||
// 64GB) since the arena only commits as much as needed.
|
// 64GB) since the arena only commits as much as needed.
|
||||||
//
|
//
|
||||||
// NOTE: API
|
// NOTE: API
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_Grow
|
// @proc Dqn_Arena_Grow
|
||||||
// @desc Grow the arena's capacity by allocating a block of memory with the
|
// @desc Grow the arena's capacity by allocating a block of memory with the
|
||||||
// requested size. The requested size is rounded up to the nearest 64k
|
// requested size. The requested size is rounded up to the nearest 64k
|
||||||
@ -160,7 +143,7 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags);
|
|||||||
// pages from the OS.
|
// pages from the OS.
|
||||||
// @param flags[in] Bit flags from 'Dqn_ArenaBlockFlags', set to 0 if none
|
// @param flags[in] Bit flags from 'Dqn_ArenaBlockFlags', set to 0 if none
|
||||||
// @return The block of memory that
|
// @return The block of memory that
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_Allocate, Dqn_Arena_New, Dqn_Arena_NewArray,
|
// @proc Dqn_Arena_Allocate, Dqn_Arena_New, Dqn_Arena_NewArray,
|
||||||
// Dqn_Arena_NewArrayWithBlock,
|
// Dqn_Arena_NewArrayWithBlock,
|
||||||
// @desc Allocate byte/objects
|
// @desc Allocate byte/objects
|
||||||
@ -169,37 +152,37 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags);
|
|||||||
// `NewArray` allocates an array of objects
|
// `NewArray` allocates an array of objects
|
||||||
// `NewArrayWithBlock` allocates an array of objects from the given memory 'block'
|
// `NewArrayWithBlock` allocates an array of objects from the given memory 'block'
|
||||||
// @return A pointer to the allocated bytes/object. Null pointer on failure
|
// @return A pointer to the allocated bytes/object. Null pointer on failure
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_Copy, Dqn_Arena_CopyZ
|
// @proc Dqn_Arena_Copy, Dqn_Arena_CopyZ
|
||||||
// @desc Allocate a copy of an object's bytes. The 'Z' variant adds
|
// @desc Allocate a copy of an object's bytes. The 'Z' variant adds
|
||||||
// a null-terminating byte at the end of the stream.
|
// a null-terminating byte at the end of the stream.
|
||||||
// @return A pointer to the allocated object. Null pointer on failure.
|
// @return A pointer to the allocated object. Null pointer on failure.
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_Reset
|
// @proc Dqn_Arena_Reset
|
||||||
// @desc Set the arena's current block to the first block in the linked list
|
// @desc Set the arena's current block to the first block in the linked list
|
||||||
// of blocks and mark all blocks free.
|
// of blocks and mark all blocks free.
|
||||||
// @param[in] zero_mem When yes, the memory is cleared using DQN_MEMSET with the
|
// @param[in] zero_mem When yes, the memory is cleared using DQN_MEMSET with the
|
||||||
// value of DQN_MEMSET_BYTE
|
// value of DQN_MEMSET_BYTE
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_Free
|
// @proc Dqn_Arena_Free
|
||||||
// @desc Free the arena returning all memory back to the OS
|
// @desc Free the arena returning all memory back to the OS
|
||||||
// @param[in] zero_mem: When true, the memory is cleared using DQN_MEMSET with
|
// @param[in] zero_mem: When true, the memory is cleared using DQN_MEMSET with
|
||||||
// the value of DQN_MEMSET_BYTE
|
// the value of DQN_MEMSET_BYTE
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_BeginTempMemory
|
// @proc Dqn_Arena_BeginTempMemory
|
||||||
// @desc Begin an allocation scope where all allocations between begin and end
|
// @desc Begin an allocation scope where all allocations between begin and end
|
||||||
// calls will be reverted. Useful for short-lived or highly defined lifetime
|
// calls will be reverted. Useful for short-lived or highly defined lifetime
|
||||||
// allocations. An allocation scope is invalidated if the arena is freed
|
// allocations. An allocation scope is invalidated if the arena is freed
|
||||||
// between the begin and end call.
|
// between the begin and end call.
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_EndTempMemory
|
// @proc Dqn_Arena_EndTempMemory
|
||||||
// @desc End an allocation scope previously begun by calling begin scope.
|
// @desc End an allocation scope previously begun by calling begin scope.
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_StatString
|
// @proc Dqn_Arena_StatString
|
||||||
// @desc Dump the stats of the given arena to a string
|
// @desc Dump the stats of the given arena to a string
|
||||||
// @param[in] arena The arena to dump stats for
|
// @param[in] arena The arena to dump stats for
|
||||||
// @return A stack allocated string containing the stats of the arena
|
// @return A stack allocated string containing the stats of the arena
|
||||||
//
|
|
||||||
// @proc Dqn_Arena_LogStats
|
// @proc Dqn_Arena_LogStats
|
||||||
// @desc Dump the stats of the given arena to the memory log-stream.
|
// @desc Dump the stats of the given arena to the memory log-stream.
|
||||||
// @param[in] arena The arena to dump stats for
|
// @param[in] arena The arena to dump stats for
|
||||||
@ -211,29 +194,29 @@ enum Dqn_ArenaBlockFlags
|
|||||||
|
|
||||||
struct Dqn_ArenaStat
|
struct Dqn_ArenaStat
|
||||||
{
|
{
|
||||||
Dqn_usize capacity; ///< Total allocating capacity of the arena in bytes
|
Dqn_usize capacity; // Total allocating capacity of the arena in bytes
|
||||||
Dqn_usize used; ///< Total amount of bytes used in the arena
|
Dqn_usize used; // Total amount of bytes used in the arena
|
||||||
Dqn_usize wasted; ///< Orphaned space in blocks due to allocations requiring more space than available in the active block
|
Dqn_usize wasted; // Orphaned space in blocks due to allocations requiring more space than available in the active block
|
||||||
uint32_t blocks; ///< Number of memory blocks in the arena
|
uint32_t blocks; // Number of memory blocks in the arena
|
||||||
Dqn_usize syscalls; ///< Number of memory allocation syscalls into the OS
|
Dqn_usize syscalls; // Number of memory allocation syscalls into the OS
|
||||||
|
|
||||||
Dqn_usize capacity_hwm; ///< High-water mark for 'capacity'
|
Dqn_usize capacity_hwm; // High-water mark for 'capacity'
|
||||||
Dqn_usize used_hwm; ///< High-water mark for 'used'
|
Dqn_usize used_hwm; // High-water mark for 'used'
|
||||||
Dqn_usize wasted_hwm; ///< High-water mark for 'wasted'
|
Dqn_usize wasted_hwm; // High-water mark for 'wasted'
|
||||||
uint32_t blocks_hwm; ///< High-water mark for 'blocks'
|
uint32_t blocks_hwm; // High-water mark for 'blocks'
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_ArenaBlock
|
struct Dqn_ArenaBlock
|
||||||
{
|
{
|
||||||
struct Dqn_Arena *arena; ///< Arena that owns this block
|
struct Dqn_Arena *arena; // Arena that owns this block
|
||||||
void *memory; ///< Backing memory of the block
|
void *memory; // Backing memory of the block
|
||||||
Dqn_usize size; ///< Size of the block
|
Dqn_usize size; // Size of the block
|
||||||
Dqn_usize used; ///< Number of bytes used up in the block. Always less than the commit amount.
|
Dqn_usize used; // Number of bytes used up in the block. Always less than the commit amount.
|
||||||
Dqn_usize hwm_used;///< High-water mark for 'used' bytes in this block
|
Dqn_usize hwm_used;// High-water mark for 'used' bytes in this block
|
||||||
Dqn_usize commit; ///< Number of bytes in the block physically backed by pages
|
Dqn_usize commit; // Number of bytes in the block physically backed by pages
|
||||||
Dqn_ArenaBlock *prev; ///< Previous linked block
|
Dqn_ArenaBlock *prev; // Previous linked block
|
||||||
Dqn_ArenaBlock *next; ///< Next linked block
|
Dqn_ArenaBlock *next; // Next linked block
|
||||||
uint8_t flags; ///< Bit field for 'Dqn_ArenaBlockFlags'
|
uint8_t flags; // Bit field for 'Dqn_ArenaBlockFlags'
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_ArenaStatString
|
struct Dqn_ArenaStatString
|
||||||
@ -246,21 +229,21 @@ struct Dqn_Arena
|
|||||||
{
|
{
|
||||||
bool use_after_free_guard;
|
bool use_after_free_guard;
|
||||||
uint32_t temp_memory_count;
|
uint32_t temp_memory_count;
|
||||||
Dqn_String8 label; ///< Optional label to describe the arena
|
Dqn_String8 label; // Optional label to describe the arena
|
||||||
Dqn_ArenaBlock *head; ///< Active block the arena is allocating from
|
Dqn_ArenaBlock *head; // Active block the arena is allocating from
|
||||||
Dqn_ArenaBlock *curr; ///< Active block the arena is allocating from
|
Dqn_ArenaBlock *curr; // Active block the arena is allocating from
|
||||||
Dqn_ArenaBlock *tail; ///< Last block in the linked list of blocks
|
Dqn_ArenaBlock *tail; // Last block in the linked list of blocks
|
||||||
Dqn_ArenaStat stats; ///< Current arena stats, reset when reset usage is invoked.
|
Dqn_ArenaStat stats; // Current arena stats, reset when reset usage is invoked.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dqn_ArenaTempMemory
|
struct Dqn_ArenaTempMemory
|
||||||
{
|
{
|
||||||
Dqn_Arena *arena; ///< Arena the scope is for
|
Dqn_Arena *arena; // Arena the scope is for
|
||||||
Dqn_ArenaBlock *head; ///< Head block of the arena at the beginning of the scope
|
Dqn_ArenaBlock *head; // Head block of the arena at the beginning of the scope
|
||||||
Dqn_ArenaBlock *curr; ///< Current block of the arena at the beginning of the scope
|
Dqn_ArenaBlock *curr; // Current block of the arena at the beginning of the scope
|
||||||
Dqn_ArenaBlock *tail; ///< Tail block of the arena at the beginning of the scope
|
Dqn_ArenaBlock *tail; // Tail block of the arena at the beginning of the scope
|
||||||
Dqn_usize curr_used; ///< Current used amount of the current block
|
Dqn_usize curr_used; // Current used amount of the current block
|
||||||
Dqn_ArenaStat stats; ///< Stats of the arena at the beginning of the scope
|
Dqn_ArenaStat stats; // Stats of the arena at the beginning of the scope
|
||||||
};
|
};
|
||||||
|
|
||||||
// Automatically begin and end a temporary memory scope on object construction
|
// Automatically begin and end a temporary memory scope on object construction
|
||||||
@ -279,10 +262,10 @@ struct Dqn_ArenaTempMemoryScope_
|
|||||||
|
|
||||||
enum Dqn_ArenaCommit
|
enum Dqn_ArenaCommit
|
||||||
{
|
{
|
||||||
/// Commit the pages to ensure the block has the requested commit amount.
|
// Commit the pages to ensure the block has the requested commit amount.
|
||||||
/// No-op if the block has sufficient commit space already.
|
// No-op if the block has sufficient commit space already.
|
||||||
Dqn_ArenaCommit_EnsureSpace,
|
Dqn_ArenaCommit_EnsureSpace,
|
||||||
Dqn_ArenaCommit_GetNewPages, ///< Grow the block by the requested commit amount
|
Dqn_ArenaCommit_GetNewPages, // Grow the block by the requested commit amount
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: Allocation ================================================================================
|
// NOTE: Allocation ================================================================================
|
||||||
@ -326,7 +309,7 @@ struct Dqn_ArenaCatalogItem
|
|||||||
|
|
||||||
struct Dqn_ArenaCatalog
|
struct Dqn_ArenaCatalog
|
||||||
{
|
{
|
||||||
Dqn_TicketMutex ticket_mutex; ///< Mutex for adding to the linked list of arenas
|
Dqn_TicketMutex ticket_mutex; // Mutex for adding to the linked list of arenas
|
||||||
Dqn_Arena *arena;
|
Dqn_Arena *arena;
|
||||||
Dqn_ArenaCatalogItem sentinel;
|
Dqn_ArenaCatalogItem sentinel;
|
||||||
uint16_t arena_count;
|
uint16_t arena_count;
|
||||||
|
Loading…
Reference in New Issue
Block a user