Skip to content

Commit

Permalink
Switch from libconfig++ to nlahmann/json
Browse files Browse the repository at this point in the history
  • Loading branch information
JustDoom committed Feb 13, 2025
1 parent febc919 commit 020540f
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 68 deletions.
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[submodule "dependencies/sdl"]
path = dependencies/sdl
url = [email protected]:libsdl-org/SDL.git
[submodule "dependencies/libconfig"]
path = dependencies/libconfig
url = https://github.com/hyperrealm/libconfig.git
[submodule "dependencies/sdl_ttf"]
path = dependencies/sdl_ttf
url = [email protected]:libsdl-org/SDL_ttf.git
[submodule "dependencies/json"]
path = dependencies/json
url = [email protected]:nlohmann/json.git
8 changes: 1 addition & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@ add_executable(8ChocChip)
add_subdirectory(dependencies)
add_subdirectory(src)

if(CMAKE_HOST_WIN32)
set(libname "libconfig")
else()
set(libname "config")
endif()

target_link_libraries(8ChocChip PRIVATE SDL3::SDL3 SDL3_ttf::SDL3_ttf ${libname}++)
target_link_libraries(8ChocChip PRIVATE nlohmann_json::nlohmann_json SDL3::SDL3 SDL3_ttf::SDL3_ttf)
target_compile_definitions(8ChocChip PUBLIC SDL_MAIN_USE_CALLBACKS)

set_target_properties(8ChocChip PROPERTIES
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
8ChocChip is an emulator for the Chip8 software that I am working on to learn the basics around emulation.

This uses SDL to handle graphics, input, audio and some other small things.
libconfig is used to manage config and save data files.
nlohmann/json is used to manage config and save data files.

## Features

Expand Down Expand Up @@ -74,4 +74,4 @@ Thanks to these two blogs that helped me through creating this emulator.
Currently, three libraries are being used
- [SDL](https://github.com/libsdl-org/SDL) - UI, graphics, input and sounds
- [SDL-ttf](https://github.com/libsdl-org/SDL_ttf) - Text fonts
- [libconfig](https://github.com/hyperrealm/libconfig) - Library to manage save data (like directories that hold ROMs) and possible future config files
- [nlohmann/json](https://github.com/nlohmann/json) - Library to manage save data (like directories that hold ROMs) and possible future config files
5 changes: 2 additions & 3 deletions dependencies/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
set(BUILD_EXAMPLES OFF CACHE BOOL "Disable examples for libconfig" FORCE)
set(BUILD_TESTS ON CACHE BOOL "Disable tests for libconfig" FORCE)
add_subdirectory(libconfig EXCLUDE_FROM_ALL)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(json)

if(SDL_VENDORED)
add_subdirectory(sdl EXCLUDE_FROM_ALL)
Expand Down
1 change: 1 addition & 0 deletions dependencies/json
Submodule json added at 606b63
1 change: 0 additions & 1 deletion dependencies/libconfig
Submodule libconfig deleted from 690342
70 changes: 30 additions & 40 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#include <iostream>
#include <unordered_map>

#include <nlohmann/json.hpp>
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <libconfig.h++>

#include "Timer.h"
#include "sdl/Emulator.h"
Expand Down Expand Up @@ -47,56 +47,46 @@ int main(int argc, char **argv) {
return 1;
}

std::string configFilePath = (std::filesystem::path(home) / ".8chocchip.cfg").string();
std::string configFilePath = (std::filesystem::path(home) / ".8chocchip.json").string();

std::vector<std::string> romDirectories;
std::unordered_map<std::string*, std::vector<std::string>> romFiles;

libconfig::Config config;
if (std::ifstream file(configFilePath, std::ios::binary | std::ios::ate); file.good()) {
config.readFile(configFilePath);

libconfig::Setting &settings = config.getRoot();
if (!settings.exists("directories")) {
settings.add("directories", libconfig::Setting::TypeArray);
if (std::ifstream file(configFilePath); file.good()) {
nlohmann::json json;
try {
json = nlohmann::json::parse(file);
} catch (const nlohmann::json::parse_error& error) {
// TODO: Better warning
std::cerr << "Unable to parse the config, please make sure it contains valid JSON";
return 1;
}

libconfig::Setting& directories = settings["directories"];
romDirectories.reserve(directories.getLength());
for (int i = 0; i < directories.getLength(); i++) {
libconfig::Setting &string = directories[i];
std::string directoryPath = string.c_str();

romDirectories.emplace_back(directoryPath);

for (const auto& romFile: std::filesystem::directory_iterator(directoryPath)) {
if (romFile.is_directory() || romFile.file_size() > 3584) {
file.close();
std::cout << json << std::endl;
if (json["directories"] != nullptr) {
for (const auto& directory : json["directories"]) {
if (std::ifstream file(directory); !file.good()) {
std::cerr << "Unable to find direcotry " << directory << std::endl;
continue;
}
romDirectories.emplace_back(directory.get<std::string>());

std::cout << "Processing file: " << romFile.path().c_str() << std::endl;
for (const auto& romFile: std::filesystem::directory_iterator(directory.get<std::string>())) {
if (romFile.is_directory() || romFile.file_size() > 3584) {
continue;
}

// Check if the rom directory doesn't exist in romFiles, then add it
if (romFiles.find(&romDirectories.back()) == romFiles.end()) {
romFiles.emplace(&romDirectories.back(), std::vector<std::string>());
}
std::cout << "Processing file: " << romFile.path().c_str() << std::endl;

// Add the file path to the romFiles entry
romFiles.find(&romDirectories.back())->second.emplace_back(romFile.path().string());
}
}
} else {
try {
config.getRoot().add("directories", libconfig::Setting::TypeList);
config.writeFile(configFilePath.c_str());
// Check if the rom directory doesn't exist in romFiles, then add it
if (romFiles.find(&romDirectories.back()) == romFiles.end()) {
romFiles.emplace(&romDirectories.back(), std::vector<std::string>());
}

std::cout << "Configuration file created successfully." << std::endl;
} catch (const libconfig::FileIOException &ioException) {
std::cerr << "I/O error while writing the configuration file." << std::endl;
return 1;
} catch (const libconfig::SettingException &settingException) {
std::cerr << "Setting error: " << settingException.what() << std::endl;
return 1;
// Add the file path to the romFiles entry
romFiles.find(&romDirectories.back())->second.emplace_back(romFile.path().string());
}
}
}
}

Expand Down
25 changes: 13 additions & 12 deletions src/sdl/MainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <libconfig.h++>
#include <nlohmann/json.hpp>
#include <nlohmann/json_fwd.hpp>

#include "../util/Constants.h"
#include "../util/MiscUtil.h"
#include "Emulator.h"
#include "ui/ScrollBox.h"
#include "../util/MiscUtil.h"
#include "../util/Constants.h"

#define WIDTH (64 * 15)
#define HEIGHT (32 * 15)
Expand Down Expand Up @@ -167,17 +168,18 @@ void MainMenu::callback(void* userdata, const char* const* directory, int filter
std::string directoryString = *directory;

SDL_LockMutex(instance->mutex);
libconfig::Config config;
config.readFile(instance->configFilePath);

libconfig::Setting &settings = config.getRoot();

if (!settings.exists("directories")) {
settings.add("directories", libconfig::Setting::TypeArray);
nlohmann::json json;
if (std::ifstream file(instance->configFilePath); file.good()) {
json = nlohmann::json::parse(file);
file.close();
}

libconfig::Setting &directories = settings["directories"];
directories.add(libconfig::Setting::TypeString) = directoryString;
json["directories"].push_back(directoryString);

std::ofstream fileWrite(instance->configFilePath);
fileWrite << json.dump(4);
fileWrite.close();

instance->romDirectories.emplace_back(directoryString);

Expand All @@ -204,7 +206,6 @@ void MainMenu::callback(void* userdata, const char* const* directory, int filter

instance->roms.emplace(file.path().string(), TextButton(0, 25.0f * instance->roms.size(), WIDTH, 25, text));
}
config.writeFile(instance->configFilePath);
instance->scrollRoms->setElements(instance->refreshRoms());

SDL_UnlockMutex(instance->mutex);
Expand Down

0 comments on commit 020540f

Please sign in to comment.