mirror of
https://github.com/nicbarker/clay.git
synced 2025-04-18 12:18:03 +00:00
Compare commits
4 Commits
8ca6d66e0f
...
87ab6402f3
Author | SHA1 | Date | |
---|---|---|---|
|
87ab6402f3 | ||
|
6bd69bdfa9 | ||
|
08033b03cb | ||
|
04694b0da2 |
123
README.md
123
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
|
||||
|
||||
@ -483,11 +480,29 @@ Takes a pointer to a function that can be used to measure the `width, height` di
|
||||
|
||||
**Note 2: It is essential that this function is as fast as possible.** For text heavy use-cases this function is called many times, and despite the fact that clay caches text measurements internally, it can easily become the dominant overall layout cost if the provided function is slow. **This is on the hot path!**
|
||||
|
||||
### Clay_SetMaxElementCount
|
||||
|
||||
`void Clay_SetMaxElementCount(uint32_t maxElementCount)`
|
||||
|
||||
Updates the internal maximum element count, allowing clay to allocate larger UI hierarchies.
|
||||
|
||||
**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**
|
||||
|
||||
### Clay_SetMaxMeasureTextCacheWordCount
|
||||
|
||||
`void Clay_SetMaxMeasureTextCacheWordCount(uint32_t maxMeasureTextCacheWordCount)`
|
||||
|
||||
Updates the internal text measurement cache size, allowing clay to allocate more text. The value represents how many seperate words can be stored in the text measurement cache.
|
||||
|
||||
**Note: You will need to reinitialize clay, after calling [Clay_MinMemorySize()](#clay_minmemorysize) to calculate updated memory requirements.**
|
||||
|
||||
### 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.
|
||||
|
||||
Reference: [Clay_Arena](#clay_createarenawithcapacityandmemory), [Clay_ErrorHandler](#clay_errorhandler)
|
||||
|
||||
### Clay_SetLayoutDimensions
|
||||
|
||||
@ -1545,6 +1560,29 @@ Element is subject to [culling](#visibility-culling). Otherwise, a single `Clay_
|
||||
|
||||
## Data Structures & Definitions
|
||||
|
||||
### Clay_String
|
||||
|
||||
```C
|
||||
typedef struct {
|
||||
int length;
|
||||
const char *chars;
|
||||
} Clay_String;
|
||||
```
|
||||
|
||||
`Clay_String` is a string container that clay uses internally to represent all strings.
|
||||
|
||||
**Fields**
|
||||
|
||||
**`.length`** - `int`
|
||||
|
||||
The number of characters in the string, _not including an optional null terminator._
|
||||
|
||||
---
|
||||
|
||||
**`.chars`** - `const char *`
|
||||
|
||||
A pointer to the contents of the string. This data is not guaranteed to be null terminated, so if you are passing it to code that expects standard null terminated C strings, you will need to copy the data and append a null terminator.
|
||||
|
||||
### Clay_ElementId
|
||||
|
||||
```C
|
||||
@ -1770,4 +1808,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_SetMaxMeasureTextCacheWordCount](#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.
|
||||
|
||||
---
|
413
clay.h
413
clay.h
@ -144,9 +144,8 @@ typedef struct
|
||||
} Clay__StringArray;
|
||||
|
||||
typedef struct {
|
||||
Clay_String label;
|
||||
uint64_t nextAllocation;
|
||||
uint64_t capacity;
|
||||
uintptr_t nextAllocation;
|
||||
size_t capacity;
|
||||
char *memory;
|
||||
} Clay_Arena;
|
||||
|
||||
@ -394,6 +393,14 @@ typedef struct
|
||||
bool found;
|
||||
} Clay_ScrollContainerData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Clay_BoundingBox elementLocation;
|
||||
|
||||
// Indicates whether an actual Element matched the provided ID or if the default struct was returned.
|
||||
bool found;
|
||||
} Clay_ElementLocationData;
|
||||
|
||||
typedef enum {
|
||||
CLAY_RENDER_COMMAND_TYPE_NONE,
|
||||
CLAY_RENDER_COMMAND_TYPE_RECTANGLE,
|
||||
@ -412,9 +419,6 @@ typedef struct
|
||||
Clay_String text; // TODO I wish there was a way to avoid having to have this on every render command
|
||||
uint32_t id;
|
||||
Clay_RenderCommandType commandType;
|
||||
#ifdef CLAY_DEBUG
|
||||
Clay_String name;
|
||||
#endif
|
||||
} Clay_RenderCommand;
|
||||
|
||||
typedef struct
|
||||
@ -438,12 +442,35 @@ typedef struct
|
||||
Clay_PointerDataInteractionState state;
|
||||
} Clay_PointerData;
|
||||
|
||||
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;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Clay_ErrorType errorType;
|
||||
Clay_String errorText;
|
||||
uintptr_t userData;
|
||||
} Clay_ErrorData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*errorHandlerFunction)(Clay_ErrorData errorText);
|
||||
uintptr_t userData;
|
||||
} Clay_ErrorHandler;
|
||||
|
||||
// Function Forward Declarations ---------------------------------
|
||||
// Public API functions ---
|
||||
uint32_t Clay_MinMemorySize();
|
||||
Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset);
|
||||
void Clay_SetPointerState(Clay_Vector2 position, bool pointerDown);
|
||||
void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions);
|
||||
void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler);
|
||||
void Clay_UpdateScrollContainers(bool enableDragScrolling, Clay_Vector2 scrollDelta, float deltaTime);
|
||||
void Clay_SetLayoutDimensions(Clay_Dimensions dimensions);
|
||||
void Clay_BeginLayout();
|
||||
@ -458,6 +485,9 @@ void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)
|
||||
Clay_RenderCommand * Clay_RenderCommandArray_Get(Clay_RenderCommandArray* array, int32_t index);
|
||||
void Clay_SetDebugModeEnabled(bool enabled);
|
||||
void Clay_SetCullingEnabled(bool enabled);
|
||||
void Clay_SetMaxElementCount(uint32_t maxElementCount);
|
||||
void Clay_SetMaxMeasureTextCacheWordCount(uint32_t maxMeasureTextCacheWordCount);
|
||||
Clay_ElementLocationData Clay_GetElementLocationData (Clay_ElementId id);
|
||||
|
||||
// Internal API functions required by macros
|
||||
void Clay__OpenElement();
|
||||
@ -509,7 +539,6 @@ Clay__ScrollContainerDataInternal *Clay__ScrollContainerDataInternalArray_Get(Cl
|
||||
|
||||
extern Clay_Color Clay__debugViewHighlightColor;
|
||||
extern uint32_t Clay__debugViewWidth;
|
||||
extern bool Clay__debugMaxElementsLatch;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -523,22 +552,6 @@ extern bool Clay__debugMaxElementsLatch;
|
||||
#ifdef CLAY_IMPLEMENTATION
|
||||
#undef CLAY_IMPLEMENTATION
|
||||
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
#include "signal.h"
|
||||
#endif
|
||||
|
||||
#ifndef CLAY_MAX_ELEMENT_COUNT
|
||||
#define CLAY_MAX_ELEMENT_COUNT 8192
|
||||
#endif
|
||||
|
||||
#ifndef CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT
|
||||
#define CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT 128
|
||||
#endif
|
||||
|
||||
#ifndef CLAY_MEASURE_TEXT_CACHE_SIZE
|
||||
#define CLAY_MEASURE_TEXT_CACHE_SIZE CLAY_MAX_ELEMENT_COUNT * 2
|
||||
#endif
|
||||
|
||||
#ifndef CLAY__NULL
|
||||
#define CLAY__NULL 0
|
||||
#endif
|
||||
@ -548,8 +561,12 @@ extern bool Clay__debugMaxElementsLatch;
|
||||
#endif
|
||||
|
||||
bool Clay__warningsEnabled = true;
|
||||
uint32_t Clay__maxElementCount = 8192;
|
||||
uint32_t Clay__maxMeasureTextCacheWordCount = 16384;
|
||||
void Clay__ErrorHandlerFunctionDefault(Clay_ErrorData errorText) {}
|
||||
Clay_ErrorHandler Clay__errorHandler = CLAY__INIT(Clay_ErrorHandler) { .errorHandlerFunction = Clay__ErrorHandlerFunctionDefault };
|
||||
|
||||
void Clay__Noop() {};
|
||||
void Clay__Noop() {}
|
||||
|
||||
Clay_String CLAY__SPACECHAR = CLAY__INIT(Clay_String) { .length = 1, .chars = " " };
|
||||
Clay_String CLAY__STRING_DEFAULT = CLAY__INIT(Clay_String) { .length = 0, .chars = NULL };
|
||||
@ -558,7 +575,7 @@ typedef struct
|
||||
{
|
||||
bool maxElementsExceeded;
|
||||
bool maxRenderCommandsExceeded;
|
||||
bool maxStringMeasureCacheExceeded;
|
||||
bool maxTextMeasureCacheExceeded;
|
||||
} Clay_BooleanWarnings;
|
||||
|
||||
Clay_BooleanWarnings Clay__booleanWarnings;
|
||||
@ -582,7 +599,7 @@ typedef struct
|
||||
Clay__WarningArray Clay__WarningArray_Allocate_Arena(uint32_t capacity, Clay_Arena *arena) {
|
||||
size_t totalSizeBytes = capacity * sizeof(Clay_String);
|
||||
Clay__WarningArray array = CLAY__INIT(Clay__WarningArray){.capacity = capacity, .length = 0};
|
||||
uintptr_t nextAllocAddress = (uintptr_t)arena->nextAllocation + (uintptr_t)arena->memory;
|
||||
uintptr_t nextAllocAddress = arena->nextAllocation + (uintptr_t)arena->memory;
|
||||
uintptr_t arenaOffsetAligned = nextAllocAddress + (CLAY__ALIGNMENT(Clay_String) - (nextAllocAddress % CLAY__ALIGNMENT(Clay_String)));
|
||||
arenaOffsetAligned -= (uintptr_t)arena->memory;
|
||||
if (arenaOffsetAligned + totalSizeBytes <= arena->capacity) {
|
||||
@ -590,9 +607,10 @@ Clay__WarningArray Clay__WarningArray_Allocate_Arena(uint32_t capacity, Clay_Are
|
||||
arena->nextAllocation = arenaOffsetAligned + totalSizeBytes;
|
||||
}
|
||||
else {
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
|
||||
.errorText = CLAY_STRING("Clay attempted to allocate memory in its arena, but ran out of capacity. Try increasing the capacity of the arena passed to Clay_Initialize()"),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
}
|
||||
return array;
|
||||
}
|
||||
@ -605,18 +623,13 @@ Clay__Warning *Clay__WarningArray_Add(Clay__WarningArray *array, Clay__Warning i
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
else {
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
return &CLAY__WARNING_DEFAULT;
|
||||
}
|
||||
|
||||
void* Clay__Array_Allocate_Arena(uint32_t capacity, uint32_t itemSize, uint32_t alignment, Clay_Arena *arena)
|
||||
{
|
||||
size_t totalSizeBytes = capacity * itemSize;
|
||||
uintptr_t nextAllocAddress = (uintptr_t)arena->nextAllocation + (uintptr_t)arena->memory;
|
||||
uintptr_t nextAllocAddress = arena->nextAllocation + (uintptr_t)arena->memory;
|
||||
uintptr_t arenaOffsetAligned = nextAllocAddress + (alignment - (nextAllocAddress % alignment));
|
||||
arenaOffsetAligned -= (uintptr_t)arena->memory;
|
||||
if (arenaOffsetAligned + totalSizeBytes <= arena->capacity) {
|
||||
@ -624,12 +637,10 @@ void* Clay__Array_Allocate_Arena(uint32_t capacity, uint32_t itemSize, uint32_t
|
||||
return (void*)((uintptr_t)arena->memory + (uintptr_t)arenaOffsetAligned);
|
||||
}
|
||||
else {
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to allocate array in arena, but arena is already at capacity and would overflow.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_ARENA_CAPACITY_EXCEEDED,
|
||||
.errorText = CLAY_STRING("Clay attempted to allocate memory in its arena, but ran out of capacity. Try increasing the capacity of the arena passed to Clay_Initialize()"),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
}
|
||||
return CLAY__NULL;
|
||||
}
|
||||
@ -639,26 +650,22 @@ bool Clay__Array_RangeCheck(int index, uint32_t length)
|
||||
if (index < length && index >= 0) {
|
||||
return true;
|
||||
}
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Array access out of bounds.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_INTERNAL_ERROR,
|
||||
.errorText = CLAY_STRING("Clay attempted to make an out of bounds array access. This is an internal error and is likely a bug."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Clay__Array_IncrementCapacityCheck(uint32_t length, uint32_t capacity)
|
||||
bool Clay__Array_AddCapacityCheck(uint32_t length, uint32_t capacity)
|
||||
{
|
||||
if (length < capacity) {
|
||||
return true;
|
||||
}
|
||||
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.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_INTERNAL_ERROR,
|
||||
.errorText = CLAY_STRING("Clay attempted to make an out of bounds array access. This is an internal error and is likely a bug."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -695,7 +702,7 @@ Clay_ElementId *Clay__ElementIdArray_Get(Clay__ElementIdArray *array, int index)
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__ELEMENT_ID_DEFAULT;
|
||||
}
|
||||
Clay_ElementId *Clay__ElementIdArray_Add(Clay__ElementIdArray *array, Clay_ElementId item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -726,7 +733,7 @@ Clay_ElementConfig *Clay__ElementConfigArray_Get(Clay__ElementConfigArray *array
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__ELEMENT_CONFIG_DEFAULT;
|
||||
}
|
||||
Clay_ElementConfig *Clay__ElementConfigArray_Add(Clay__ElementConfigArray *array, Clay_ElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -752,7 +759,7 @@ Clay__LayoutConfigArray Clay__LayoutConfigArray_Allocate_Arena(uint32_t capacity
|
||||
return CLAY__INIT(Clay__LayoutConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutConfig), CLAY__ALIGNMENT(Clay_LayoutConfig), arena)};
|
||||
}
|
||||
Clay_LayoutConfig *Clay__LayoutConfigArray_Add(Clay__LayoutConfigArray *array, Clay_LayoutConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -775,7 +782,7 @@ Clay__RectangleElementConfigArray Clay__RectangleElementConfigArray_Allocate_Are
|
||||
return CLAY__INIT(Clay__RectangleElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_RectangleElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_RectangleElementConfig), CLAY__ALIGNMENT(Clay_RectangleElementConfig), arena)};
|
||||
}
|
||||
Clay_RectangleElementConfig *Clay__RectangleElementConfigArray_Add(Clay__RectangleElementConfigArray *array, Clay_RectangleElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -798,7 +805,7 @@ Clay__TextElementConfigArray Clay__TextElementConfigArray_Allocate_Arena(uint32_
|
||||
return CLAY__INIT(Clay__TextElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_TextElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_TextElementConfig), CLAY__ALIGNMENT(Clay_TextElementConfig), arena)};
|
||||
}
|
||||
Clay_TextElementConfig *Clay__TextElementConfigArray_Add(Clay__TextElementConfigArray *array, Clay_TextElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -821,7 +828,7 @@ Clay__ImageElementConfigArray Clay__ImageElementConfigArray_Allocate_Arena(uint3
|
||||
return CLAY__INIT(Clay__ImageElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_ImageElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_ImageElementConfig), CLAY__ALIGNMENT(Clay_ImageElementConfig), arena)};
|
||||
}
|
||||
Clay_ImageElementConfig *Clay__ImageElementConfigArray_Add(Clay__ImageElementConfigArray *array, Clay_ImageElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -844,7 +851,7 @@ Clay__FloatingElementConfigArray Clay__FloatingElementConfigArray_Allocate_Arena
|
||||
return CLAY__INIT(Clay__FloatingElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_FloatingElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_FloatingElementConfig), CLAY__ALIGNMENT(Clay_FloatingElementConfig), arena)};
|
||||
}
|
||||
Clay_FloatingElementConfig *Clay__FloatingElementConfigArray_Add(Clay__FloatingElementConfigArray *array, Clay_FloatingElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -867,7 +874,7 @@ Clay__CustomElementConfigArray Clay__CustomElementConfigArray_Allocate_Arena(uin
|
||||
return CLAY__INIT(Clay__CustomElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_CustomElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_CustomElementConfig), CLAY__ALIGNMENT(Clay_CustomElementConfig), arena)};
|
||||
}
|
||||
Clay_CustomElementConfig *Clay__CustomElementConfigArray_Add(Clay__CustomElementConfigArray *array, Clay_CustomElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -890,7 +897,7 @@ Clay__ScrollElementConfigArray Clay__ScrollElementConfigArray_Allocate_Arena(uin
|
||||
return CLAY__INIT(Clay__ScrollElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_ScrollElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_ScrollElementConfig), CLAY__ALIGNMENT(Clay_ScrollElementConfig), arena)};
|
||||
}
|
||||
Clay_ScrollElementConfig *Clay__ScrollElementConfigArray_Add(Clay__ScrollElementConfigArray *array, Clay_ScrollElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -910,7 +917,7 @@ Clay__StringArray Clay__StringArray_Allocate_Arena(uint32_t capacity, Clay_Arena
|
||||
return CLAY__INIT(Clay__StringArray){.capacity = capacity, .length = 0, .internalArray = (Clay_String *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_String), CLAY__ALIGNMENT(Clay_String), arena)};
|
||||
}
|
||||
Clay_String *Clay__StringArray_Add(Clay__StringArray *array, Clay_String item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -944,7 +951,7 @@ Clay__TextElementData *Clay__TextElementDataArray_Get(Clay__TextElementDataArray
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__TEXT_ELEMENT_DATA_DEFAULT;
|
||||
}
|
||||
Clay__TextElementData *Clay__TextElementDataArray_Add(Clay__TextElementDataArray *array, Clay__TextElementData item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -967,7 +974,7 @@ Clay__BorderElementConfigArray Clay__BorderElementConfigArray_Allocate_Arena(uin
|
||||
return CLAY__INIT(Clay__BorderElementConfigArray){.capacity = capacity, .length = 0, .internalArray = (Clay_BorderElementConfig *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_BorderElementConfig), CLAY__ALIGNMENT(Clay_BorderElementConfig), arena)};
|
||||
}
|
||||
Clay_BorderElementConfig *Clay__BorderElementConfigArray_Add(Clay__BorderElementConfigArray *array, Clay_BorderElementConfig item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -984,9 +991,6 @@ typedef struct
|
||||
|
||||
typedef struct Clay_LayoutElement
|
||||
{
|
||||
#ifdef CLAY_DEBUG
|
||||
Clay_String name;
|
||||
#endif
|
||||
union {
|
||||
Clay__LayoutElementChildren children;
|
||||
Clay__TextElementData *textElementData;
|
||||
@ -1013,7 +1017,7 @@ Clay_LayoutElementArray Clay_LayoutElementArray_Allocate_Arena(uint32_t capacity
|
||||
return CLAY__INIT(Clay_LayoutElementArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutElement *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutElement), CLAY__ALIGNMENT(Clay_LayoutElement), arena)};
|
||||
}
|
||||
Clay_LayoutElement *Clay_LayoutElementArray_Add(Clay_LayoutElementArray *array, Clay_LayoutElement item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1037,7 +1041,7 @@ Clay__LayoutElementPointerArray Clay__LayoutElementPointerArray_Allocate_Arena(u
|
||||
return CLAY__INIT(Clay__LayoutElementPointerArray){.capacity = capacity, .length = 0, .internalArray = (Clay_LayoutElement* *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_LayoutElement*), CLAY__ALIGNMENT(Clay_LayoutElement*), arena)};
|
||||
}
|
||||
Clay_LayoutElement* *Clay__LayoutElementPointerArray_Add(Clay__LayoutElementPointerArray *array, Clay_LayoutElement* item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1066,13 +1070,13 @@ Clay_RenderCommandArray Clay_RenderCommandArray_Allocate_Arena(uint32_t capacity
|
||||
return CLAY__INIT(Clay_RenderCommandArray){.capacity = capacity, .length = 0, .internalArray = (Clay_RenderCommand *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay_RenderCommand), CLAY__ALIGNMENT(Clay_RenderCommand), arena)};
|
||||
}
|
||||
Clay_RenderCommand *Clay_RenderCommandArray_Add(Clay_RenderCommandArray *array, Clay_RenderCommand item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
return &CLAY__RENDER_COMMAND_DEFAULT;
|
||||
}
|
||||
Clay_RenderCommand *Clay_RenderCommandArray_Get(Clay_RenderCommandArray *array, int32_t index) {
|
||||
Clay_RenderCommand *Clay_RenderCommandArray_Get(Clay_RenderCommandArray *array, int index) {
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__RENDER_COMMAND_DEFAULT;
|
||||
}
|
||||
#pragma endregion
|
||||
@ -1087,7 +1091,7 @@ Clay__ScrollContainerDataInternalArray Clay__ScrollContainerDataInternalArray_Al
|
||||
return CLAY__INIT(Clay__ScrollContainerDataInternalArray){.capacity = capacity, .length = 0, .internalArray = (Clay__ScrollContainerDataInternal *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__ScrollContainerDataInternal), CLAY__ALIGNMENT(Clay__ScrollContainerDataInternal), arena)};
|
||||
}
|
||||
Clay__ScrollContainerDataInternal *Clay__ScrollContainerDataInternalArray_Add(Clay__ScrollContainerDataInternalArray *array, Clay__ScrollContainerDataInternal item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1133,7 +1137,7 @@ Clay__DebugElementDataArray Clay__DebugElementDataArray_Allocate_Arena(uint32_t
|
||||
return CLAY__INIT(Clay__DebugElementDataArray){.capacity = capacity, .length = 0, .internalArray = (Clay__DebugElementData *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__DebugElementData), CLAY__ALIGNMENT(Clay__DebugElementData), arena)};
|
||||
}
|
||||
Clay__DebugElementData *Clay__DebugElementDataArray_Add(Clay__DebugElementDataArray *array, Clay__DebugElementData item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1174,7 +1178,7 @@ Clay_LayoutElementHashMapItem *Clay__LayoutElementHashMapItemArray_Get(Clay__Lay
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT;
|
||||
}
|
||||
Clay_LayoutElementHashMapItem *Clay__LayoutElementHashMapItemArray_Add(Clay__LayoutElementHashMapItemArray *array, Clay_LayoutElementHashMapItem item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1208,20 +1212,13 @@ Clay__MeasuredWord *Clay__MeasuredWordArray_Get(Clay__MeasuredWordArray *array,
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__MEASURED_WORD_DEFAULT;
|
||||
}
|
||||
void Clay__MeasuredWordArray_Set(Clay__MeasuredWordArray *array, int index, Clay__MeasuredWord value) {
|
||||
if (index < array->capacity && index >= 0) {
|
||||
if (Clay__Array_RangeCheck(index, array->capacity)) {
|
||||
array->internalArray[index] = value;
|
||||
array->length = index < array->length ? array->length : index + 1;
|
||||
} else {
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to allocate array in arena, but arena is already at capacity and would overflow.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Clay__MeasuredWord *Clay__MeasuredWordArray_Add(Clay__MeasuredWordArray *array, Clay__MeasuredWord item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1257,23 +1254,16 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCacheItemArray_Get(Clay__MeasureTex
|
||||
return Clay__Array_RangeCheck(index, array->length) ? &array->internalArray[index] : &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||
}
|
||||
Clay__MeasureTextCacheItem *Clay__MeasureTextCacheItemArray_Add(Clay__MeasureTextCacheItemArray *array, Clay__MeasureTextCacheItem item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||
}
|
||||
void Clay__MeasureTextCacheItemArray_Set(Clay__MeasureTextCacheItemArray *array, int index, Clay__MeasureTextCacheItem value) {
|
||||
if (index < array->capacity && index >= 0) {
|
||||
if (Clay__Array_RangeCheck(index, array->capacity)) {
|
||||
array->internalArray[index] = value;
|
||||
array->length = index < array->length ? array->length : index + 1;
|
||||
} else {
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to allocate array in arena, but arena is already at capacity and would overflow.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
@ -1294,21 +1284,14 @@ int32_t Clay__int32_tArray_Get(Clay__int32_tArray *array, int index) {
|
||||
return Clay__Array_RangeCheck(index, array->length) ? array->internalArray[index] : -1;
|
||||
}
|
||||
void Clay__int32_tArray_Add(Clay__int32_tArray *array, int32_t item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
}
|
||||
}
|
||||
void Clay__int32_tArray_Set(Clay__int32_tArray *array, int index, int32_t value) {
|
||||
if (index < array->capacity && index >= 0) {
|
||||
if (Clay__Array_RangeCheck(index, array->capacity)) {
|
||||
array->internalArray[index] = value;
|
||||
array->length = index < array->length ? array->length : index + 1;
|
||||
} else {
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to allocate array in arena, but arena is already at capacity and would overflow.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
int32_t Clay__int32_tArray_RemoveSwapback(Clay__int32_tArray *array, int index) {
|
||||
@ -1344,7 +1327,7 @@ Clay__LayoutElementTreeNodeArray Clay__LayoutElementTreeNodeArray_Allocate_Arena
|
||||
return CLAY__INIT(Clay__LayoutElementTreeNodeArray){.capacity = capacity, .length = 0, .internalArray = (Clay__LayoutElementTreeNode *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__LayoutElementTreeNode), CLAY__ALIGNMENT(Clay__LayoutElementTreeNode), arena)};
|
||||
}
|
||||
Clay__LayoutElementTreeNode *Clay__LayoutElementTreeNodeArray_Add(Clay__LayoutElementTreeNodeArray *array, Clay__LayoutElementTreeNode item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1379,7 +1362,7 @@ Clay__LayoutElementTreeRootArray Clay__LayoutElementTreeRootArray_Allocate_Arena
|
||||
return CLAY__INIT(Clay__LayoutElementTreeRootArray){.capacity = capacity, .length = 0, .internalArray = (Clay__LayoutElementTreeRoot *)Clay__Array_Allocate_Arena(capacity, sizeof(Clay__LayoutElementTreeRoot), CLAY__ALIGNMENT(Clay__LayoutElementTreeRoot), arena)};
|
||||
}
|
||||
Clay__LayoutElementTreeRoot *Clay__LayoutElementTreeRootArray_Add(Clay__LayoutElementTreeRootArray *array, Clay__LayoutElementTreeRoot item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
@ -1424,7 +1407,6 @@ bool Clay__externalScrollHandlingEnabled = false;
|
||||
uint32_t Clay__debugSelectedElementId = 0;
|
||||
uint32_t Clay__debugViewWidth = 400;
|
||||
Clay_Color Clay__debugViewHighlightColor = CLAY__INIT(Clay_Color) { 168, 66, 28, 100 };
|
||||
bool Clay__debugMaxElementsLatch = false;
|
||||
uint32_t Clay__generation = 0;
|
||||
uint64_t Clay__arenaResetOffset = 0;
|
||||
Clay_Arena Clay__internalArena;
|
||||
@ -1604,8 +1586,17 @@ Clay__MeasuredWord *Clay__AddMeasuredWord(Clay__MeasuredWord word, Clay__Measure
|
||||
}
|
||||
|
||||
Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_TextElementConfig *config) {
|
||||
#ifndef CLAY_WASM
|
||||
if (!Clay__MeasureText) {
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_TEXT_MEASUREMENT_FUNCTION_NOT_PROVIDED,
|
||||
.errorText = CLAY_STRING("Clay's internal MeasureText function is null. You may have forgotten to call Clay_SetMeasureTextFunction(), or passed a NULL function pointer by mistake."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
uint32_t id = Clay__HashTextWithConfig(text, config);
|
||||
uint32_t hashBucket = id % CLAY__TEXT_MEASURE_HASH_BUCKET_COUNT;
|
||||
uint32_t hashBucket = id % (Clay__maxMeasureTextCacheWordCount / 32);
|
||||
int32_t elementIndexPrevious = 0;
|
||||
int32_t elementIndex = Clay__measureTextHashMap.internalArray[hashBucket];
|
||||
while (elementIndex != 0) {
|
||||
@ -1650,6 +1641,13 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
measured = Clay__MeasureTextCacheItemArray_Get(&Clay__measureTextHashMapInternal, newItemIndex);
|
||||
} else {
|
||||
if (Clay__measureTextHashMapInternal.length == Clay__measureTextHashMapInternal.capacity - 1) {
|
||||
if (Clay__booleanWarnings.maxTextMeasureCacheExceeded) {
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
|
||||
.errorText = CLAY_STRING("Clay ran out of capacity while attempting to measure text elements. Try using Clay_SetMaxElementCount() with a higher value."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
Clay__booleanWarnings.maxTextMeasureCacheExceeded = true;
|
||||
}
|
||||
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||
}
|
||||
measured = Clay__MeasureTextCacheItemArray_Add(&Clay__measureTextHashMapInternal, newCacheItem);
|
||||
@ -1665,6 +1663,13 @@ Clay__MeasureTextCacheItem *Clay__MeasureTextCached(Clay_String *text, Clay_Text
|
||||
Clay__MeasuredWord *previousWord = &tempWord;
|
||||
while (end < text->length) {
|
||||
if (Clay__measuredWords.length == Clay__measuredWords.capacity - 1) {
|
||||
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 using Clay_SetMaxMeasureTextCacheWordCount() (default 16384, with 1 unit storing 1 measured word)."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
Clay__booleanWarnings.maxTextMeasureCacheExceeded = true;
|
||||
}
|
||||
return &CLAY__MEASURE_TEXT_CACHE_ITEM_DEFAULT;
|
||||
}
|
||||
char current = text->chars[end];
|
||||
@ -1728,9 +1733,10 @@ Clay_LayoutElementHashMapItem* Clay__AddHashMapItem(Clay_ElementId elementId, Cl
|
||||
hashItem->layoutElement = layoutElement;
|
||||
hashItem->debugData->collision = false;
|
||||
} else { // Multiple collisions this frame - two elements have the same ID
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Duplicate ID detected for element: "), Clay__WriteStringToCharBuffer(&Clay__dynamicStringData, elementId.stringId) });
|
||||
}
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_DUPLICATE_ID,
|
||||
.errorText = CLAY_STRING("An element with this ID was already previously declared during this layout."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
if (Clay__debugModeEnabled) {
|
||||
hashItem->debugData->collision = true;
|
||||
}
|
||||
@ -1769,13 +1775,10 @@ void Clay__GenerateIdForAnonymousElement(Clay_LayoutElement *openLayoutElement)
|
||||
openLayoutElement->id = elementId.id;
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement);
|
||||
Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
|
||||
#ifdef CLAY_DEBUG
|
||||
openLayoutElement->name = elementId.stringId;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Clay__ElementPostConfiguration() {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
@ -1817,7 +1820,10 @@ void Clay__ElementPostConfiguration() {
|
||||
Clay_LayoutElementHashMapItem *parentItem = Clay__GetHashMapItem(floatingConfig->parentId);
|
||||
clipElementId = Clay__int32_tArray_Get(&Clay__layoutElementClipElementIds, parentItem->layoutElement - Clay__layoutElements.internalArray);
|
||||
if (!parentItem) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Clay Warning: Couldn't find parent container to attach floating container to.") });
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_FLOATING_CONTAINER_PARENT_NOT_FOUND,
|
||||
.errorText = CLAY_STRING("A floating element was declared with a parentId, but no element with that ID was found."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
}
|
||||
}
|
||||
Clay__LayoutElementTreeRootArray_Add(&Clay__layoutElementTreeRoots, CLAY__INIT(Clay__LayoutElementTreeRoot) {
|
||||
@ -1860,7 +1866,7 @@ void Clay__ElementPostConfiguration() {
|
||||
}
|
||||
|
||||
void Clay__CloseElement() {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
@ -1954,8 +1960,8 @@ void Clay__CloseElement() {
|
||||
}
|
||||
|
||||
void Clay__OpenElement() {
|
||||
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__debugMaxElementsLatch) {
|
||||
Clay__debugMaxElementsLatch = true;
|
||||
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__booleanWarnings.maxElementsExceeded) {
|
||||
Clay__booleanWarnings.maxElementsExceeded = true;
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement layoutElement = CLAY__INIT(Clay_LayoutElement) {};
|
||||
@ -1969,8 +1975,8 @@ void Clay__OpenElement() {
|
||||
}
|
||||
|
||||
void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig) {
|
||||
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__debugMaxElementsLatch) {
|
||||
Clay__debugMaxElementsLatch = true;
|
||||
if (Clay__layoutElements.length == Clay__layoutElements.capacity - 1 || Clay__booleanWarnings.maxElementsExceeded) {
|
||||
Clay__booleanWarnings.maxElementsExceeded = true;
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement *parentElement = Clay__GetOpenLayoutElement();
|
||||
@ -1982,9 +1988,6 @@ void Clay__OpenTextElement(Clay_String text, Clay_TextElementConfig *textConfig)
|
||||
Clay__MeasureTextCacheItem *textMeasured = Clay__MeasureTextCached(&text, textConfig);
|
||||
Clay_ElementId elementId = Clay__HashString(CLAY_STRING("Text"), parentElement->children.length, parentElement->id);
|
||||
openLayoutElement->id = elementId.id;
|
||||
#ifdef CLAY_DEBUG
|
||||
openLayoutElement->name = CLAY_STRING("Text");
|
||||
#endif
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement);
|
||||
Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
|
||||
Clay_Dimensions textDimensions = CLAY__INIT(Clay_Dimensions) { .width = textMeasured->unwrappedDimensions.width, .height = textConfig->lineHeight > 0 ? textConfig->lineHeight : textMeasured->unwrappedDimensions.height };
|
||||
@ -2005,50 +2008,50 @@ void Clay__InitializeEphemeralMemory(Clay_Arena *arena) {
|
||||
// Ephemeral Memory - reset every frame
|
||||
Clay__internalArena.nextAllocation = Clay__arenaResetOffset;
|
||||
|
||||
Clay__layoutElementChildrenBuffer = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElements = Clay_LayoutElementArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementChildrenBuffer = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__layoutElements = Clay_LayoutElementArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay_warnings = Clay__WarningArray_Allocate_Arena(100, arena);
|
||||
|
||||
Clay__layoutConfigs = Clay__LayoutConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__elementConfigBuffer = Clay__ElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__elementConfigs = Clay__ElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__rectangleElementConfigs = Clay__RectangleElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__textElementConfigs = Clay__TextElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__imageElementConfigs = Clay__ImageElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__floatingElementConfigs = Clay__FloatingElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__scrollElementConfigs = Clay__ScrollElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__customElementConfigs = Clay__CustomElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__borderElementConfigs = Clay__BorderElementConfigArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutConfigs = Clay__LayoutConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__elementConfigBuffer = Clay__ElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__elementConfigs = Clay__ElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__rectangleElementConfigs = Clay__RectangleElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__textElementConfigs = Clay__TextElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__imageElementConfigs = Clay__ImageElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__floatingElementConfigs = Clay__FloatingElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__scrollElementConfigs = Clay__ScrollElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__customElementConfigs = Clay__CustomElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__borderElementConfigs = Clay__BorderElementConfigArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
|
||||
Clay__layoutElementIdStrings = Clay__StringArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__wrappedTextLines = Clay__StringArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementTreeNodeArray1 = Clay__LayoutElementTreeNodeArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementTreeRoots = Clay__LayoutElementTreeRootArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementChildren = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__openLayoutElementStack = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__textElementData = Clay__TextElementDataArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__imageElementPointers = Clay__LayoutElementPointerArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__renderCommands = Clay_RenderCommandArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__treeNodeVisited = Clay__BoolArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementIdStrings = Clay__StringArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__wrappedTextLines = Clay__StringArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__layoutElementTreeNodeArray1 = Clay__LayoutElementTreeNodeArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__layoutElementTreeRoots = Clay__LayoutElementTreeRootArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__layoutElementChildren = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__openLayoutElementStack = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__textElementData = Clay__TextElementDataArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__imageElementPointers = Clay__LayoutElementPointerArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__renderCommands = Clay_RenderCommandArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__treeNodeVisited = Clay__BoolArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__treeNodeVisited.length = Clay__treeNodeVisited.capacity; // This array is accessed directly rather than behaving as a list
|
||||
Clay__openClipElementStack = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__reusableElementIndexBuffer = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementClipElementIds = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__dynamicStringData = Clay__CharArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__openClipElementStack = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__reusableElementIndexBuffer = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__layoutElementClipElementIds = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__dynamicStringData = Clay__CharArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
}
|
||||
|
||||
void Clay__InitializePersistentMemory(Clay_Arena *arena) {
|
||||
// Persistent memory - initialized once and not reset
|
||||
Clay__scrollContainerDatas = Clay__ScrollContainerDataInternalArray_Allocate_Arena(10, arena);
|
||||
Clay__layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementsHashMap = Clay__int32_tArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__measureTextHashMapInternal = Clay__MeasureTextCacheItemArray_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_MEASURE_TEXT_CACHE_SIZE, arena);
|
||||
Clay__measureTextHashMap = Clay__int32_tArray_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__debugElementData = Clay__DebugElementDataArray_Allocate_Arena(CLAY_MAX_ELEMENT_COUNT, arena);
|
||||
Clay__layoutElementsHashMapInternal = Clay__LayoutElementHashMapItemArray_Allocate_Arena(Clay__maxElementCount, 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__maxMeasureTextCacheWordCount, arena);
|
||||
Clay__measureTextHashMap = Clay__int32_tArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__measuredWords = Clay__MeasuredWordArray_Allocate_Arena(Clay__maxMeasureTextCacheWordCount, arena);
|
||||
Clay__pointerOverIds = Clay__ElementIdArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__debugElementData = Clay__DebugElementDataArray_Allocate_Arena(Clay__maxElementCount, arena);
|
||||
Clay__arenaResetOffset = arena->nextAllocation;
|
||||
}
|
||||
|
||||
@ -2312,7 +2315,13 @@ void Clay__AddRenderCommand(Clay_RenderCommand renderCommand) {
|
||||
if (Clay__renderCommands.length < Clay__renderCommands.capacity - 1) {
|
||||
Clay_RenderCommandArray_Add(&Clay__renderCommands, renderCommand);
|
||||
} else {
|
||||
Clay__booleanWarnings.maxRenderCommandsExceeded = true;
|
||||
if (!Clay__booleanWarnings.maxRenderCommandsExceeded) {
|
||||
Clay__booleanWarnings.maxRenderCommandsExceeded = true;
|
||||
Clay__errorHandler.errorHandlerFunction(CLAY__INIT(Clay_ErrorData) {
|
||||
.errorType = CLAY_ERROR_TYPE_ELEMENTS_CAPACITY_EXCEEDED,
|
||||
.errorText = CLAY_STRING("Clay ran out of capacity while attempting to create render commands. This is usually caused by a large amount of wrapping text elements while close to the max element capacity. Try using Clay_SetMaxElementCount() with a higher value."),
|
||||
.userData = Clay__errorHandler.userData });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2350,7 +2359,6 @@ void Clay__CalculateFinalLayout() {
|
||||
int32_t wordIndex = measureTextCacheItem->measuredWordsStartIndex;
|
||||
while (wordIndex != -1) {
|
||||
if (Clay__wrappedTextLines.length > Clay__wrappedTextLines.capacity - 1) {
|
||||
Clay__booleanWarnings.maxStringMeasureCacheExceeded = true;
|
||||
break;
|
||||
}
|
||||
Clay__MeasuredWord *measuredWord = Clay__MeasuredWordArray_Get(&Clay__measuredWords, wordIndex);
|
||||
@ -2863,40 +2871,37 @@ void Clay__CalculateFinalLayout() {
|
||||
}
|
||||
|
||||
void Clay__AttachId(Clay_ElementId elementId) {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
openLayoutElement->id = elementId.id;
|
||||
Clay__AddHashMapItem(elementId, openLayoutElement);
|
||||
Clay__StringArray_Add(&Clay__layoutElementIdStrings, elementId.stringId);
|
||||
#ifdef CLAY_DEBUG
|
||||
openLayoutElement->name = elementId.stringId;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Clay__AttachLayoutConfig(Clay_LayoutConfig *config) {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay__GetOpenLayoutElement()->layoutConfig = config;
|
||||
}
|
||||
void Clay__AttachElementConfig(Clay_ElementConfigUnion config, Clay__ElementConfigType type) {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
openLayoutElement->elementConfigs.length++;
|
||||
Clay__ElementConfigArray_Add(&Clay__elementConfigBuffer, CLAY__INIT(Clay_ElementConfig) { .type = type, .config = config });
|
||||
}
|
||||
Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config) { return Clay__debugMaxElementsLatch ? &CLAY_LAYOUT_DEFAULT : Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config); }
|
||||
Clay_RectangleElementConfig * Clay__StoreRectangleElementConfig(Clay_RectangleElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__RECTANGLE_ELEMENT_CONFIG_DEFAULT : Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config); }
|
||||
Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__TEXT_ELEMENT_CONFIG_DEFAULT : Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config); }
|
||||
Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__IMAGE_ELEMENT_CONFIG_DEFAULT : Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config); }
|
||||
Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_FloatingElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__FLOATING_ELEMENT_CONFIG_DEFAULT : Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config); }
|
||||
Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__CUSTOM_ELEMENT_CONFIG_DEFAULT : Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config); }
|
||||
Clay_ScrollElementConfig * Clay__StoreScrollElementConfig(Clay_ScrollElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__SCROLL_ELEMENT_CONFIG_DEFAULT : Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config); }
|
||||
Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config) { return Clay__debugMaxElementsLatch ? &CLAY__BORDER_ELEMENT_CONFIG_DEFAULT : Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config); }
|
||||
Clay_LayoutConfig * Clay__StoreLayoutConfig(Clay_LayoutConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY_LAYOUT_DEFAULT : Clay__LayoutConfigArray_Add(&Clay__layoutConfigs, config); }
|
||||
Clay_RectangleElementConfig * Clay__StoreRectangleElementConfig(Clay_RectangleElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__RECTANGLE_ELEMENT_CONFIG_DEFAULT : Clay__RectangleElementConfigArray_Add(&Clay__rectangleElementConfigs, config); }
|
||||
Clay_TextElementConfig * Clay__StoreTextElementConfig(Clay_TextElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__TEXT_ELEMENT_CONFIG_DEFAULT : Clay__TextElementConfigArray_Add(&Clay__textElementConfigs, config); }
|
||||
Clay_ImageElementConfig * Clay__StoreImageElementConfig(Clay_ImageElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__IMAGE_ELEMENT_CONFIG_DEFAULT : Clay__ImageElementConfigArray_Add(&Clay__imageElementConfigs, config); }
|
||||
Clay_FloatingElementConfig * Clay__StoreFloatingElementConfig(Clay_FloatingElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__FLOATING_ELEMENT_CONFIG_DEFAULT : Clay__FloatingElementConfigArray_Add(&Clay__floatingElementConfigs, config); }
|
||||
Clay_CustomElementConfig * Clay__StoreCustomElementConfig(Clay_CustomElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__CUSTOM_ELEMENT_CONFIG_DEFAULT : Clay__CustomElementConfigArray_Add(&Clay__customElementConfigs, config); }
|
||||
Clay_ScrollElementConfig * Clay__StoreScrollElementConfig(Clay_ScrollElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__SCROLL_ELEMENT_CONFIG_DEFAULT : Clay__ScrollElementConfigArray_Add(&Clay__scrollElementConfigs, config); }
|
||||
Clay_BorderElementConfig * Clay__StoreBorderElementConfig(Clay_BorderElementConfig config) { return Clay__booleanWarnings.maxElementsExceeded ? &CLAY__BORDER_ELEMENT_CONFIG_DEFAULT : Clay__BorderElementConfigArray_Add(&Clay__borderElementConfigs, config); }
|
||||
|
||||
#pragma region DebugTools
|
||||
Clay_Color CLAY__DEBUGVIEW_COLOR_1 = CLAY__INIT(Clay_Color) {58, 56, 52, 255};
|
||||
@ -3192,7 +3197,9 @@ void Clay__RenderDebugView() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int32_t highlightedRow = (int32_t)((Clay__pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1;
|
||||
int32_t highlightedRow = Clay__pointerInfo.position.y < Clay__layoutDimensions.height - 300
|
||||
? (int32_t)((Clay__pointerInfo.position.y - scrollYOffset) / (float)CLAY__DEBUGVIEW_ROW_HEIGHT) - 1
|
||||
: -1;
|
||||
if (Clay__pointerInfo.position.x < Clay__layoutDimensions.width - (float)Clay__debugViewWidth) {
|
||||
highlightedRow = -1;
|
||||
}
|
||||
@ -3488,7 +3495,7 @@ void Clay__RenderDebugView() {
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_MinMemorySize")
|
||||
uint32_t Clay_MinMemorySize() {
|
||||
Clay_Arena fakeArena = CLAY__INIT(Clay_Arena) { .capacity = INT64_MAX };
|
||||
Clay_Arena fakeArena = CLAY__INIT(Clay_Arena) { .capacity = SIZE_MAX };
|
||||
Clay__InitializePersistentMemory(&fakeArena);
|
||||
Clay__InitializeEphemeralMemory(&fakeArena);
|
||||
return fakeArena.nextAllocation;
|
||||
@ -3507,9 +3514,6 @@ Clay_Arena Clay_CreateArenaWithCapacityAndMemory(uint32_t capacity, void *offset
|
||||
void Clay_SetMeasureTextFunction(Clay_Dimensions (*measureTextFunction)(Clay_String *text, Clay_TextElementConfig *config)) {
|
||||
Clay__MeasureText = measureTextFunction;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CLAY_WASM
|
||||
void Clay_SetQueryScrollOffsetFunction(Clay_Vector2 (*queryScrollOffsetFunction)(uint32_t elementId)) {
|
||||
Clay__QueryScrollOffset = queryScrollOffsetFunction;
|
||||
}
|
||||
@ -3522,7 +3526,7 @@ void Clay_SetLayoutDimensions(Clay_Dimensions dimensions) {
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_SetPointerState")
|
||||
void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay__pointerInfo.position = position;
|
||||
@ -3589,7 +3593,7 @@ void Clay_SetPointerState(Clay_Vector2 position, bool isPointerDown) {
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_Initialize")
|
||||
void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions) {
|
||||
void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions, Clay_ErrorHandler errorHandler) {
|
||||
Clay__internalArena = arena;
|
||||
Clay__InitializePersistentMemory(&Clay__internalArena);
|
||||
Clay__InitializeEphemeralMemory(&Clay__internalArena);
|
||||
@ -3601,6 +3605,7 @@ void Clay_Initialize(Clay_Arena arena, Clay_Dimensions layoutDimensions) {
|
||||
}
|
||||
Clay__measureTextHashMapInternal.length = 1; // Reserve the 0 value to mean "no next element"
|
||||
Clay__layoutDimensions = layoutDimensions;
|
||||
Clay__errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_UpdateScrollContainers")
|
||||
@ -3726,9 +3731,9 @@ void Clay_BeginLayout() {
|
||||
if (Clay__debugModeEnabled) {
|
||||
rootDimensions.width -= (float)Clay__debugViewWidth;
|
||||
}
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
return;
|
||||
}
|
||||
Clay__booleanWarnings.maxElementsExceeded = false;
|
||||
Clay__booleanWarnings.maxTextMeasureCacheExceeded = false;
|
||||
Clay__booleanWarnings.maxRenderCommandsExceeded = false;
|
||||
Clay__OpenElement();
|
||||
CLAY_ID("Clay__RootContainer");
|
||||
CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED((rootDimensions.width)), CLAY_SIZING_FIXED(rootDimensions.height)} });
|
||||
@ -3744,16 +3749,12 @@ Clay_RenderCommandArray Clay_EndLayout()
|
||||
{
|
||||
Clay__CloseElement();
|
||||
if (Clay__debugModeEnabled) {
|
||||
#ifndef CLAY_DEBUG
|
||||
Clay__warningsEnabled = false;
|
||||
#endif
|
||||
Clay__RenderDebugView();
|
||||
#ifndef CLAY_DEBUG
|
||||
Clay__warningsEnabled = true;
|
||||
#endif
|
||||
}
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand ) { .boundingBox = { Clay__layoutDimensions.width / 2 - 59 * 4, Clay__layoutDimensions.height / 2 }, .config = { .textElementConfig = &Clay__DebugView_ErrorTextConfig }, .text = CLAY_STRING("Clay Error: Layout elements exceeded CLAY_MAX_ELEMENT_COUNT"), .commandType = CLAY_RENDER_COMMAND_TYPE_TEXT });
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
Clay__AddRenderCommand(CLAY__INIT(Clay_RenderCommand ) { .boundingBox = { Clay__layoutDimensions.width / 2 - 59 * 4, Clay__layoutDimensions.height / 2 }, .config = { .textElementConfig = &Clay__DebugView_ErrorTextConfig }, .text = CLAY_STRING("Clay Error: Layout elements exceeded Clay__maxElementCount"), .commandType = CLAY_RENDER_COMMAND_TYPE_TEXT });
|
||||
} else {
|
||||
Clay__CalculateFinalLayout();
|
||||
}
|
||||
@ -3771,7 +3772,7 @@ Clay_ElementId Clay_GetElementIdWithIndex(Clay_String idString, uint32_t index)
|
||||
}
|
||||
|
||||
bool Clay_Hovered() {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return false;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
@ -3788,7 +3789,7 @@ bool Clay_Hovered() {
|
||||
}
|
||||
|
||||
void Clay_OnHover(void (*onHoverFunction)(Clay_ElementId elementId, Clay_PointerData pointerInfo, intptr_t userData), intptr_t userData) {
|
||||
if (Clay__debugMaxElementsLatch) {
|
||||
if (Clay__booleanWarnings.maxElementsExceeded) {
|
||||
return;
|
||||
}
|
||||
Clay_LayoutElement *openLayoutElement = Clay__GetOpenLayoutElement();
|
||||
@ -3827,6 +3828,22 @@ Clay_ScrollContainerData Clay_GetScrollContainerData(Clay_ElementId id) {
|
||||
return CLAY__INIT(Clay_ScrollContainerData) {};
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_GetElementLocationData")
|
||||
Clay_ElementLocationData Clay_GetElementLocationData(Clay_ElementId id){
|
||||
Clay_LayoutElementHashMapItem * item =Clay__GetHashMapItem(id.id);
|
||||
if(item == &CLAY__LAYOUT_ELEMENT_HASH_MAP_ITEM_DEFAULT) {
|
||||
return CLAY__INIT(Clay_ElementLocationData){
|
||||
.found=false,
|
||||
.elementLocation=CLAY__INIT(Clay_BoundingBox){}
|
||||
};
|
||||
}
|
||||
|
||||
return CLAY__INIT(Clay_ElementLocationData){
|
||||
.elementLocation=item->boundingBox,
|
||||
.found = true
|
||||
};
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_SetDebugModeEnabled")
|
||||
void Clay_SetDebugModeEnabled(bool enabled) {
|
||||
Clay__debugModeEnabled = enabled;
|
||||
@ -3842,6 +3859,16 @@ void Clay_SetExternalScrollHandlingEnabled(bool enabled) {
|
||||
Clay__externalScrollHandlingEnabled = enabled;
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_SetMaxElementCount")
|
||||
void Clay_SetMaxElementCount(uint32_t maxElementCount) {
|
||||
Clay__maxElementCount = maxElementCount;
|
||||
}
|
||||
|
||||
CLAY_WASM_EXPORT("Clay_SetMaxMeasureTextCacheWordCount")
|
||||
void Clay_SetMaxMeasureTextCacheWordCount(uint32_t maxMeasureTextCacheWordCount) {
|
||||
Clay__maxMeasureTextCacheWordCount = maxMeasureTextCacheWordCount;
|
||||
}
|
||||
|
||||
#endif //CLAY_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
|
@ -109,6 +109,10 @@ void Layout() {
|
||||
}
|
||||
}
|
||||
|
||||
void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
printf("%s", errorData.errorText.chars);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// First we set up our cairo surface.
|
||||
// In this example we will use the PDF backend,
|
||||
@ -131,11 +135,11 @@ int main(void) {
|
||||
Clay_Cairo_Initialize(cr);
|
||||
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = (Clay_Arena) { .label = CLAY_STRING("Clay Memory Arena"), .memory = malloc(totalMemorySize), .capacity = totalMemorySize };
|
||||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
|
||||
Clay_SetMeasureTextFunction(Clay_Cairo_MeasureText);
|
||||
|
||||
// We initialize Clay with the same size
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { width, height });
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { width, height }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
|
||||
Clay_BeginLayout();
|
||||
|
||||
|
@ -311,23 +311,26 @@
|
||||
});
|
||||
|
||||
const importObject = {
|
||||
clay: { measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig) => {
|
||||
let stringLength = memoryDataView.getUint32(textToMeasure, true);
|
||||
let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true);
|
||||
let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition);
|
||||
let textDecoder = new TextDecoder("utf-8");
|
||||
let text = textDecoder.decode(memoryDataView.buffer.slice(pointerToString, pointerToString + stringLength));
|
||||
let sourceDimensions = getTextDimensions(text, `${Math.round(textConfig.fontSize.value * GLOBAL_FONT_SCALING_FACTOR)}px ${fontsById[textConfig.fontId.value]}`);
|
||||
memoryDataView.setFloat32(addressOfDimensions, sourceDimensions.width, true);
|
||||
memoryDataView.setFloat32(addressOfDimensions + 4, sourceDimensions.height, true);
|
||||
},
|
||||
queryScrollOffsetFunction: (addressOfOffset, elementId) => {
|
||||
let container = document.getElementById(elementId.toString());
|
||||
if (container) {
|
||||
memoryDataView.setFloat32(addressOfOffset, -container.scrollLeft, true);
|
||||
memoryDataView.setFloat32(addressOfOffset + 4, -container.scrollTop, true);
|
||||
clay: {
|
||||
|
||||
measureTextFunction: (addressOfDimensions, textToMeasure, addressOfConfig) => {
|
||||
let stringLength = memoryDataView.getUint32(textToMeasure, true);
|
||||
let pointerToString = memoryDataView.getUint32(textToMeasure + 4, true);
|
||||
let textConfig = readStructAtAddress(addressOfConfig, textConfigDefinition);
|
||||
let textDecoder = new TextDecoder("utf-8");
|
||||
let text = textDecoder.decode(memoryDataView.buffer.slice(pointerToString, pointerToString + stringLength));
|
||||
let sourceDimensions = getTextDimensions(text, `${Math.round(textConfig.fontSize.value * GLOBAL_FONT_SCALING_FACTOR)}px ${fontsById[textConfig.fontId.value]}`);
|
||||
memoryDataView.setFloat32(addressOfDimensions, sourceDimensions.width, true);
|
||||
memoryDataView.setFloat32(addressOfDimensions + 4, sourceDimensions.height, true);
|
||||
},
|
||||
queryScrollOffsetFunction: (addressOfOffset, elementId) => {
|
||||
let container = document.getElementById(elementId.toString());
|
||||
if (container) {
|
||||
memoryDataView.setFloat32(addressOfOffset, -container.scrollLeft, true);
|
||||
memoryDataView.setFloat32(addressOfOffset + 4, -container.scrollTop, true);
|
||||
}
|
||||
}
|
||||
}},
|
||||
},
|
||||
};
|
||||
const { instance } = await WebAssembly.instantiateStreaming(
|
||||
fetch("/clay/index.wasm"), importObject
|
||||
|
@ -4,10 +4,14 @@
|
||||
|
||||
Clay_LayoutConfig layoutElement = Clay_LayoutConfig { .padding = {5} };
|
||||
|
||||
void HandleClayErrors(Clay_ErrorData errorData) {
|
||||
printf("%s", errorData.errorText.chars);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = Clay_Arena { .label = CLAY_STRING("Clay Memory Arena"), .capacity = totalMemorySize, .memory = (char *)malloc(totalMemorySize) };
|
||||
Clay_Initialize(clayMemory, Clay_Dimensions {1024,768});
|
||||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, (char *)malloc(totalMemorySize));
|
||||
Clay_Initialize(clayMemory, Clay_Dimensions {1024,768}, Clay_ErrorHandler { HandleClayErrors });
|
||||
Clay_BeginLayout();
|
||||
CLAY(CLAY_RECTANGLE({ .color = {255,255,255,0} }), CLAY_LAYOUT(layoutElement)) {}
|
||||
Clay_EndLayout();
|
||||
|
@ -202,11 +202,24 @@ 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_SetMaxMeasureTextCacheWordCount(Clay__maxMeasureTextCacheWordCount * 2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||
Clay_Arena clayMemory = (Clay_Arena) { .label = CLAY_STRING("Clay Memory Arena"), .memory = malloc(totalMemorySize), .capacity = totalMemorySize };
|
||||
Clay_Arena clayMemory = Clay_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
|
||||
Clay_SetMeasureTextFunction(Raylib_MeasureText);
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() });
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
Clay_Raylib_Initialize(1024, 768, "Clay - Raylib Renderer Example", FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT);
|
||||
profilePicture = LoadTextureFromImage(LoadImage("resources/profile-picture.png"));
|
||||
Raylib_fonts[FONT_ID_BODY_24] = (Raylib_Font) {
|
||||
@ -226,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_CreateArenaWithCapacityAndMemory(totalMemorySize, malloc(totalMemorySize));
|
||||
Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() }, (Clay_ErrorHandler) { HandleClayErrors });
|
||||
reinitializeClay = false;
|
||||
}
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
return 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
$TYPE$ *$NAME$_Add($NAME$ *array, $TYPE$ item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
return &array->internalArray[array->length - 1];
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
void $NAME$_Add($NAME$ *array, $TYPE$ item) {
|
||||
if (Clay__Array_IncrementCapacityCheck(array->length, array->capacity)) {
|
||||
if (Clay__Array_AddCapacityCheck(array->length, array->capacity)) {
|
||||
array->internalArray[array->length++] = item;
|
||||
}
|
||||
}
|
@ -1,13 +1,6 @@
|
||||
void $NAME$_Set($NAME$ *array, int index, $TYPE$ value) {
|
||||
if (index < array->capacity && index >= 0) {
|
||||
if (Clay__Array_RangeCheck(index, array->capacity)) {
|
||||
array->internalArray[index] = value;
|
||||
array->length = index < array->length ? array->length : index + 1;
|
||||
} else {
|
||||
if (Clay__warningsEnabled) {
|
||||
Clay__WarningArray_Add(&Clay_warnings, CLAY__INIT(Clay__Warning) { CLAY_STRING("Attempting to allocate array in arena, but arena is already at capacity and would overflow.") });
|
||||
}
|
||||
#ifdef CLAY_OVERFLOW_TRAP
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,22 +1,22 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib v5.5-dev - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
* raylib v5.5 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com)
|
||||
*
|
||||
* FEATURES:
|
||||
* - NO external dependencies, all required libraries included with raylib
|
||||
* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly,
|
||||
* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5.
|
||||
* - Written in plain C code (C99) in PascalCase/camelCase notation
|
||||
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile)
|
||||
* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3, ES2, ES3 - choose at compile)
|
||||
* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
|
||||
* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts)
|
||||
* - Multiple Fonts formats supported (TTF, OTF, FNT, BDF, Sprite fonts)
|
||||
* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
|
||||
* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
|
||||
* - Flexible Materials system, supporting classic maps and PBR maps
|
||||
* - Animated 3D models supported (skeletal bones animation) (IQM)
|
||||
* - Animated 3D models supported (skeletal bones animation) (IQM, M3D, GLTF)
|
||||
* - Shaders support, including Model shaders and Postprocessing shaders
|
||||
* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
|
||||
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
|
||||
* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, QOA, XM, MOD)
|
||||
* - VR stereo rendering with configurable HMD device parameters
|
||||
* - Bindings to multiple programming languages available!
|
||||
*
|
||||
@ -27,29 +27,35 @@
|
||||
* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
|
||||
*
|
||||
* DEPENDENCIES (included):
|
||||
* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP)
|
||||
* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP)
|
||||
* [rcore][GLFW] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input
|
||||
* [rcore][RGFW] rgfw (ColleagueRiley - github.com/ColleagueRiley/RGFW) for window/context management and input
|
||||
* [rlgl] glad/glad_gles2 (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading
|
||||
* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management
|
||||
*
|
||||
* OPTIONAL DEPENDENCIES (included):
|
||||
* [rcore] msf_gif (Miles Fogle) for GIF recording
|
||||
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
|
||||
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
|
||||
* [rcore] rprand (Ramon Snatamaria) for pseudo-random numbers generation
|
||||
* [rtextures] qoi (Dominic Szablewski - https://phoboslab.org) for QOI image manage
|
||||
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
|
||||
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
|
||||
* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
|
||||
* [rtextures] stb_image_resize2 (Sean Barret) for image resizing algorithms
|
||||
* [rtextures] stb_perlin (Sean Barret) for Perlin Noise image generation
|
||||
* [rtext] stb_truetype (Sean Barret) for ttf fonts loading
|
||||
* [rtext] stb_rect_pack (Sean Barret) for rectangles packing
|
||||
* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation
|
||||
* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL)
|
||||
* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF)
|
||||
* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
|
||||
* [rmodels] m3d (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d)
|
||||
* [rmodels] vox_loader (Johann Nadalutti) for models loading (VOX)
|
||||
* [raudio] dr_wav (David Reid) for WAV audio file loading
|
||||
* [raudio] dr_flac (David Reid) for FLAC audio file loading
|
||||
* [raudio] dr_mp3 (David Reid) for MP3 audio file loading
|
||||
* [raudio] stb_vorbis (Sean Barret) for OGG audio loading
|
||||
* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading
|
||||
* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading
|
||||
* [raudio] qoa (Dominic Szablewski - https://phoboslab.org) for QOA audio manage
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
@ -84,7 +90,7 @@
|
||||
#define RAYLIB_VERSION_MAJOR 5
|
||||
#define RAYLIB_VERSION_MINOR 5
|
||||
#define RAYLIB_VERSION_PATCH 0
|
||||
#define RAYLIB_VERSION "5.5-dev"
|
||||
#define RAYLIB_VERSION "5.5"
|
||||
|
||||
// Function specifiers in case library is build/used as a shared library
|
||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
|
||||
@ -352,8 +358,10 @@ typedef struct Mesh {
|
||||
// Animation vertex data
|
||||
float *animVertices; // Animated vertex positions (after bones transformations)
|
||||
float *animNormals; // Animated normals (after bones transformations)
|
||||
unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning)
|
||||
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning)
|
||||
unsigned char *boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) (shader-location = 6)
|
||||
float *boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) (shader-location = 7)
|
||||
Matrix *boneMatrices; // Bones animated transformation matrices
|
||||
int boneCount; // Number of bones
|
||||
|
||||
// OpenGL identifiers
|
||||
unsigned int vaoId; // OpenGL Vertex Array Object id
|
||||
@ -790,7 +798,10 @@ typedef enum {
|
||||
SHADER_LOC_MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap
|
||||
SHADER_LOC_MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance
|
||||
SHADER_LOC_MAP_PREFILTER, // Shader location: samplerCube texture: prefilter
|
||||
SHADER_LOC_MAP_BRDF // Shader location: sampler2d texture: brdf
|
||||
SHADER_LOC_MAP_BRDF, // Shader location: sampler2d texture: brdf
|
||||
SHADER_LOC_VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds
|
||||
SHADER_LOC_VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights
|
||||
SHADER_LOC_BONE_MATRICES // Shader location: array of matrices uniform: boneMatrices
|
||||
} ShaderLocationIndex;
|
||||
|
||||
#define SHADER_LOC_MAP_DIFFUSE SHADER_LOC_MAP_ALBEDO
|
||||
@ -872,8 +883,7 @@ typedef enum {
|
||||
CUBEMAP_LAYOUT_LINE_VERTICAL, // Layout is defined by a vertical line with faces
|
||||
CUBEMAP_LAYOUT_LINE_HORIZONTAL, // Layout is defined by a horizontal line with faces
|
||||
CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces
|
||||
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces
|
||||
CUBEMAP_LAYOUT_PANORAMA // Layout is defined by a panorama image (equirrectangular map)
|
||||
CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE // Layout is defined by a 4x3 cross with cubemap faces
|
||||
} CubemapLayout;
|
||||
|
||||
// Font type, defines generation method
|
||||
@ -960,36 +970,36 @@ RLAPI void CloseWindow(void); // Close windo
|
||||
RLAPI bool WindowShouldClose(void); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked)
|
||||
RLAPI bool IsWindowReady(void); // Check if window has been initialized successfully
|
||||
RLAPI bool IsWindowFullscreen(void); // Check if window is currently fullscreen
|
||||
RLAPI bool IsWindowHidden(void); // Check if window is currently hidden (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowFocused(void); // Check if window is currently focused (only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsWindowHidden(void); // Check if window is currently hidden
|
||||
RLAPI bool IsWindowMinimized(void); // Check if window is currently minimized
|
||||
RLAPI bool IsWindowMaximized(void); // Check if window is currently maximized
|
||||
RLAPI bool IsWindowFocused(void); // Check if window is currently focused
|
||||
RLAPI bool IsWindowResized(void); // Check if window has been resized last frame
|
||||
RLAPI bool IsWindowState(unsigned int flag); // Check if one specific window flag is enabled
|
||||
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowState(unsigned int flags); // Set window configuration state using flags
|
||||
RLAPI void ClearWindowState(unsigned int flags); // Clear window configuration state flags
|
||||
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP)
|
||||
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP)
|
||||
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP)
|
||||
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP)
|
||||
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowTitle(const char *title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB)
|
||||
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
|
||||
RLAPI void ToggleFullscreen(void); // Toggle window state: fullscreen/windowed, resizes monitor to match window resolution
|
||||
RLAPI void ToggleBorderlessWindowed(void); // Toggle window state: borderless windowed, resizes window to match monitor resolution
|
||||
RLAPI void MaximizeWindow(void); // Set window state: maximized, if resizable
|
||||
RLAPI void MinimizeWindow(void); // Set window state: minimized, if resizable
|
||||
RLAPI void RestoreWindow(void); // Set window state: not minimized/maximized
|
||||
RLAPI void SetWindowIcon(Image image); // Set icon for window (single image, RGBA 32bit)
|
||||
RLAPI void SetWindowIcons(Image *images, int count); // Set icon for window (multiple images, RGBA 32bit)
|
||||
RLAPI void SetWindowTitle(const char *title); // Set title for window
|
||||
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen
|
||||
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window
|
||||
RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
|
||||
RLAPI void SetWindowMaxSize(int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE)
|
||||
RLAPI void SetWindowSize(int width, int height); // Set window dimensions
|
||||
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowFocused(void); // Set window focused (only PLATFORM_DESKTOP)
|
||||
RLAPI void SetWindowOpacity(float opacity); // Set window opacity [0.0f..1.0f]
|
||||
RLAPI void SetWindowFocused(void); // Set window focused
|
||||
RLAPI void *GetWindowHandle(void); // Get native window handle
|
||||
RLAPI int GetScreenWidth(void); // Get current screen width
|
||||
RLAPI int GetScreenHeight(void); // Get current screen height
|
||||
RLAPI int GetRenderWidth(void); // Get current render width (it considers HiDPI)
|
||||
RLAPI int GetRenderHeight(void); // Get current render height (it considers HiDPI)
|
||||
RLAPI int GetMonitorCount(void); // Get number of connected monitors
|
||||
RLAPI int GetCurrentMonitor(void); // Get current connected monitor
|
||||
RLAPI int GetCurrentMonitor(void); // Get current monitor where window is placed
|
||||
RLAPI Vector2 GetMonitorPosition(int monitor); // Get specified monitor position
|
||||
RLAPI int GetMonitorWidth(int monitor); // Get specified monitor width (current video mode used by monitor)
|
||||
RLAPI int GetMonitorHeight(int monitor); // Get specified monitor height (current video mode used by monitor)
|
||||
@ -1001,6 +1011,7 @@ RLAPI Vector2 GetWindowScaleDPI(void); // Get window
|
||||
RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor
|
||||
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
|
||||
RLAPI const char *GetClipboardText(void); // Get clipboard text content
|
||||
RLAPI Image GetClipboardImage(void); // Get clipboard image content
|
||||
RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling
|
||||
RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling
|
||||
|
||||
@ -1039,7 +1050,7 @@ RLAPI void UnloadVrStereoConfig(VrStereoConfig config); // Unload VR s
|
||||
// NOTE: Shader functionality is not available on OpenGL 1.1
|
||||
RLAPI Shader LoadShader(const char *vsFileName, const char *fsFileName); // Load shader from files and bind default locations
|
||||
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); // Load shader from code strings and bind default locations
|
||||
RLAPI bool IsShaderReady(Shader shader); // Check if a shader is ready
|
||||
RLAPI bool IsShaderValid(Shader shader); // Check if a shader is valid (loaded on GPU)
|
||||
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
|
||||
RLAPI int GetShaderLocationAttrib(Shader shader, const char *attribName); // Get shader attribute location
|
||||
RLAPI void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); // Set shader uniform value
|
||||
@ -1122,11 +1133,12 @@ RLAPI const char *GetDirectoryPath(const char *filePath); // Get full pa
|
||||
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
|
||||
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
||||
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
|
||||
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
|
||||
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
|
||||
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
|
||||
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
|
||||
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths
|
||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan
|
||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result
|
||||
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
|
||||
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
||||
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
|
||||
@ -1138,6 +1150,10 @@ RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *
|
||||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
|
||||
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
|
||||
RLAPI unsigned int ComputeCRC32(unsigned char *data, int dataSize); // Compute CRC32 hash code
|
||||
RLAPI unsigned int *ComputeMD5(unsigned char *data, int dataSize); // Compute MD5 hash code, returns static int[4] (16 bytes)
|
||||
RLAPI unsigned int *ComputeSHA1(unsigned char *data, int dataSize); // Compute SHA1 hash code, returns static int[5] (20 bytes)
|
||||
|
||||
|
||||
// Automation events functionality
|
||||
RLAPI AutomationEventList LoadAutomationEventList(const char *fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS
|
||||
@ -1155,7 +1171,7 @@ RLAPI void PlayAutomationEvent(AutomationEvent event);
|
||||
|
||||
// Input-related functions: keyboard
|
||||
RLAPI bool IsKeyPressed(int key); // Check if a key has been pressed once
|
||||
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP)
|
||||
RLAPI bool IsKeyPressedRepeat(int key); // Check if a key has been pressed again
|
||||
RLAPI bool IsKeyDown(int key); // Check if a key is being pressed
|
||||
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
|
||||
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
|
||||
@ -1174,7 +1190,7 @@ RLAPI int GetGamepadButtonPressed(void);
|
||||
RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad
|
||||
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis
|
||||
RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB)
|
||||
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor); // Set gamepad vibration for both motors
|
||||
RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds)
|
||||
|
||||
// Input-related functions: mouse
|
||||
RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once
|
||||
@ -1205,7 +1221,7 @@ RLAPI int GetTouchPointCount(void); // Get number of t
|
||||
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
|
||||
RLAPI bool IsGestureDetected(unsigned int gesture); // Check if a gesture have been detected
|
||||
RLAPI int GetGestureDetected(void); // Get latest detected gesture
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
|
||||
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in seconds
|
||||
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
|
||||
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
|
||||
RLAPI Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
|
||||
@ -1228,8 +1244,8 @@ RLAPI Texture2D GetShapesTexture(void); // Get t
|
||||
RLAPI Rectangle GetShapesTextureRectangle(void); // Get texture source rectangle that is used for shapes drawing
|
||||
|
||||
// Basic shapes drawing functions
|
||||
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
|
||||
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
|
||||
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel using geometry [Can be slow, use with care]
|
||||
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel using geometry (Vector version) [Can be slow, use with care]
|
||||
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
|
||||
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines)
|
||||
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads)
|
||||
@ -1238,7 +1254,7 @@ RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color c
|
||||
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
|
||||
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
|
||||
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
|
||||
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
|
||||
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color inner, Color outer); // Draw a gradient-filled circle
|
||||
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
|
||||
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
|
||||
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
|
||||
@ -1250,9 +1266,9 @@ RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color)
|
||||
RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
|
||||
RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
|
||||
RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters
|
||||
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a vertical-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors
|
||||
RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Color top, Color bottom); // Draw a vertical-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color left, Color right); // Draw a horizontal-gradient-filled rectangle
|
||||
RLAPI void DrawRectangleGradientEx(Rectangle rec, Color topLeft, Color bottomLeft, Color topRight, Color bottomRight); // Draw a gradient-filled rectangle with custom vertex colors
|
||||
RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
|
||||
RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters
|
||||
RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges
|
||||
@ -1289,13 +1305,13 @@ RLAPI Vector2 GetSplinePointBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vect
|
||||
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
|
||||
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
|
||||
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
|
||||
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
|
||||
RLAPI bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
RLAPI bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
|
||||
RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
|
||||
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
|
||||
RLAPI bool CheckCollisionPointPoly(Vector2 point, const Vector2 *points, int pointCount); // Check if point is within a polygon described by array of vertices
|
||||
RLAPI bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference
|
||||
RLAPI bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]
|
||||
RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2); // Check if circle collides with a line created betweeen two points [p1] and [p2]
|
||||
RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -1306,13 +1322,12 @@ RLAPI Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2);
|
||||
// NOTE: These functions do not require GPU access
|
||||
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
|
||||
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data
|
||||
RLAPI Image LoadImageSvg(const char *fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size
|
||||
RLAPI Image LoadImageAnim(const char *fileName, int *frames); // Load image sequence from file (frames appended to image.data)
|
||||
RLAPI Image LoadImageAnimFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int *frames); // Load image sequence from memory buffer
|
||||
RLAPI Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png'
|
||||
RLAPI Image LoadImageFromTexture(Texture2D texture); // Load image from GPU texture data
|
||||
RLAPI Image LoadImageFromScreen(void); // Load image from screen buffer and (screenshot)
|
||||
RLAPI bool IsImageReady(Image image); // Check if an image is ready
|
||||
RLAPI bool IsImageValid(Image image); // Check if an image is valid (data and parameters)
|
||||
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
RLAPI bool ExportImage(Image image, const char *fileName); // Export image data to file, returns true on success
|
||||
RLAPI unsigned char *ExportImageToMemory(Image image, const char *fileType, int *fileSize); // Export image to memory buffer
|
||||
@ -1398,9 +1413,9 @@ RLAPI Texture2D LoadTexture(const char *fileName);
|
||||
RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data
|
||||
RLAPI TextureCubemap LoadTextureCubemap(Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported
|
||||
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer)
|
||||
RLAPI bool IsTextureReady(Texture2D texture); // Check if a texture is ready
|
||||
RLAPI bool IsTextureValid(Texture2D texture); // Check if a texture is valid (loaded in GPU)
|
||||
RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM)
|
||||
RLAPI bool IsRenderTextureReady(RenderTexture2D target); // Check if a render texture is ready
|
||||
RLAPI bool IsRenderTextureValid(RenderTexture2D target); // Check if a render texture is valid (loaded in GPU)
|
||||
RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM)
|
||||
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
|
||||
RLAPI void UpdateTextureRec(Texture2D texture, Rectangle rec, const void *pixels); // Update GPU texture rectangle with new data
|
||||
@ -1431,6 +1446,7 @@ RLAPI Color ColorBrightness(Color color, float factor); // G
|
||||
RLAPI Color ColorContrast(Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f
|
||||
RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
|
||||
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
|
||||
RLAPI Color ColorLerp(Color color1, Color color2, float factor); // Get color lerp interpolation between two colors, factor [0.0f..1.0f]
|
||||
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
|
||||
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
|
||||
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
|
||||
@ -1443,10 +1459,10 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
|
||||
// Font loading/unloading functions
|
||||
RLAPI Font GetFontDefault(void); // Get the default Font
|
||||
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
||||
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||
RLAPI bool IsFontReady(Font font); // Check if a font is ready
|
||||
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
|
||||
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use
|
||||
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
||||
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
|
||||
@ -1536,7 +1552,7 @@ RLAPI void DrawGrid(int slices, float spacing);
|
||||
// Model management functions
|
||||
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
|
||||
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
|
||||
RLAPI bool IsModelReady(Model model); // Check if a model is ready
|
||||
RLAPI bool IsModelValid(Model model); // Check if a model is valid (loaded in GPU, VAO/VBOs)
|
||||
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
|
||||
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
|
||||
|
||||
@ -1545,6 +1561,8 @@ RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint);
|
||||
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
|
||||
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
|
||||
RLAPI void DrawModelPoints(Model model, Vector3 position, float scale, Color tint); // Draw a model as points
|
||||
RLAPI void DrawModelPointsEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model as points with extended parameters
|
||||
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
|
||||
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a billboard texture
|
||||
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
|
||||
@ -1577,14 +1595,15 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
||||
// Material loading/unloading functions
|
||||
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
|
||||
RLAPI Material LoadMaterialDefault(void); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps)
|
||||
RLAPI bool IsMaterialReady(Material material); // Check if a material is ready
|
||||
RLAPI bool IsMaterialValid(Material material); // Check if a material is valid (shader assigned, map textures loaded in GPU)
|
||||
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
|
||||
RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...)
|
||||
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
|
||||
|
||||
// Model animations loading/unloading functions
|
||||
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
|
||||
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
|
||||
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose (CPU)
|
||||
RLAPI void UpdateModelAnimationBones(Model model, ModelAnimation anim, int frame); // Update model animation mesh bone matrices (GPU skinning)
|
||||
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
|
||||
RLAPI void UnloadModelAnimations(ModelAnimation *animations, int animCount); // Unload animation array data
|
||||
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
|
||||
@ -1614,11 +1633,11 @@ RLAPI float GetMasterVolume(void); // Get mas
|
||||
// Wave/Sound loading/unloading functions
|
||||
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
|
||||
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
|
||||
RLAPI bool IsWaveReady(Wave wave); // Checks if wave data is ready
|
||||
RLAPI bool IsWaveValid(Wave wave); // Checks if wave data is valid (data loaded and parameters)
|
||||
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
|
||||
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
|
||||
RLAPI Sound LoadSoundAlias(Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data
|
||||
RLAPI bool IsSoundReady(Sound sound); // Checks if a sound is ready
|
||||
RLAPI bool IsSoundValid(Sound sound); // Checks if a sound is valid (data loaded and buffers initialized)
|
||||
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data
|
||||
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
||||
RLAPI void UnloadSound(Sound sound); // Unload sound
|
||||
@ -1644,7 +1663,7 @@ RLAPI void UnloadWaveSamples(float *samples); // Unload
|
||||
// Music management functions
|
||||
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
|
||||
RLAPI Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data, int dataSize); // Load music stream from data
|
||||
RLAPI bool IsMusicReady(Music music); // Checks if a music stream is ready
|
||||
RLAPI bool IsMusicValid(Music music); // Checks if a music stream is valid (context and buffers initialized)
|
||||
RLAPI void UnloadMusicStream(Music music); // Unload music stream
|
||||
RLAPI void PlayMusicStream(Music music); // Start music playing
|
||||
RLAPI bool IsMusicStreamPlaying(Music music); // Check if music is playing
|
||||
@ -1661,7 +1680,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur
|
||||
|
||||
// AudioStream management functions
|
||||
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
|
||||
RLAPI bool IsAudioStreamReady(AudioStream stream); // Checks if an audio stream is ready
|
||||
RLAPI bool IsAudioStreamValid(AudioStream stream); // Checks if an audio stream is valid (buffers initialized)
|
||||
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
|
||||
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
|
||||
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||
* raymath v2.0 - Math functions to work with Vector2, Vector3, Matrix and Quaternions
|
||||
*
|
||||
* CONVENTIONS:
|
||||
* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all
|
||||
@ -12,7 +12,7 @@
|
||||
* - Functions are always self-contained, no function use another raymath function inside,
|
||||
* required code is directly re-implemented inside
|
||||
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
||||
* - Functions use always a "result" variable for return
|
||||
* - Functions use always a "result" variable for return (except C++ operators)
|
||||
* - Functions are always defined inline
|
||||
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
||||
* - No compound literals used to make sure libray is compatible with C++
|
||||
@ -27,6 +27,8 @@
|
||||
* Define static inline functions code, so #include header suffices for use.
|
||||
* This may use up lots of memory.
|
||||
*
|
||||
* #define RAYMATH_DISABLE_CPP_OPERATORS
|
||||
* Disables C++ operator overloads for raymath types.
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
@ -2567,7 +2569,13 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
||||
if (!FloatEquals(det, 0))
|
||||
{
|
||||
clone.m0 /= s.x;
|
||||
clone.m4 /= s.x;
|
||||
clone.m8 /= s.x;
|
||||
clone.m1 /= s.y;
|
||||
clone.m5 /= s.y;
|
||||
clone.m9 /= s.y;
|
||||
clone.m2 /= s.z;
|
||||
clone.m6 /= s.z;
|
||||
clone.m10 /= s.z;
|
||||
|
||||
// Extract rotation
|
||||
@ -2580,4 +2588,354 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RAYMATH_H
|
||||
#if defined(__cplusplus) && !defined(RAYMATH_DISABLE_CPP_OPERATORS)
|
||||
|
||||
// Optional C++ math operators
|
||||
//-------------------------------------------------------------------------------
|
||||
|
||||
// Vector2 operators
|
||||
static constexpr Vector2 Vector2Zeros = { 0, 0 };
|
||||
static constexpr Vector2 Vector2Ones = { 1, 1 };
|
||||
static constexpr Vector2 Vector2UnitX = { 1, 0 };
|
||||
static constexpr Vector2 Vector2UnitY = { 0, 1 };
|
||||
|
||||
inline Vector2 operator + (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Add(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator += (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Add(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator - (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Subtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator -= (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Subtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const float& rhs)
|
||||
{
|
||||
return Vector2Scale(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator *= (Vector2& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector2Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Multiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator *= (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Multiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator * (const Vector2& lhs, const Matrix& rhs)
|
||||
{
|
||||
return Vector2Transform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator -= (Vector2& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = Vector2Transform(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator / (const Vector2& lhs, const float& rhs)
|
||||
{
|
||||
return Vector2Scale(lhs, 1.0f / rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator /= (Vector2& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector2Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector2 operator / (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return Vector2Divide(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector2& operator /= (Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
lhs = Vector2Divide(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector2& lhs, const Vector2& rhs)
|
||||
{
|
||||
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y);
|
||||
}
|
||||
|
||||
// Vector3 operators
|
||||
static constexpr Vector3 Vector3Zeros = { 0, 0, 0 };
|
||||
static constexpr Vector3 Vector3Ones = { 1, 1, 1 };
|
||||
static constexpr Vector3 Vector3UnitX = { 1, 0, 0 };
|
||||
static constexpr Vector3 Vector3UnitY = { 0, 1, 0 };
|
||||
static constexpr Vector3 Vector3UnitZ = { 0, 0, 1 };
|
||||
|
||||
inline Vector3 operator + (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Add(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator += (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Add(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator - (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Subtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator -= (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Subtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const float& rhs)
|
||||
{
|
||||
return Vector3Scale(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator *= (Vector3& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector3Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Multiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator *= (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Multiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator * (const Vector3& lhs, const Matrix& rhs)
|
||||
{
|
||||
return Vector3Transform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator -= (Vector3& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = Vector3Transform(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator / (const Vector3& lhs, const float& rhs)
|
||||
{
|
||||
return Vector3Scale(lhs, 1.0f / rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator /= (Vector3& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector3Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector3 operator / (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return Vector3Divide(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector3& operator /= (Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
lhs = Vector3Divide(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector3& lhs, const Vector3& rhs)
|
||||
{
|
||||
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z);
|
||||
}
|
||||
|
||||
// Vector4 operators
|
||||
static constexpr Vector4 Vector4Zeros = { 0, 0, 0, 0 };
|
||||
static constexpr Vector4 Vector4Ones = { 1, 1, 1, 1 };
|
||||
static constexpr Vector4 Vector4UnitX = { 1, 0, 0, 0 };
|
||||
static constexpr Vector4 Vector4UnitY = { 0, 1, 0, 0 };
|
||||
static constexpr Vector4 Vector4UnitZ = { 0, 0, 1, 0 };
|
||||
static constexpr Vector4 Vector4UnitW = { 0, 0, 0, 1 };
|
||||
|
||||
inline Vector4 operator + (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Add(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator += (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Add(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator - (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Subtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator -= (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Subtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator * (const Vector4& lhs, const float& rhs)
|
||||
{
|
||||
return Vector4Scale(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator *= (Vector4& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector4Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator * (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Multiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator *= (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Multiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator / (const Vector4& lhs, const float& rhs)
|
||||
{
|
||||
return Vector4Scale(lhs, 1.0f / rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator /= (Vector4& lhs, const float& rhs)
|
||||
{
|
||||
lhs = Vector4Scale(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Vector4 operator / (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return Vector4Divide(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Vector4& operator /= (Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
lhs = Vector4Divide(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline bool operator == (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return FloatEquals(lhs.x, rhs.x) && FloatEquals(lhs.y, rhs.y) && FloatEquals(lhs.z, rhs.z) && FloatEquals(lhs.w, rhs.w);
|
||||
}
|
||||
|
||||
inline bool operator != (const Vector4& lhs, const Vector4& rhs)
|
||||
{
|
||||
return !FloatEquals(lhs.x, rhs.x) || !FloatEquals(lhs.y, rhs.y) || !FloatEquals(lhs.z, rhs.z) || !FloatEquals(lhs.w, rhs.w);
|
||||
}
|
||||
|
||||
// Quaternion operators
|
||||
static constexpr Quaternion QuaternionZeros = { 0, 0, 0, 0 };
|
||||
static constexpr Quaternion QuaternionOnes = { 1, 1, 1, 1 };
|
||||
static constexpr Quaternion QuaternionUnitX = { 0, 0, 0, 1 };
|
||||
|
||||
inline Quaternion operator + (const Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
return QuaternionAddValue(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Quaternion& operator += (Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
lhs = QuaternionAddValue(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Quaternion operator - (const Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
return QuaternionSubtractValue(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Quaternion& operator -= (Quaternion& lhs, const float& rhs)
|
||||
{
|
||||
lhs = QuaternionSubtractValue(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Quaternion operator * (const Quaternion& lhs, const Matrix& rhs)
|
||||
{
|
||||
return QuaternionTransform(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Quaternion& operator *= (Quaternion& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = QuaternionTransform(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
// Matrix operators
|
||||
inline Matrix operator + (const Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
return MatrixAdd(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Matrix& operator += (Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = MatrixAdd(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Matrix operator - (const Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
return MatrixSubtract(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Matrix& operator -= (Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = MatrixSubtract(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline Matrix operator * (const Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
return MatrixMultiply(lhs, rhs);
|
||||
}
|
||||
|
||||
inline const Matrix& operator *= (Matrix& lhs, const Matrix& rhs)
|
||||
{
|
||||
lhs = MatrixMultiply(lhs, rhs);
|
||||
return lhs;
|
||||
}
|
||||
//-------------------------------------------------------------------------------
|
||||
#endif // C++ operators
|
||||
|
||||
#endif // RAYMATH_H
|
||||
|
Loading…
Reference in New Issue
Block a user