Files
dusk/.claude/util.md
T
2026-06-16 10:15:59 -05:00

192 lines
5.1 KiB
Markdown

# Utility Library
Source: `src/dusk/util/`
All C code in the project must use these utilities instead of their
standard library equivalents. Do not use `malloc`, `free`, `strcmp`,
`strcpy`, `memcpy`, `memset`, etc. directly.
---
## Memory (`memory.h`)
```c
void *memoryAllocate(size_t size);
void *memoryAlign(size_t alignment, size_t size); // aligned alloc
void memoryFree(void *ptr);
void memoryCopy(void *dest, const void *src, size_t size);
void memoryZero(void *dest, size_t size);
errorret_t memoryCompare(const void *a, const void *b, size_t size);
size_t memoryGetAllocatedCount(void);
// Returns the number of live allocations. Must be 0 at test teardown.
void memoryTrack(void *ptr);
// Register a pointer that was malloc'd outside the engine (e.g. by a
// third-party library) so it counts toward the allocation tracker.
```
`MEMORY_POINTERS_IN_USE` is a file-scope static tracking the live count.
It is incremented by `memoryAllocate` / `memoryTrack` and decremented by
`memoryFree`. Tests assert this is 0 at teardown to catch leaks.
---
## String (`string.h`)
Use these instead of `<string.h>` / `<ctype.h>` functions:
```c
void stringCopy(char_t *dest, const char_t *src, size_t destSize);
int stringCompare(const char_t *a, const char_t *b);
bool_t stringEquals(const char_t *a, const char_t *b);
int stringCompareInsensitive(const char_t *a, const char_t *b);
size_t stringLength(const char_t *str);
void stringTrim(char_t *str);
bool_t stringIsWhitespace(char_t c);
bool_t stringStartsWith(const char_t *str, const char_t *prefix);
bool_t stringEndsWith(const char_t *str, const char_t *suffix);
bool_t stringContains(const char_t *haystack, const char_t *needle);
char_t *stringFind(const char_t *haystack, const char_t *needle);
void stringFormat(char_t *dest, size_t destSize, const char_t *fmt, ...);
int32_t stringToInt(const char_t *str);
float_t stringToFloat(const char_t *str);
void stringFromInt(char_t *dest, size_t destSize, int32_t value);
void stringFromFloat(char_t *dest, size_t destSize, float_t value);
```
`destSize` in `stringCopy` / `stringFormat` is the buffer capacity
**excluding** the null terminator.
---
## Math (`math.h`)
```c
#define MATH_PI M_PI
#define mathMax(a, b)
#define mathMin(a, b)
#define mathClamp(x, lower, upper)
#define mathAbs(amt)
uint32_t mathNextPowTwo(uint32_t value);
float_t mathModFloat(float_t x, float_t y); // always non-negative
float_t mathLerp(float_t a, float_t b, float_t t);
// plus additional trig / remap helpers
```
The project uses **cglm** for vector and matrix math (`vec3`, `mat4`,
`glm_vec3_*`, `glm_mat4_*`, etc.). `math.h` provides scalar helpers
that complement cglm.
---
## Endian (`endian.h`)
GameCube and Wii are big-endian. Any binary data format (asset files,
network packets) must use the endian utilities when reading multi-byte
values.
```c
bool_t isHostLittleEndian(void);
uint16_t endianLittleToHost16(uint16_t value);
uint32_t endianLittleToHost32(uint32_t value);
uint64_t endianLittleToHost64(uint64_t value);
float_t endianLittleToHostFloat(float_t value);
```
If neither `DUSK_PLATFORM_ENDIAN_LITTLE` nor `DUSK_PLATFORM_ENDIAN_BIG`
is defined, the implementation falls back to a runtime check
(`ENDIAN_MAGIC` probe). Prefer setting the compile-time macro for new
platform targets.
---
## Reference counting (`ref.h`)
`ref_t` is a generic reference-counted handle with optional lock /
unlock / all-unlocked callbacks.
```c
void refInit(
ref_t *ref,
void *data,
refcallback_t onLock,
refcallback_t onUnlock,
refcallback_t onAllUnlocked // called when count -> 0; do cleanup here
);
void refLock(ref_t *ref); // increment count
bool_t refUnlock(ref_t *ref); // decrement; returns true if count == 0
```
The asset entry system uses `ref_t` internally to track how many
subsystems have locked a loaded asset.
---
## Array (`array.h`)
```c
void arrayReverse(void *array, size_t count, size_t elementSize);
```
Generic in-place reverse using the element stride.
---
## Sort (`sort.h`)
Use these instead of `qsort` for portability across all platforms.
```c
typedef int_t (*sortcompare_t)(const void *, const void *);
void sortBubble(
void *array,
const size_t count,
const size_t size,
const sortcompare_t compare
);
void sortQuick(
void *array,
const size_t count,
const size_t size,
const sortcompare_t compare
);
#define sort sortQuick // preferred; use this in new code
```
Typed convenience helpers for `uint8_t` arrays:
```c
int sortArrayU8Compare(const void *a, const void *b);
void sortArrayU8(uint8_t *array, const size_t count);
```
---
## Crypt (`crypt.h`)
CRC32 checksum for save file integrity. Not cryptographically secure --
do not use for security purposes.
```c
// One-shot checksum:
uint32_t cryptCRC32(const void *data, const size_t size);
// Streaming (incremental) CRC32:
uint32_t cryptCRC32Begin(void);
void cryptCRC32Update(
uint32_t *crc, const void *data, const size_t size
);
uint32_t cryptCRC32End(const uint32_t crc);
```
The streaming API allows computing a checksum across multiple buffers
or while interleaving other reads -- the save system uses this to
verify the whole save slot in a single pass.