Leaderboards system WIP

This commit is contained in:
Edgaru089 2024-04-30 13:11:53 +08:00
parent 47fa6b5b80
commit d0beff76fe
3 changed files with 146 additions and 0 deletions

77
leaderboards.c Normal file
View File

@ -0,0 +1,77 @@
#include "leaderboards.h"
#include "types.h"
#include "util/vector.h"
#include "util/tree.h"
#include "util/assert.h"
#include <string.h>
System_Leaderboards *lboard_NewSystem(App *super) {
System_Leaderboards *sys = zero_malloc(sizeof(System_Leaderboards));
sys->super = super;
sys->levelnames = vector_Create(sizeof(char *));
sys->records = vector_Create(sizeof(tree_Tree *));
return sys;
}
void lboard_DeleteSystem(System_Leaderboards *sys) {
// Free level names
for (int i = 0; i < vector_Size(sys->levelnames); i++) {
char *str = *(char **)vector_At(sys->levelnames, i);
free(str);
}
vector_Destroy(sys->levelnames);
// Free records
for (int i = 0; i < vector_Size(sys->records); i++) {
tree_Tree *tree = *(tree_Tree **)vector_At(sys->levelnames, i);
for (tree_Node *node = tree_FirstNode(tree); node != NULL; node = tree_Node_Next(node)) {
vector_Vector *names = *(vector_Vector **)node->data;
if (names) {
for (int j = 0; j < vector_Size(names); j++)
free(*(void **)vector_At(names, j));
vector_Destroy(names);
}
}
tree_Destroy(tree);
}
vector_Destroy(sys->records);
free(sys);
}
int lboard_FindLevel(System_Leaderboards *sys, const char *level) {
for (int i = 0; i < vector_Size(sys->levelnames); i++) {
char *str = *(char **)vector_At(sys->levelnames, i);
if (strcmp(str, level) == 0)
return i;
}
return -1;
}
void lboard_Insert(System_Leaderboards *sys, const char *level, uintptr_t time_millisec, const char *name) {
int indice = lboard_FindLevel(sys, level);
if (indice == -1) {
// Append a new one
char *level_copy = copy_malloc(level);
tree_Tree *empty_tree = tree_Create(sizeof(vector_Vector *));
vector_Push(sys->levelnames, level_copy);
vector_Push(sys->records, &empty_tree);
ASSERT(vector_Size(sys->levelnames) == vector_Size(sys->records));
indice = vector_Size(sys->levelnames) - 1;
}
tree_Tree *tree = *(tree_Tree **)vector_At(sys->records, indice);
// Insert or find this node
bool added;
tree_Node *node = tree_Insert(tree, time_millisec, &added);
if (added)
// Brand new node, create a new vector of names
*((vector_Vector **)node->data) = vector_Create(sizeof(char *));
// Insert this name
char *name_copy = copy_malloc(name);
vector_Push(*(vector_Vector **)node->data, &name_copy);
}

42
leaderboards.h Normal file
View File

@ -0,0 +1,42 @@
#pragma once
#include "util/vector.h"
#include "util/tree.h"
#include "types.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _App App;
// Leaderboards keep track of level-gametime-username records in leaderboards.txt.
typedef struct {
App *super;
vector_Vector *levelnames; // vector of allocated char* strings
vector_Vector *records; // vector of tree_Tree* of gametime(milliseconds)->vector of allocated char* strings
} System_Leaderboards;
System_Leaderboards *lboard_NewSystem(App *super);
void lboard_DeleteSystem(System_Leaderboards *sys);
// Find the indice at which this level is located
// Returns -1 if not found
int lboard_FindLevel(System_Leaderboards *sys, const char *level);
// Insert a record.
void lboard_Insert(System_Leaderboards *sys, const char *level, uintptr_t time_millisec, const char *name);
// This should only be called on an empty (newly created) leaderboard.
void lboard_LoadFromFile(System_Leaderboards *sys, const char *filename);
void lboard_SaveToFile(System_Leaderboards *sys, const char *filename);
#ifdef __cplusplus
}
#endif

27
leaderboards_file.c Normal file
View File

@ -0,0 +1,27 @@
#include "leaderboards.h"
#include <stdio.h>
void lboard_LoadFromFile(System_Leaderboards *sys, const char *filename) {
FILE *f = fopen(filename, "r");
if (!f) {
WARN("failed to open file\"%s\"", filename);
return;
}
// Read every line
char linebuf[512];
memset(linebuf, 0, sizeof(linebuf));
while (!feof(f) && fgets(linebuf, sizeof(linebuf), f)) {
while (linebuf[strlen(linebuf) - 1] == '\n')
linebuf[strlen(linebuf) - 1] = '\0';
// Skip empty lines
if (strlen(linebuf) == 0)
continue;
}
}
void lboard_SaveToFile(System_Leaderboards *sys, const char *filename) {
}