From b1b2586afa06105291355a19f581016c347463bc Mon Sep 17 00:00:00 2001 From: physick Date: Tue, 11 Aug 2026 21:08:37 +0500 Subject: arena + dir reading --- src/main.c | 4 ++- src/scenes/collectionScene.c | 83 ++++++++++++++++++++++++++++++++++++++++++-- src/ui_elements/UI.c | 6 ++-- src/ui_elements/UI.h | 4 +++ src/utils/arena.c | 38 ++++++++++++++++++++ src/utils/arena.h | 17 +++++++++ 6 files changed, 145 insertions(+), 7 deletions(-) create mode 100644 src/utils/arena.c create mode 100644 src/utils/arena.h (limited to 'src') diff --git a/src/main.c b/src/main.c index 0c94184..34b32e0 100644 --- a/src/main.c +++ b/src/main.c @@ -3,7 +3,6 @@ #include "scenes/scenes.h" #include "resources/resources.h" - int main(void) { Puzzle *puzzle = ReadPuzzleFromFile("puzzles/test.pz"); PrintPuzzle(puzzle); @@ -27,6 +26,9 @@ int main(void) { return 1; } + DeleteSceneFromStack(); + return 0; + // if (!AddScene(CreatePuzzleScene(puzzle))) { // printf("Failed to create a puzzle menu\n"); // return 1; diff --git a/src/scenes/collectionScene.c b/src/scenes/collectionScene.c index 2173619..8ed545a 100644 --- a/src/scenes/collectionScene.c +++ b/src/scenes/collectionScene.c @@ -1,14 +1,80 @@ -#include "scenes.h" +#include #include +#include +#include +#include #include +#include "scenes.h" #include "../ui_elements/UI.h" #include "../resources/resources.h" +#include "../utils/arena.h" + +typedef struct { + char *Name; +} CollectionElement; + +static const size_t ARENA_SIZE = 1024 * 64; typedef struct { + Arena arena; char *DirPath; char *Name; + + CollectionElement *elements; + size_t count; } CollectionSceneData; +bool readCollectionFromDir(char *path, CollectionSceneData *data) { + DIR *dir = opendir(path); + if (dir == NULL) { + perror("Failed to open a dir"); + return false; + } + + CollectionElement *outp = malloc(sizeof(CollectionElement)); + if (outp == NULL) { + TraceLog(LOG_ERROR, "Failed to create the buffer in the heap"); + closedir(dir); + return false; + }; + + struct dirent *entry; + size_t cap = 16; + CollectionElement *elements = malloc(sizeof(CollectionElement) * cap); + + while ((entry = readdir(dir)) != NULL) { + // The element is not a file. Also eliminates `.` and `..` + if (entry->d_type != 8) continue; + if (data->count == cap) { + CollectionElement *new = realloc(elements, cap * 2); + if (new == NULL) break; + cap *= 2; + elements = new; + } + CollectionElement *current = &elements[data->count]; + current->Name = ArenaStrdup(&data->arena, entry->d_name); + data->count += 1; + } + + // Moving all of this to the arena + size_t array_size = sizeof(CollectionElement) * data->count; + data->elements = ArenaAlloc(&data->arena, array_size); + + if (data->elements == NULL) { + TraceLog(LOG_ERROR, "The arena failed to allocate the element array"); + // The arena is full + free(elements); + data->count = 0; + closedir(dir); + return false; + } + + memcpy(data->elements, elements, array_size); + free(elements); + closedir(dir); + return true; +} + CollectionSceneData *getData(void *self) { return ((Scene *)self)->data; } @@ -47,7 +113,10 @@ bool drawCollectionScene(void *self) { void deinitCollectionScene(void *self) { TraceLog(LOG_INFO, "Deleting a collection scene"); CollectionSceneData *data = getData(self); - if (data != NULL) free(data); + if (data != NULL) { + free(data->arena.mem); + free(data); + } free((Scene *)self); } @@ -65,8 +134,16 @@ Scene *CreatePuzzleCollectionScene(char *path) { free(outp); return NULL; } - data->DirPath = strdup(path); + data->arena = (Arena){0}; + ArenaInit(&data->arena, ARENA_SIZE); + data->DirPath = ArenaStrdup(&data->arena, path); data->Name = getCollectionName(path); + if (!readCollectionFromDir(path, data)) { + TraceLog(LOG_ERROR, "Failed to read the collection directory"); + } + for (int i = 0; i < data->count; i++) { + TraceLog(LOG_INFO, "Puzzle: %s", data->elements[i].Name); + } outp->data = data; diff --git a/src/ui_elements/UI.c b/src/ui_elements/UI.c index 9daed74..9f17826 100644 --- a/src/ui_elements/UI.c +++ b/src/ui_elements/UI.c @@ -6,8 +6,8 @@ const int MAX_LINES = 8192; const int SPACING_H = 1; void DrawRecBordered(Rectangle rec, Color bg, Color border_color, int border_width) { - DrawRectangleRounded(rec, 0.015f, 8, bg); - DrawRectangleRoundedLinesEx(rec, 0.015f, 8, border_width, border_color); + DrawRectangleRounded(rec, ROUNDNESS, ROUNDNESS_SEGMENTS, bg); + DrawRectangleRoundedLinesEx(rec, ROUNDNESS, ROUNDNESS_SEGMENTS, border_width, border_color); } float MeasureChar(Font *font, int height, char symbol) { @@ -126,7 +126,7 @@ void DrawPageView(int y, unsigned int pages, unsigned int current_page) { .b = COLORSCHEME_WHITE.b, .a = COLORSCHEME_WHITE.a & PAGE_DOTS_TRANSPARENCY }; - DrawRectangleRounded(rec, 0.15f, 8, color); + DrawRectangleRounded(rec, ROUNDNESS, ROUNDNESS_SEGMENTS, color); int x_pos = (int)rec.x + PAGE_DOTS_PADDING + PAGE_DOTS_RADIUS; int y_pos = (int)rec.y + PAGE_DOTS_PADDING + PAGE_DOTS_RADIUS; diff --git a/src/ui_elements/UI.h b/src/ui_elements/UI.h index 8754329..52d2222 100644 --- a/src/ui_elements/UI.h +++ b/src/ui_elements/UI.h @@ -5,6 +5,9 @@ #ifndef UI_ELEMENTS_H #define UI_ELEMENTS_H +static const float ROUNDNESS = 0.015f; +static const int ROUNDNESS_SEGMENTS = 8; + static const float SCROLL_SENC = 10; static const float TAB_WIDTH = 4; static const int PADDING = 10; @@ -44,6 +47,7 @@ static const int PAGE_DOTS_PADDING = 15; static const int PAGE_DOTS_RADIUS = 3; static const char PAGE_DOTS_TRANSPARENCY = (char)192; +/// Draws the little dots that represent the page you are on void DrawPageView(int y, unsigned int pages, unsigned int current_page); // ========== TEXT EDITOR ========== diff --git a/src/utils/arena.c b/src/utils/arena.c new file mode 100644 index 0000000..ce50d24 --- /dev/null +++ b/src/utils/arena.c @@ -0,0 +1,38 @@ +#include "arena.h" +#include +#include +#include +#include + +bool ArenaInit(Arena *arena, size_t capacity) { + arena->mem = malloc(capacity); + if (!arena->mem) { + return false; + } + arena->head = 0; + arena->capacity = capacity; + return true; +} + +void *ArenaAlloc(Arena *arena, size_t size) { + uintptr_t current_ptr = (uintptr_t)arena->mem + arena->head; + // Alignment + uintptr_t aligned_ptr = (current_ptr + 7) & ~7; + + size_t alignment_padding = aligned_ptr - current_ptr; + size_t total_needed = size + alignment_padding; + if (arena->head + total_needed > arena->capacity) { + return NULL; + } + + arena->head += total_needed; + return (void *)aligned_ptr; +} + +char *ArenaStrdup(Arena *arena, const char *str) { + size_t len = strlen(str) + 1; // adding a \0 + char *ptr = ArenaAlloc(arena, len); + if (ptr == NULL) return NULL; + memcpy(ptr, str, len); + return ptr; +} diff --git a/src/utils/arena.h b/src/utils/arena.h new file mode 100644 index 0000000..88cd17c --- /dev/null +++ b/src/utils/arena.h @@ -0,0 +1,17 @@ +#include +#include + +#ifndef ARENA_H +#define ARENA_H + +typedef struct { + void *mem; + size_t head; + size_t capacity; +} Arena; + +bool ArenaInit(Arena *arena, size_t capacity); +void *ArenaAlloc(Arena *arena, size_t size); +char *ArenaStrdup(Arena *arena, const char *str); + +#endif // ARENA_H -- cgit v1.3