clay icon indicating copy to clipboard operation
clay copied to clipboard

[Macros] CLAY_STRING should only be used for constant strings

Open mfbulut opened this issue 2 months ago • 8 comments

Environment:

  • OS: Windows 11
  • Renderer: raylib
  • GPU: NVIDIA RTX 3060

I was writing a small demo to test if I can use Clay to create a leaderboard (source code below). However, I noticed that Clay behaves incorrectly approximately 20% of the time, while it works as expected the other 80%. Every variablein my code is constant so I thought it was an issue with clay

Expected behavior:

image

Same executable 20% of the time

image image image image

#define CLAY_IMPLEMENTATION
#include "clay.h"
#include "clay_renderer_raylib.c"

const uint32_t FONT_ID_BODY_24 = 0;
const uint32_t FONT_ID_BODY_16 = 1;
#define COLOR_ORANGE (Clay_Color) {225, 138, 50, 255}
#define COLOR_BLUE (Clay_Color) {111, 173, 162, 255}

#define RAYLIB_VECTOR2_TO_CLAY_VECTOR2(vector) (Clay_Vector2) { .x = vector.x, .y = vector.y }

typedef struct {
    char rank[20];
    char name[20];
    char money[20];
} LeaderboardEntry;

LeaderboardEntry leaderboard2[] = {
    (LeaderboardEntry){"1", "richman","1000003"},
    (LeaderboardEntry){"2", "ali","3100"},
    (LeaderboardEntry){"3", "ahmed","1600"},
    (LeaderboardEntry){"4", "brokefurk","3"},
    (LeaderboardEntry){"5", "richman","1000003"},
    (LeaderboardEntry){"6", "ali","3100"},
    (LeaderboardEntry){"7", "ahmed","1600"},
    (LeaderboardEntry){"8", "brokefurk","3"},
    (LeaderboardEntry){"9", "brokefurk","3"},
    (LeaderboardEntry){"10", "brokefurk","3"},
    (LeaderboardEntry){"1", "richman","1000003"},
    (LeaderboardEntry){"2", "ali","3100"},
    (LeaderboardEntry){"3", "ahmed","1600"},
    (LeaderboardEntry){"4", "brokefurk","3"},
    (LeaderboardEntry){"5", "richman","1000003"},
    (LeaderboardEntry){"6", "ali","3100"},
    (LeaderboardEntry){"7", "ahmed","1600"},
    (LeaderboardEntry){"8", "brokefurk","3"},
    (LeaderboardEntry){"9", "brokefurk","3"},
    (LeaderboardEntry){"10","brokefurk","3"},
    (LeaderboardEntry){"1", "richman","1000003"},
    (LeaderboardEntry){"2", "ali","3100"},
    (LeaderboardEntry){"3", "ahmed","1600"},
    (LeaderboardEntry){"4", "brokefurk","3"},
    (LeaderboardEntry){"5", "richman","1000003"},
    (LeaderboardEntry){"6", "ali","3100"},
    (LeaderboardEntry){"7", "ahmed","1600"},
    (LeaderboardEntry){"8", "brokefurk","3"},
    (LeaderboardEntry){"9", "brokefurk","3"},
    (LeaderboardEntry){"10", "brokefurk","3"},
    (LeaderboardEntry){"1", "richman","1000003"},
    (LeaderboardEntry){"2", "ali","3100"},
    (LeaderboardEntry){"3", "ahmed","1600"},
    (LeaderboardEntry){"4", "brokefurk","3"},
    (LeaderboardEntry){"5", "richman","1000003"},
    (LeaderboardEntry){"6", "ali","3100"},
    (LeaderboardEntry){"7", "ahmed","1600"},
    (LeaderboardEntry){"8", "brokefurk","3"},
    (LeaderboardEntry){"9", "brokefurk","3"},
    (LeaderboardEntry){"10", "brokefurk","3"},
    (LeaderboardEntry){"1", "richman","1000003"},
    (LeaderboardEntry){"2", "ali","3100"},
    (LeaderboardEntry){"3", "ahmed","1600"},
    (LeaderboardEntry){"4", "brokefurk","3"},
    (LeaderboardEntry){"5", "richman","1000003"},
    (LeaderboardEntry){"6", "ali","3100"},
    (LeaderboardEntry){"7", "ahmed","1600"},
    (LeaderboardEntry){"8", "brokefurk","3"},
    (LeaderboardEntry){"9", "brokefurk","3"},
    (LeaderboardEntry){"10","brokefurk","3"},

};

int count = 50;

Clay_RenderCommandArray CreateLayout() {
    Clay_BeginLayout();
    CLAY(CLAY_LAYOUT({ .sizing = { .width = CLAY_SIZING_GROW(), .height = CLAY_SIZING_GROW() }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} }),
    CLAY_RECTANGLE({ .color = {200, 200, 200, 255} })) {
        CLAY(CLAY_ID("MainContent"),
            CLAY_SCROLL({ .vertical = true }),
            CLAY_LAYOUT({ .layoutDirection = CLAY_TOP_TO_BOTTOM, .sizing = { CLAY_SIZING_FIXED(600), CLAY_SIZING_FIXED(300) }  }),
            CLAY_RECTANGLE({ .color = {200, 200, 255, 255} }))
        {
            for (int i = 0; i < count; i++) {
                int rowColor = (i % 2) ? 40 : 60;
                CLAY(
                    CLAY_LAYOUT({ .childGap = 4, .sizing = { CLAY_SIZING_GROW(), CLAY_SIZING_FIXED(40) }  }),
                    CLAY_RECTANGLE({ .color = {0, 0, 0, 255} }))
                {

                    CLAY(
                        CLAY_LAYOUT({.sizing = { CLAY_SIZING_PERCENT(0.1f), CLAY_SIZING_GROW() }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER}}),
                        CLAY_RECTANGLE({ .color = {rowColor, rowColor, rowColor, 255} }))
                    {
                         CLAY_TEXT(CLAY_STRING(leaderboard2[i].rank), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {255,255,255,255} }));
                    }

                    CLAY(
                        CLAY_LAYOUT({.sizing = { CLAY_SIZING_PERCENT(0.45f), CLAY_SIZING_GROW() }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} }),
                        CLAY_RECTANGLE({ .color = {rowColor, rowColor, rowColor, 255} }))
                    {
                         CLAY_TEXT(CLAY_STRING(leaderboard2[i].name), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {255,255,255,255} }));
                    }
                    CLAY(
                        CLAY_LAYOUT({.sizing = { CLAY_SIZING_PERCENT(0.45f), CLAY_SIZING_GROW() }, .childAlignment = { CLAY_ALIGN_X_CENTER, CLAY_ALIGN_Y_CENTER} }),
                        CLAY_RECTANGLE({ .color = {rowColor, rowColor, rowColor, 255} }))
                    {
                         CLAY_TEXT(CLAY_STRING(leaderboard2[i].money), CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY_24, .fontSize = 24, .textColor = {255,255,255,255} }));
                    }

                }
            }

        }

        Clay_ScrollContainerData scrollData = Clay_GetScrollContainerData(Clay_GetElementId(CLAY_STRING("MainContent")));
        if (scrollData.found) {
            CLAY(CLAY_ID("ScrollBar"),
                CLAY_FLOATING({
                    .offset = { .y = -(scrollData.scrollPosition->y / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height },
                    .zIndex = 1,
                    .parentId = Clay_GetElementId(CLAY_STRING("MainContent")).id,
                    .attachment = {.element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_TOP}
                })
            ) {
                CLAY(CLAY_ID("ScrollBarButton"),
                    CLAY_LAYOUT({ .sizing = {CLAY_SIZING_FIXED(10), CLAY_SIZING_FIXED((scrollData.scrollContainerDimensions.height / scrollData.contentDimensions.height) * scrollData.scrollContainerDimensions.height) }}),
                    CLAY_RECTANGLE({ .cornerRadius = {6}, .color = Clay_PointerOver(Clay__HashString(CLAY_STRING("ScrollBar"), 0, 0)) ? (Clay_Color){255, 255, 255, 180} : (Clay_Color){255, 255, 255, 120} })
                ) {}
            }
        }
    }
    return Clay_EndLayout();
}

typedef struct
{
    Clay_Vector2 clickOrigin;
    Clay_Vector2 positionOrigin;
    bool mouseDown;
} ScrollbarData;

ScrollbarData scrollbarData = (ScrollbarData) {};

bool debugEnabled = false;

void UpdateDrawFrame(void)
{
    Vector2 mouseWheelDelta = GetMouseWheelMoveV();
    float mouseWheelX = mouseWheelDelta.x;
    float mouseWheelY = mouseWheelDelta.y;

    if (IsKeyPressed(KEY_D)) {
        debugEnabled = !debugEnabled;
        Clay_SetDebugModeEnabled(debugEnabled);
    }

    Clay_Vector2 mousePosition = RAYLIB_VECTOR2_TO_CLAY_VECTOR2(GetMousePosition());
    Clay_SetPointerState(mousePosition, IsMouseButtonDown(0) && !scrollbarData.mouseDown);
    Clay_SetLayoutDimensions((Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() });
    if (!IsMouseButtonDown(0)) {
        scrollbarData.mouseDown = false;
    }

    if (IsMouseButtonDown(0) && !scrollbarData.mouseDown && Clay_PointerOver(Clay__HashString(CLAY_STRING("ScrollBar"), 0, 0))) {
        Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(Clay__HashString(CLAY_STRING("MainContent"), 0, 0));
        scrollbarData.clickOrigin = mousePosition;
        scrollbarData.positionOrigin = *scrollContainerData.scrollPosition;
        scrollbarData.mouseDown = true;
    } else if (scrollbarData.mouseDown) {
        Clay_ScrollContainerData scrollContainerData = Clay_GetScrollContainerData(Clay__HashString(CLAY_STRING("MainContent"), 0, 0));
        if (scrollContainerData.contentDimensions.height > 0) {
            Clay_Vector2 ratio = (Clay_Vector2) {
                scrollContainerData.contentDimensions.width / scrollContainerData.scrollContainerDimensions.width,
                scrollContainerData.contentDimensions.height / scrollContainerData.scrollContainerDimensions.height,
            };
            if (scrollContainerData.config.vertical) {
                scrollContainerData.scrollPosition->y = scrollbarData.positionOrigin.y + (scrollbarData.clickOrigin.y - mousePosition.y) * ratio.y;
            }
            if (scrollContainerData.config.horizontal) {
                scrollContainerData.scrollPosition->x = scrollbarData.positionOrigin.x + (scrollbarData.clickOrigin.x - mousePosition.x) * ratio.x;
            }
        }
    }

    Clay_UpdateScrollContainers(true, (Clay_Vector2) {mouseWheelX, mouseWheelY}, GetFrameTime());

    double currentTime = GetTime();
    Clay_RenderCommandArray renderCommands = CreateLayout();
    printf("layout time: %f microseconds\n", (GetTime() - currentTime) * 1000 * 1000);

    BeginDrawing();
    ClearBackground(BLACK);
    Clay_Raylib_Render(renderCommands);
    EndDrawing();
}

int main() {
    uint64_t totalMemorySize = Clay_MinMemorySize();
    Clay_Arena clayMemory = (Clay_Arena) {.memory = malloc(totalMemorySize), .capacity = totalMemorySize };
    Clay_SetMeasureTextFunction(Raylib_MeasureText);
    Clay_Initialize(clayMemory, (Clay_Dimensions) { (float)GetScreenWidth(), (float)GetScreenHeight() });
    Clay_Raylib_Initialize(1200, 540, "Clay - Raylib Renderer Example", FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE | FLAG_WINDOW_HIGHDPI | FLAG_MSAA_4X_HINT);

    Raylib_fonts[FONT_ID_BODY_24] = (Raylib_Font) {
        .font = LoadFontEx("Poppins-Regular.ttf", 48, 0, 400),
        .fontId = FONT_ID_BODY_24,
    };
	SetTextureFilter(Raylib_fonts[FONT_ID_BODY_24].font.texture, TEXTURE_FILTER_BILINEAR);

    Raylib_fonts[FONT_ID_BODY_16] = (Raylib_Font) {
        .font = LoadFontEx("Poppins-Regular.ttf", 32, 0, 400),
        .fontId = FONT_ID_BODY_16,
    };
    SetTextureFilter(Raylib_fonts[FONT_ID_BODY_16].font.texture, TEXTURE_FILTER_BILINEAR);

    while (!WindowShouldClose())
    {
        UpdateDrawFrame();
    }
}

mfbulut avatar Dec 21 '24 08:12 mfbulut