mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-20 05:08:04 +00:00
Initial attempt at handling overflows more comprehensively
This commit is contained in:
parent
51c5355686
commit
1d2c38a680
62
clay.h
62
clay.h
@ -468,6 +468,7 @@ void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig)
|
|||||||
|
|
||||||
extern Clay_Color Clay__debugViewHighlightColor;
|
extern Clay_Color Clay__debugViewHighlightColor;
|
||||||
extern uint32_t Clay__debugViewWidth;
|
extern uint32_t Clay__debugViewWidth;
|
||||||
|
extern bool Clay__debugMaxElementsLatch;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
@ -486,11 +487,15 @@ extern uint32_t Clay__debugViewWidth;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CLAY_MAX_ELEMENT_COUNT
|
#ifndef CLAY_MAX_ELEMENT_COUNT
|
||||||
#define CLAY_MAX_ELEMENT_COUNT 8192
|
#define CLAY_MAX_ELEMENT_COUNT 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT
|
#ifndef CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT
|
||||||
#define CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT 1024
|
#define CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT (CLAY_MAX_ELEMENT_COUNT / 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CLAY_MEASURE_TEXT_CACHE_SIZE
|
||||||
|
#define CLAY_MEASURE_TEXT_CACHE_SIZE CLAY_MAX_ELEMENT_COUNT * 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CLAY__NULL
|
#ifndef CLAY__NULL
|
||||||
@ -601,7 +606,7 @@ bool Clay__Array_IncrementCapacityCheck(uint32_t length, uint32_t capacity)
|
|||||||
if (length < capacity) {
|
if (length < capacity) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (Clay__warningsEnabled) {
|
if (Clay__warningsEnabled && !Clay__debugMaxElementsLatch) {
|
||||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to add to array that is already at capacity.") });
|
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to add to array that is already at capacity.") });
|
||||||
}
|
}
|
||||||
#ifdef CLAY_OVERFLOW_TRAP
|
#ifdef CLAY_OVERFLOW_TRAP
|
||||||
@ -1398,6 +1403,7 @@ bool Clay__debugModeEnabled = false;
|
|||||||
uint32_t Clay__debugSelectedElementId = 0;
|
uint32_t Clay__debugSelectedElementId = 0;
|
||||||
uint32_t Clay__debugViewWidth = 400;
|
uint32_t Clay__debugViewWidth = 400;
|
||||||
Clay_Color Clay__debugViewHighlightColor = CLAY__INIT(Clay_Color) { 168, 66, 28, 100 };
|
Clay_Color Clay__debugViewHighlightColor = CLAY__INIT(Clay_Color) { 168, 66, 28, 100 };
|
||||||
|
bool Clay__debugMaxElementsLatch = false;
|
||||||
uint32_t Clay__generation = 0;
|
uint32_t Clay__generation = 0;
|
||||||
uint64_t Clay__arenaResetOffset = 0;
|
uint64_t Clay__arenaResetOffset = 0;
|
||||||
Clay_Arena Clay__internalArena;
|
Clay_Arena Clay__internalArena;
|
||||||
@ -1603,8 +1609,8 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
|||||||
Clay__MeasureTextCacheItemArray_Set(&Clay__measureTextHashMapInternal, newItemIndex, newCacheItem);
|
Clay__MeasureTextCacheItemArray_Set(&Clay__measureTextHashMapInternal, newItemIndex, newCacheItem);
|
||||||
measured = Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, newItemIndex);
|
measured = Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, newItemIndex);
|
||||||
} else {
|
} else {
|
||||||
if (Clay__measureTextHashMapInternal.length == Clay__measureTextHashMapInternal.capacity) {
|
if (Clay__measureTextHashMapInternal.length == Clay__measureTextHashMapInternal.capacity - 1) {
|
||||||
return NULL;
|
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||||
}
|
}
|
||||||
measured = Clay__MeasureTextCacheItemArray_Add(&Clay__measureTextHashMapInternal, newCacheItem);
|
measured = Clay__MeasureTextCacheItemArray_Add(&Clay__measureTextHashMapInternal, newCacheItem);
|
||||||
newItemIndex = Clay__measureTextHashMapInternal.length - 1;
|
newItemIndex = Clay__measureTextHashMapInternal.length - 1;
|
||||||
@ -1616,6 +1622,9 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
|||||||
float measuredHeight = 0;
|
float measuredHeight = 0;
|
||||||
float spaceWidth = Clay__MeasureText(&CLAY__SPACECHAR, config).width;
|
float spaceWidth = Clay__MeasureText(&CLAY__SPACECHAR, config).width;
|
||||||
while (end < text->length) {
|
while (end < text->length) {
|
||||||
|
if (Clay__measuredWords.length == Clay__measuredWords.capacity - 1) {
|
||||||
|
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||||
|
}
|
||||||
char current = text->chars[end];
|
char current = text->chars[end];
|
||||||
if (current == ' ' || current == '\n') {
|
if (current == ' ' || current == '\n') {
|
||||||
uint32_t length = end - start;
|
uint32_t length = end - start;
|
||||||
@ -1661,6 +1670,9 @@ bool Clay__PointIsInsideRect(Clay_Vector2 point, Clay_BoundingBox rect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) {
|
Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Clay_LayoutElement* layoutElement) {
|
||||||
|
if (Clay__layoutElementsHashMapInternal.length == Clay__layoutElementsHashMapInternal.capacity - 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
Clay_LayoutElementHashMapItem item = CLAY__INIT(Clay_LayoutElementHashMapItem) { .elementId = elementId, .layoutElement = layoutElement, .nextIndex = -1, .generation = Clay__generation + 1 };
|
Clay_LayoutElementHashMapItem item = CLAY__INIT(Clay_LayoutElementHashMapItem) { .elementId = elementId, .layoutElement = layoutElement, .nextIndex = -1, .generation = Clay__generation + 1 };
|
||||||
uint32_t hashBucket = elementId.id % Clay__layoutElementsHashMap.capacity;
|
uint32_t hashBucket = elementId.id % Clay__layoutElementsHashMap.capacity;
|
||||||
int32_t hashItemPrevious = -1;
|
int32_t hashItemPrevious = -1;
|
||||||
@ -1706,7 +1718,7 @@ Clay_LayoutElementHashMapItem *Clay__GetHashMapItem(uint32_t id) {
|
|||||||
}
|
}
|
||||||
elementIndex = hashEntry->nextIndex;
|
elementIndex = hashEntry->nextIndex;
|
||||||
}
|
}
|
||||||
return CLAY__NULL;
|
return &CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement) {
|
void Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement) {
|
||||||
@ -1721,6 +1733,9 @@ void Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__ElementPostConfiguration() {
|
void Clay__ElementPostConfiguration() {
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||||
// ID
|
// ID
|
||||||
if (openLayoutElement->id == 0) {
|
if (openLayoutElement->id == 0) {
|
||||||
@ -1799,6 +1814,9 @@ void Clay__ElementPostConfiguration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__CloseElement() {
|
void Clay__CloseElement() {
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||||
Clay_LayoutConfig *layoutConfig = openLayoutElement->layoutConfig;
|
Clay_LayoutConfig *layoutConfig = openLayoutElement->layoutConfig;
|
||||||
bool elementHasScrollHorizontal = false;
|
bool elementHasScrollHorizontal = false;
|
||||||
@ -1890,12 +1908,20 @@ void Clay__CloseElement() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__OpenElement() {
|
void Clay__OpenElement() {
|
||||||
|
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__debugMaxElementsLatch) {
|
||||||
|
Clay__debugMaxElementsLatch = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement layoutElement = CLAY__INIT(Clay_LayoutElement) {};
|
Clay_LayoutElement layoutElement = CLAY__INIT(Clay_LayoutElement) {};
|
||||||
Clay_LayoutElementArray_Add(&Clay__layoutElements, layoutElement);
|
Clay_LayoutElementArray_Add(&Clay__layoutElements, layoutElement);
|
||||||
Clay__int32_tArray_Add(&Clay__openLayoutElementStack, Clay__layoutElements.length - 1);
|
Clay__int32_tArray_Add(&Clay__openLayoutElementStack, Clay__layoutElements.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig) {
|
void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig) {
|
||||||
|
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__debugMaxElementsLatch) {
|
||||||
|
Clay__debugMaxElementsLatch = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement *parentElement = Clay__GetOpenLayoutElement();
|
Clay_LayoutElement *parentElement = Clay__GetOpenLayoutElement();
|
||||||
parentElement->children.length++;
|
parentElement->children.length++;
|
||||||
|
|
||||||
@ -1968,7 +1994,7 @@ void Clay__InitializePersistentMemory(Clay_Arena *arena) {
|
|||||||
Clay__measureTextHashMapInternalFreeList = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__measureTextHashMapInternalFreeList = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__measuredWordsFreeList = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__measuredWordsFreeList = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__measureTextHashMap = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__measureTextHashMap = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__measuredWords = Clay__MeasuredWordArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__measuredWords = Clay__MeasuredWordArray_Allocate_Arena(CLAY_MEASURE_TEXT_CACHE_SIZE, arena);
|
||||||
Clay__pointerOverIds = Clay__ElementIdArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__pointerOverIds = Clay__ElementIdArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__debugElementData = Clay__DebugElementDataArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
Clay__debugElementData = Clay__DebugElementDataArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||||
Clay__arenaResetOffset = arena->nextAllocation;
|
Clay__arenaResetOffset = arena->nextAllocation;
|
||||||
@ -2692,6 +2718,9 @@ void Clay__CalculateFinalLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__AttachId(Clay_ElementId elementId) {
|
void Clay__AttachId(Clay_ElementId elementId) {
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||||
openLayoutElement->id = elementId.id;
|
openLayoutElement->id = elementId.id;
|
||||||
Clay__AddHashMapItem(elementId, openLayoutElement);
|
Clay__AddHashMapItem(elementId, openLayoutElement);
|
||||||
@ -2702,9 +2731,16 @@ void Clay__AttachId(Clay_ElementId elementId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay__AttachLayoutConfig(Clay_LayoutConfig *config) {
|
void Clay__AttachLayoutConfig(Clay_LayoutConfig *config) {
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
Clay__GetOpenLayoutElement()->layoutConfig = &CLAY_LAYOUT_DEFAULT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay__GetOpenLayoutElement()->layoutConfig = config;
|
Clay__GetOpenLayoutElement()->layoutConfig = config;
|
||||||
}
|
}
|
||||||
void Clay__AttachElementConfig(Clay_ElementConfigUnion config, Clay__ElementConfigType type) {
|
void Clay__AttachElementConfig(Clay_ElementConfigUnion config, Clay__ElementConfigType type) {
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||||
openLayoutElement->elementConfigs.length++;
|
openLayoutElement->elementConfigs.length++;
|
||||||
Clay__ElementConfigArray_Add(&Clay__elementConfigBuffer, CLAY__INIT(Clay_ElementConfig) { .type = type, .config = config });
|
Clay__ElementConfigArray_Add(&Clay__elementConfigBuffer, CLAY__INIT(Clay_ElementConfig) { .type = type, .config = config });
|
||||||
@ -3559,6 +3595,9 @@ void Clay_BeginLayout() {
|
|||||||
if (Clay__debugModeEnabled) {
|
if (Clay__debugModeEnabled) {
|
||||||
rootDimensions.width -= (float)Clay__debugViewWidth;
|
rootDimensions.width -= (float)Clay__debugViewWidth;
|
||||||
}
|
}
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay__OpenElement();
|
Clay__OpenElement();
|
||||||
CLAY_ID("Clay__RootContainer");
|
CLAY_ID("Clay__RootContainer");
|
||||||
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} });
|
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} });
|
||||||
@ -3567,6 +3606,8 @@ void Clay_BeginLayout() {
|
|||||||
Clay__LayoutElementTreeRootArray_Add(&Clay__layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) { .layoutElementIndex = 0 });
|
Clay__LayoutElementTreeRootArray_Add(&Clay__layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) { .layoutElementIndex = 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Clay_TextElementConfig Clay__DebugView_ErrorTextConfig = CLAY__INIT(Clay_TextElementConfig) {.textColor = {255, 0, 0, 255}, .fontSize = 16, .wrapMode = CLAY_TEXT_WRAP_NONE };
|
||||||
|
|
||||||
CLAY_WASM_EXPORT("Clay_EndLayout")
|
CLAY_WASM_EXPORT("Clay_EndLayout")
|
||||||
Clay_RenderCommandArray Clay_EndLayout()
|
Clay_RenderCommandArray Clay_EndLayout()
|
||||||
{
|
{
|
||||||
@ -3580,7 +3621,11 @@ Clay_RenderCommandArray Clay_EndLayout()
|
|||||||
Clay__warningsEnabled = true;
|
Clay__warningsEnabled = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
Clay_RenderCommandArray_Add(&Clay__renderCommands, CLAY__INIT(Clay_RenderCommand ) { .commandType = CLAY_RENDER_COMMAND_TYPE_TEXT, .boundingBox = { Clay__layoutDimensions.width / 2 - 59 * 4, Clay__layoutDimensions.height / 2 }, .text = CLAY_STRING("Clay Error: Layout elements exceeded CLAY_MAX_ELEMENT_COUNT"), .config = { .textElementConfig = &Clay__DebugView_ErrorTextConfig } });
|
||||||
|
} else {
|
||||||
Clay__CalculateFinalLayout();
|
Clay__CalculateFinalLayout();
|
||||||
|
}
|
||||||
return Clay__renderCommands;
|
return Clay__renderCommands;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3609,6 +3654,9 @@ bool Clay_Hovered() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData), intptr_t userData) {
|
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData), intptr_t userData) {
|
||||||
|
if (Clay__debugMaxElementsLatch) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||||
if (openLayoutElement->id == 0) {
|
if (openLayoutElement->id == 0) {
|
||||||
Clay__GenerateIdForAnonymousElement(openLayoutElement);
|
Clay__GenerateIdForAnonymousElement(openLayoutElement);
|
||||||
|
Loading…
Reference in New Issue
Block a user