summaryrefslogtreecommitdiff
path: root/src/scenes/collectionScene.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/scenes/collectionScene.c')
-rw-r--r--src/scenes/collectionScene.c83
1 files changed, 80 insertions, 3 deletions
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 <dirent.h>
#include <raylib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#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;