Add SongManager

This commit is contained in:
Joseph DiMaria 2026-01-31 00:55:01 -08:00
parent 741d2c9392
commit 5e52f308b3

View File

@ -1,6 +1,9 @@
#pragma once #pragma once
#include "engine/framework.h" #include "engine/framework.h"
#include "rapidjson/document.h"
#include "rapidjson/filereadstream.h"
#include "entities/song.h"
/** /**
* For when you want multiple of the same manager. * For when you want multiple of the same manager.
@ -214,4 +217,163 @@ public:
{ {
return static_cast<float>(width) / static_cast<float>(height); return static_cast<float>(width) / static_cast<float>(height);
} }
};
/**
* Manager for handling JSON files using RapidJSON.
*/
class JsonManager : public Manager
{
public:
std::unordered_map<std::string, rapidjson::Document> documents;
JsonManager() = default;
~JsonManager()
{
// Documents clean up automatically
}
/**
* Load a JSON file and parse it into a RapidJSON document.
*
* @param name The name to associate with the document.
* @param filename The filename of the JSON file to load.
* @return A reference to the loaded document.
*/
rapidjson::Document& load_json(const std::string& name, const std::string& filename)
{
// If already loaded, return existing document
if (documents.find(name) != documents.end())
{
return documents[name];
}
// Open the file
FILE* fp = fopen(filename.c_str(), "rb");
if (!fp)
{
fprintf(stderr, "Error: Could not open file %s\n", filename.c_str());
// Return an empty document on error
documents[name] = rapidjson::Document();
return documents[name];
}
// Create a buffer and stream
char readBuffer[65536];
rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));
// Parse the stream into a document
rapidjson::Document doc;
doc.ParseStream(is);
fclose(fp);
// Check for parse errors
if (doc.HasParseError())
{
fprintf(stderr, "JSON parse error in %s: %d\n", filename.c_str(), doc.GetParseError());
}
// Move document into map
documents[name] = std::move(doc);
return documents[name];
}
/**
* Get a JSON document by name.
*
* @param name The name of the document.
* @return A reference to the document.
*/
rapidjson::Document& get_document(const std::string& name)
{
return documents[name];
}
/**
* Check if a document exists.
*
* @param name The name of the document.
* @return True if the document exists, false otherwise.
*/
bool has_document(const std::string& name) const
{
return documents.find(name) != documents.end();
}
};
/**
* Manager for handling Song objects parsed from JSON files.
*/
class SongManager : public Manager
{
public:
std::unordered_map<std::string, Song> songs;
JsonManager* json_manager;
SongManager(JsonManager* json_mgr) : json_manager(json_mgr) {}
/**
* Load a song from a JSON file.
*
* @param name The name to associate with the song.
* @param filename The filename of the JSON file to load.
* @return A reference to the loaded song.
*/
Song& load_song(const std::string& name, const std::string& filename)
{
// If already loaded, return existing song
if (songs.find(name) != songs.end())
{
return songs[name];
}
// Load and parse the JSON file
rapidjson::Document& doc = json_manager->load_json(name, filename);
// Parse the document into a Song struct
Song song = parseSong(doc);
// Store the song
songs[name] = song;
return songs[name];
}
/**
* Get a song by name.
*
* @param name The name of the song.
* @return A reference to the song.
*/
Song& get_song(const std::string& name)
{
return songs[name];
}
/**
* Check if a song exists.
*
* @param name The name of the song.
* @return True if the song exists, false otherwise.
*/
bool has_song(const std::string& name) const
{
return songs.find(name) != songs.end();
}
/**
* Get the number of tracks in a song.
*
* @param name The name of the song.
* @return The number of tracks.
*/
size_t get_track_count(const std::string& name) const
{
auto it = songs.find(name);
if (it != songs.end())
{
return it->second.tracks.size();
}
return 0;
}
}; };