#include "beatmapstore.h" #include "beatmap.h" #include "defines.h" #include "util.h" #include #include #include struct Osu_BeatmapStore* Osu_CreateBeatmapStore(const char* dataPath) { struct Osu_BeatmapStore* beatmaps = calloc(1, sizeof(struct Osu_BeatmapStore)); beatmaps->mutex = SDL_CreateMutex(); beatmaps->beatmapsLen = 0; SDL_asprintf(&beatmaps->basePath, "%s" OSU_PATHSEP "beatmaps", dataPath); if (SDL_GetPathInfo(beatmaps->basePath, NULL)) { SDL_SAFEASSN(beatmaps->loadWorker, SDL_CreateThread, &Osu_LoadBeatmapsWorker, "BeatmapLoader", beatmaps); } return beatmaps; } void Osu_DestroyBeatmapStore(struct Osu_BeatmapStore* beatmaps) { SDL_LockMutex(beatmaps->mutex); for (Uint32 i = 0; i < beatmaps->beatmapsLen; i++) { Osu_DestroyBeatmap(beatmaps->beatmaps[i]); } free(beatmaps->beatmaps); beatmaps->beatmaps = NULL; SDL_UnlockMutex(beatmaps->mutex); SDL_WaitThread(beatmaps->loadWorker, NULL); beatmaps->loadWorker = NULL; SDL_DestroyMutex(beatmaps->mutex); free(beatmaps->basePath); free(beatmaps); } int Osu_LoadBeatmapsWorker(void* userdata) { struct Osu_BeatmapStore* beatmaps = userdata; int filesCount; char** files = SDL_GlobDirectory(beatmaps->basePath, "*" OSU_PATHSEP "*.osu", SDL_GLOB_CASEINSENSITIVE, &filesCount); if (!files) { return 0; } size_t filesLen = filesCount; // Why does SDL return this as an int!? beatmaps->beatmaps = calloc(filesCount, sizeof(struct Osu_Beatmap*)); char filepath[512]; for (size_t i = 0; i < filesLen; i++) { sprintf(filepath, "%s" OSU_PATHSEP "%s", beatmaps->basePath, files[i]); struct Osu_Beatmap* beatmap = Osu_LoadBeatmap(filepath); if (!beatmap) { continue; } SDL_LockMutex(beatmaps->mutex); // If beatmaps no longer exists then loading was canceled. if (!beatmaps->beatmaps) { Osu_DestroyBeatmap(beatmap); break; } beatmaps->beatmaps[beatmaps->beatmapsLen] = beatmap; beatmaps->beatmapsLen++; SDL_UnlockMutex(beatmaps->mutex); } SDL_LockMutex(beatmaps->mutex); if (beatmaps->beatmaps && beatmaps->beatmapsLen < filesLen) { beatmaps->beatmaps = realloc(beatmaps->beatmaps, sizeof(struct Osu_Beatmap*) * beatmaps->beatmapsLen); } beatmaps->finishedLoading = true; SDL_UnlockMutex(beatmaps->mutex); SDL_free(files); return 0; }