mirror of
https://github.com/nicbarker/clay.git
synced 2025-01-23 01:46:02 +00:00
Compare commits
2 Commits
4b115afd57
...
f49ec15da8
Author | SHA1 | Date | |
---|---|---|---|
|
f49ec15da8 | ||
|
5261c1eef2 |
82
README.md
82
README.md
@ -410,15 +410,12 @@ Clay supports C preprocessor directives to modulate functionality at compile tim
|
||||
|
||||
The supported directives are:
|
||||
|
||||
- `CLAY_MAX_ELEMENT_COUNT` - Controls the maximum number of clay elements that memory is pre-allocated for. Defaults to **8192**, which should be more than enough for the majority of use cases. Napkin math is ~450 bytes of memory overhead per element (8192 elements is ~3.5mb of memory)
|
||||
- `CLAY_DISABLE_CULLING` - Disables [Visibility Culling](#visibility-culling) of render commands.
|
||||
- `CLAY_WASM` - Required when targeting Web Assembly.
|
||||
- `CLAY_OVERFLOW_TRAP` - By default, clay will continue to allow function calls without crashing even when it exhausts all its available pre-allocated memory. This can produce erroneous layout results that are difficult to interpret. If `CLAY_OVERFLOW_TRAP` is defined, clay will raise a `SIGTRAP` signal that will be caught by your debugger. Relies on `signal.h` being available in your environment.
|
||||
- `CLAY_DEBUG` - Used for debugging clay's internal implementation. Useful if you want to modify or debug clay, or learn how things work. It enables a number of debug features such as preserving source strings for hash IDs to make debugging easier.
|
||||
- `CLAY_EXTEND_CONFIG_RECTANGLE` - Provide additional struct members to `CLAY_RECTANGLE` that will be passed through with output render commands.
|
||||
- `CLAY_EXTEND_CONFIG_TEXT` - Provide additional struct members to `CLAY_TEXT_CONFIG` that will be passed through with output render commands.
|
||||
- `CLAY_EXTEND_CONFIG_IMAGE` - Provide additional struct members to `CLAY_IMAGE_CONFIG` that will be passed through with output render commands.
|
||||
- `CLAY_EXTEND_CONFIG_CUSTOM` - Provide additional struct members to `CLAY_IMAGE_CONFIG` that will be passed through with output render commands.
|
||||
- `CLAY_EXTEND_CONFIG_CUSTOM` - Provide additional struct members to `CLAY_CUSTOM_CONFIG` that will be passed through with output render commands.
|
||||
|
||||
### Bindings for non C
|
||||
|
||||
@ -485,9 +482,9 @@ Takes a pointer to a function that can be used to measure the `width, height` di
|
||||
|
||||
### Clay_Initialize
|
||||
|
||||
`void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions)`
|
||||
`void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler)`
|
||||
|
||||
Initializes the internal memory mapping, and sets the internal dimensions for layout.
|
||||
Initializes the internal memory mapping, sets the internal dimensions for layout, and binds an error handler for clay to use when something goes wrong.
|
||||
|
||||
### Clay_SetLayoutDimensions
|
||||
|
||||
@ -1770,4 +1767,77 @@ An enum value representing the current "state" of the pointer interaction. As an
|
||||
|
||||
---
|
||||
|
||||
### Clay_ErrorHandler
|
||||
|
||||
```C
|
||||
typedef struct
|
||||
{
|
||||
void (*errorHandlerFunction)(Clay_ErrorData errorText);
|
||||
uintptr_t userData;
|
||||
} Clay_ErrorHandler;
|
||||
```
|
||||
|
||||
**Fields**
|
||||
|
||||
**`.errorHandlerFunction`** - `void (Clay_ErrorData errorText) {}`
|
||||
|
||||
A function pointer to an error handler function, which takes `Clay_ErrorData` as an argument. This function will be called whenever Clay encounters an internal error.
|
||||
|
||||
---
|
||||
|
||||
**`.userData`** - `uintptr_t`
|
||||
|
||||
A generic pointer to extra userdata that is transparently passed through from `Clay_Initialize` to Clay's error handler callback. Defaults to NULL.
|
||||
|
||||
---
|
||||
|
||||
### Clay_ErrorData
|
||||
|
||||
```C
|
||||
typedef struct
|
||||
{
|
||||
Clay_ErrorType errorType;
|
||||
Clay_String errorText;
|
||||
uintptr_t userData;
|
||||
} Clay_ErrorData;
|
||||
```
|
||||
|
||||
**Fields**
|
||||
|
||||
**`.errorType`** - `Clay_ErrorType`
|
||||
|
||||
```C
|
||||
typedef enum {
|
||||
CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
|
||||
CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
|
||||
CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
|
||||
CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
|
||||
CLAY_ERROR_TYPE_DUPLICATE_ID,
|
||||
CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
|
||||
CLAY_ERROR_TYPE_INTERNAL_ERROR,
|
||||
} Clay_ErrorType;
|
||||
```
|
||||
|
||||
An enum representing the type of error Clay encountered. It's up to the user to handle on a case by case basis, but as some general guidance:
|
||||
|
||||
- `CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED` - The user is attempting to use `CLAY_TEXT` and either forgot to call [Clay_SetMeasureTextFunction](#clay_setmeasuretextfunction) or accidentally passed a null function pointer.
|
||||
- `CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED` - Clay was initialized with an Arena that was too small for the configured [Clay_SetMaxElementCount](#clay_setmaxelementcount). Try using [Clay_MinMemorySize()](#clay_minmemorysize) to get the exact number of bytes required by the current configuration.
|
||||
- `CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED` - The declared UI hierarchy has too many elements for the configured max element count. Use [Clay_SetMaxElementCount](#clay_setmaxelementcount) to increase the max, then call [Clay_MinMemorySize()](#clay_minmemorysize) again and reinitialize clay's memory with the required size.
|
||||
- `CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED` - The declared UI hierarchy has too much text for the configured text measure cache size. Use [Clay_SetMeasureTextCacheSize](#clay_setmeasuretextcachesize) to increase the max, then call [Clay_MinMemorySize()](#clay_minmemorysize) again and reinitialize clay's memory with the required size.
|
||||
- `CLAY_ERROR_TYPE_DUPLICATE_ID` - Two elements in Clays UI Hierarchy have been declared with exactly the same ID. Set a breakpoint in your error handler function for a stack trace back to exactly where this occured.
|
||||
- `CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND` - A `CLAY_FLOATING` element was declared with the `.parentId` property, but no element with that ID was found. Set a breakpoint in your error handler function for a stack trace back to exactly where this occured.
|
||||
- `CLAY_ERROR_TYPE_INTERNAL_ERROR` - Clay has encountered an internal logic or memory error. Please report this as a bug with a stack trace to help us fix these!
|
||||
|
||||
---
|
||||
|
||||
**`.errorText`** - `Clay_String`
|
||||
|
||||
A [Clay_String](#clay_string) that provides a human readable description of the error. May change in future and should not be relied on to detect error types.
|
||||
|
||||
---
|
||||
|
||||
**`.userData`** - `uintptr_t`
|
||||
|
||||
A generic pointer to extra userdata that is transparently passed through from `Clay_Initialize` to Clay's error handler callback. Defaults to NULL.
|
||||
|
||||
---
|
25
clay.h
25
clay.h
@ -479,6 +479,7 @@ Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array,
|
||||
void Clay_SetDebugModeEnabled(bool enabled);
|
||||
void Clay_SetCullingEnabled(bool enabled);
|
||||
void Clay_SetMaxElementCount(uint32_t maxElementCount);
|
||||
void Clay_SetMeasureTextCacheSize(uint32_t measureTextCacheSize);
|
||||
|
||||
// Internal API functions required by macros
|
||||
void Clay__OpenElement();
|
||||
@ -514,14 +515,6 @@ extern uint32_t Clay__debugViewWidth;
|
||||
#ifdef CLAY_IMPLEMENTATION
|
||||
#undef CLAY_IMPLEMENTATION
|
||||
|
||||
#ifndef CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT
|
||||
#define CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT 16
|
||||
#endif
|
||||
|
||||
#ifndef CLAY_MEASURE_TEXT_CACHE_SIZE
|
||||
#define CLAY_MEASURE_TEXT_CACHE_SIZE Clay__maxElementCount * 2
|
||||
#endif
|
||||
|
||||
#ifndef CLAY__NULL
|
||||
#define CLAY__NULL 0
|
||||
#endif
|
||||
@ -531,7 +524,8 @@ extern uint32_t Clay__debugViewWidth;
|
||||
#endif
|
||||
|
||||
bool Clay__warningsEnabled = true;
|
||||
uint32_t Clay__maxElementCount = 128;
|
||||
uint32_t Clay__maxElementCount = 8192;
|
||||
uint32_t Clay__measureTextCacheSize = 16384;
|
||||
Clay_ErrorHandler Clay__errorHandler = CLAY__INIT(Clay_ErrorHandler) { .errorHandlerFunction = Clay__Noop };
|
||||
|
||||
void Clay__Noop() {};
|
||||
@ -1583,7 +1577,7 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
return NULL;
|
||||
}
|
||||
uint32_t id = Clay__HashTextWithConfig(text, config);
|
||||
uint32_t hashBucket = id % CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT;
|
||||
uint32_t hashBucket = id % (Clay__measureTextCacheSize / 8);
|
||||
int32_t elementIndexPrevious = 0;
|
||||
int32_t elementIndex = Clay__measureTextHashMap.internalArray[hashBucket];
|
||||
while (elementIndex != 0) {
|
||||
@ -1653,7 +1647,7 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
if (!Clay__booleanWarnings.maxTextMeasureCacheExceeded) {
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED,
|
||||
.errorText = CLAY_STRING("Clay has run out of space in it's internal text measurement cache. Try increasing CLAY_MEASURE_TEXT_CACHE_SIZE."),
|
||||
.errorText = CLAY_STRING("Clay has run out of space in it's internal text measurement cache. Try using Clay_SetMeasureTextCacheSize() (default 16384, with 1 unit storing 1 measured word)."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
Clay__booleanWarnings.maxTextMeasureCacheExceeded = true;
|
||||
}
|
||||
@ -2034,9 +2028,9 @@ void Clay__InitializePersistentMemory(Clay_Arena *arena) {
|
||||
Clay__layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__measureTextHashMapInternalFreeList = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__measuredWordsFreeList = Clay__int32_tArray_Allocate_Arena(CLAY_MEASURE_TEXT_CACHE_SIZE, arena);
|
||||
Clay__measuredWordsFreeList = Clay__int32_tArray_Allocate_Arena(Clay__measureTextCacheSize, arena);
|
||||
Clay__measureTextHashMap = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__measuredWords = Clay__MeasuredWordArray_Allocate_Arena(CLAY_MEASURE_TEXT_CACHE_SIZE, arena);
|
||||
Clay__measuredWords = Clay__MeasuredWordArray_Allocate_Arena(Clay__measureTextCacheSize, arena);
|
||||
Clay__pointerOverIds = Clay__ElementIdArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__debugElementData = Clay__DebugElementDataArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__arenaResetOffset = arena->nextAllocation;
|
||||
@ -3836,6 +3830,11 @@ void Clay_SetMaxElementCount(uint32_t maxElementCount) {
|
||||
Clay__maxElementCount = maxElementCount;
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_SetMeasureTextCacheSize")
|
||||
void Clay_SetMeasureTextCacheSize(uint32_t measureTextCacheSize) {
|
||||
Clay__measureTextCacheSize = measureTextCacheSize;
|
||||
}
|
||||
|
||||
#endif //CLAY_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
|
@ -202,8 +202,17 @@ void UpdateDrawFrame(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
bool reinitializeClay = false;
|
||||
|
||||
void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
printf("%s", errorData.errorText.chars);
|
||||
if (errorData.errorType == CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED) {
|
||||
reinitializeClay = true;
|
||||
Clay_SetMaxElementCount(Clay__maxElementCount * 2);
|
||||
} else if (errorData.errorType == CLAY_ERROR_TYPE_TEXT_MEASUREMENT_CAPACITY_EXCEEDED) {
|
||||
reinitializeClay = true;
|
||||
Clay_SetMeasureTextCacheSize(Clay__measureTextCacheSize * 2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
@ -230,6 +239,13 @@ int main(void) {
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
if (reinitializeClay) {
|
||||
Clay_SetMaxElementCount(8192);
|
||||
totalMemorySize = Clay_MinMemorySize();
|
||||
clayMemory = (Clay_Arena) { .label = CLAY_STRING("Clay Memory Arena"), .memory = malloc(totalMemorySize), .capacity = totalMemorySize };
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
reinitializeClay = false;
|
||||
}
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user