diff --git a/Apps/Demos/phong/CMakeLists.txt b/Apps/Demos/phong/CMakeLists.txt index 309273e..6c477c3 100644 --- a/Apps/Demos/phong/CMakeLists.txt +++ b/Apps/Demos/phong/CMakeLists.txt @@ -11,7 +11,6 @@ PRIVATE target_link_libraries(phong PRIVATE elemental IOCore - nlohmann_json ) diff --git a/Apps/Demos/phong/GameSettings.hpp b/Apps/Demos/phong/GameSettings.hpp index af4e14e..b4e2814 100644 --- a/Apps/Demos/phong/GameSettings.hpp +++ b/Apps/Demos/phong/GameSettings.hpp @@ -11,6 +11,7 @@ #include "types/rendering.hpp" +#include "IOCore/util/serialization.hpp" #include "IOCore/util/toml.hpp" #include @@ -20,8 +21,7 @@ namespace elemental { struct GameSettings { RendererSettings renderer_settings; - // DEFINE_TOML_FIELDS(renderer_settings); - NLOHMANN_DEFINE_TYPE_INTRUSIVE(GameSettings, renderer_settings); + JSON_SERIALIZABLE(GameSettings, renderer_settings); }; } // namespace elemental diff --git a/Apps/Demos/phong/Phong.cpp b/Apps/Demos/phong/Phong.cpp index 1106133..c1c4936 100644 --- a/Apps/Demos/phong/Phong.cpp +++ b/Apps/Demos/phong/Phong.cpp @@ -15,7 +15,6 @@ #include "util/debug.hpp" #include "IOCore/Exception.hpp" -#include "JsonConfigFile.hpp" #include "LoopRegulator.hpp" #include "SdlEventSource.hpp" #include "SdlRenderer.hpp" diff --git a/Apps/Demos/phong/Phong.hpp b/Apps/Demos/phong/Phong.hpp index 2db0d52..33db67e 100644 --- a/Apps/Demos/phong/Phong.hpp +++ b/Apps/Demos/phong/Phong.hpp @@ -14,7 +14,9 @@ #include "IObserver.hpp" #include "IOCore/Application.hpp" -#include "JsonConfigFile.hpp" +#include "IOCore/JsonConfigFile.hpp" + +// #include "JsonConfigFile.hpp" #include "LoopRegulator.hpp" #include "Observable.hpp" #include "Singleton.hpp" @@ -65,7 +67,7 @@ class Phong SdlEventSource& event_emitter; GameSettings settings; - configuration::JsonConfigFile settings_file; + IOCore::JsonConfigFile settings_file; }; } // namespace elemental diff --git a/Doxyfile b/Doxyfile index cfff797..1d3c311 100644 --- a/Doxyfile +++ b/Doxyfile @@ -914,9 +914,9 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = src/ \ - include/ \ - demo/ +INPUT = Modules/elemental/ \ + Apps/ \ + Tests # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/Modules/elemental/CMakeLists.txt b/Modules/elemental/CMakeLists.txt index 6a01f63..4e4fe96 100644 --- a/Modules/elemental/CMakeLists.txt +++ b/Modules/elemental/CMakeLists.txt @@ -1,6 +1,5 @@ add_library(elemental OBJECT - JsonConfigFile.cpp LoopRegulator.cpp Observable.cpp SdlRenderer.cpp diff --git a/Modules/elemental/JsonConfigFile.hpp b/Modules/elemental/JsonConfigFile.hpp deleted file mode 100644 index 3205825..0000000 --- a/Modules/elemental/JsonConfigFile.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* JsonConfigFile.hpp - * Copyright © 2024 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#pragma once - -#include "types.hpp" - -#include "IOCore/FileResource.hpp" -#include - -#include - -namespace elemental::configuration { - -using IOCore::CreateDirs; -using IOCore::FileResource; - -class JsonConfigFile : public FileResource { - public: - JsonConfigFile( - const std::filesystem::path& file_path, - CreateDirs mode = CreateDirs::Disable - ); - ~JsonConfigFile() override; - - auto read() -> nlohmann::json&; - void write(); - - template - [[nodiscard]] auto get() const -> TData - { - return config_json.get(); - } - - template - void set(const T_& value) - { - config_json = value; - } - - auto jsonDataRef() -> nlohmann::json& { return this->config_json; }; - - protected: - nlohmann::json config_json; -}; -} // namespace elemental::configuration - -// clang-format off -// vim: set foldmethod=syntax foldlevel=1 foldminlines=12 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/Modules/elemental/SdlRenderer.cpp b/Modules/elemental/SdlRenderer.cpp index 99cf310..3a61beb 100644 --- a/Modules/elemental/SdlRenderer.cpp +++ b/Modules/elemental/SdlRenderer.cpp @@ -7,18 +7,17 @@ * obtain one at https://mozilla.org/MPL/2.0/. */ -#include -#include - -#include "IOCore/Exception.hpp" -#include "IRenderer.hpp" #include "SdlRenderer.hpp" -#include "util/debug.hpp" - #include "types/input.hpp" #include "types/rendering.hpp" +#include "util/debug.hpp" +#include + +#include +#include +#include #include #include @@ -53,10 +52,11 @@ void SdlRenderer::init(RendererSettings& settings) IMG_Init( IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF | IMG_INIT_WEBP )) { - error_buffer.str(""); - error_buffer << "Could not initialize SDL_Image: IMG_INIT() == 0" - << std::flush; - throw IOCore::Exception(error_buffer.str()); + HANDLE_SDL_ERROR(fmt::format( + "Could not initialize SDL_Image: {}", + IMG_GetError() + ) + .c_str()); } int window_xpos, window_ypos, window_width, window_height, res_width, res_height; diff --git a/Modules/elemental/types/rendering.hpp b/Modules/elemental/types/rendering.hpp index 6b4d28b..7f52d50 100644 --- a/Modules/elemental/types/rendering.hpp +++ b/Modules/elemental/types/rendering.hpp @@ -9,7 +9,7 @@ #pragma once -#include "util/serialization.hpp" +#include "IOCore/util/serialization.hpp" #include #include @@ -18,13 +18,15 @@ namespace elemental { struct Point { uint32_t x, y; - SERIALIZABLE(Point, x, y); + JSON_SERIALIZABLE(Point, x, y); + TOML_SERIALIZABLE(Point, x, y); }; using Position2D = Point; struct Area { uint32_t width, height; - SERIALIZABLE(Area, width, height); + JSON_SERIALIZABLE(Area, width, height); + TOML_SERIALIZABLE(Area, width, height); }; using Resolution = Area; @@ -38,7 +40,8 @@ struct Rectangle { uint32_t& width = size.width; uint32_t& height = size.height; - SERIALIZABLE(Rectangle, position, size); + JSON_SERIALIZABLE(Rectangle, position, size); + // TOML_SERIALIZABLE(Rectangle, position); }; enum class WindowMode { @@ -46,23 +49,12 @@ enum class WindowMode { Borderless = 0x01, Fullscreen = 0x11, }; -// NOLINTNEXTLINE(readability-identifier-length) -SERIALIZABLE_ENUM( - WindowMode, { { WindowMode::Windowed, "windowed" }, - { WindowMode::Borderless, "borderless" }, - { WindowMode::Fullscreen, "fullscreen" } } -); -enum class WindowPlacement : int - -{ - Manual = 0x00, - Centered = 0x01 -}; -// NOLINTNEXTLINE(readability-identifier-length) -SERIALIZABLE_ENUM( - WindowPlacement, { { WindowPlacement::Manual, "manual" }, - { WindowPlacement::Centered, "centered" } } +JSON_SERIALIZABLE_ENUM( // NOLINT(readability-identifier-length) + WindowMode, { { WindowMode::Windowed, "Windowed" }, + { WindowMode::Borderless, "Borderless" }, + { WindowMode::Fullscreen, "Fullscreen" } } ); +enum class WindowPlacement : int { Manual = 0x00, Centered = 0x01 }; struct WindowParameters { std::string title; @@ -71,14 +63,17 @@ struct WindowParameters { Position2D position; Area size; - SERIALIZABLE(WindowParameters, title, mode, placement, position, size); + JSON_SERIALIZABLE( + WindowParameters, title, mode, placement, position, size + ); }; struct RendererSettings { WindowParameters window; Resolution resolution; + int field1; - SERIALIZABLE(RendererSettings, window, resolution); + JSON_SERIALIZABLE(RendererSettings, window, resolution, field1); }; } // namespace elemental diff --git a/Modules/elemental/util/serialization.hpp b/Modules/elemental/util/serialization.hpp deleted file mode 100644 index e74c3b6..0000000 --- a/Modules/elemental/util/serialization.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* serialization.hpp - * Copyright © 2024 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ -#pragma once - -#include - -/* NOLINTBEGIN(readability-identifier-length) */ - -#define SERIALIZABLE(...) NLOHMANN_DEFINE_TYPE_INTRUSIVE(__VA_ARGS__) -#define SERIALIZABLE_ENUM(...) NLOHMANN_JSON_SERIALIZE_ENUM(__VA_ARGS__) - -/* NOLINTEND */ - -// clang-format off -// vim: set foldmethod=syntax foldminlines=10 textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen : diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4540d78..41cd168 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -8,9 +8,7 @@ add_executable(test-runner Observable.test.cpp sdl/SdlEventSource.test.cpp SDL_Memory.test.cpp - JsonConfigFile.test.cpp paths.test.cpp - ) set_target_properties(test-runner diff --git a/Tests/JsonConfigFile.test.cpp b/Tests/JsonConfigFile.test.cpp deleted file mode 100644 index 2896d08..0000000 --- a/Tests/JsonConfigFile.test.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* JsonConfigFile.test.cpp - * } - * Copyright © 2024 Saul D. Beniquez - * License: Mozilla Public License v. 2.0 - * - * This Source Code Form is subject to the terms of the Mozilla Public License, - * v.2.0. If a copy of the MPL was not distributed with this file, You can - * obtain one at https://mozilla.org/MPL/2.0/. - */ - -#include "JsonConfigFile.hpp" -#include "IOCore/Exception.hpp" - -#include "sys/debuginfo.hpp" -#include "util/debug.hpp" - -#include "test-utils/common.hpp" - -#include -#include -#include -#include - -#include - -using namespace elemental; -using namespace elemental::configuration; - -namespace fs = std::filesystem; - -constexpr c::const_string kINPUT_FILE_PATH = "/tmp/test_config.json"; -constexpr c::const_string kBADFILE_PATH = "/tmp/test_bad_config.json"; -constexpr c::const_string kNON_EXISTENT_PATH = "/hades/tmp/dne/file.json"; - -BEGIN_TEST_SUITE("elemental::JsonConfigFile") -{ - namespace { // Test fixtures - struct SampleFileGenerator { - SampleFileGenerator() - { - if (!fs::exists(kINPUT_FILE_PATH)) { - std::ofstream new_file( - kINPUT_FILE_PATH, - std::ios::out | std::ios::trunc - ); - new_file - << R"({"key1": "value1", "key2": "value2"})" - << std::endl; - new_file.close(); - } - } - ~SampleFileGenerator() - { - try { - if (fs::exists(kINPUT_FILE_PATH)) { - fs::remove(kINPUT_FILE_PATH); - } - } catch (std::exception& e) { - DBG_PRINT(e.what()); - } - } - }; - using TestFixture = SampleFileGenerator; - } // anonymous namespace - - TEST("elemental::nlohmann::json is serializablable like " - "std::map") - { - IOCore::Dictionary test_data; - nlohmann::json jsonified; - - test_data["one"] = "1"; - test_data["resolution"] = "1280x720"; - test_data["Hello"] = "world"; - - jsonified = test_data; - - REQUIRE(test_data["one"] == jsonified["one"].get()); - REQUIRE( - test_data["resolution"] == - jsonified["resolution"].get() - ); - REQUIRE( - test_data["Hello"] == jsonified["Hello"].get() - ); - } - - FIXTURE_TEST("JsonConfigFile construction") - { - SECTION("JsonConfigFile w/ valid path") - { - auto config = JsonConfigFile(kINPUT_FILE_PATH); - auto& config_data = config.jsonDataRef(); - - REQUIRE(config_data.empty()); - } - SECTION("JsonConfigFile w/ invalid path throws exception") - { - - REQUIRE_THROWS_AS( - JsonConfigFile(kNON_EXISTENT_PATH), - IOCore::UnreachablePathException - ); - } - } - FIXTURE_TEST("JsonConfigFile::Read") - { - auto config_file = JsonConfigFile(kINPUT_FILE_PATH); - auto& json_data = config_file.jsonDataRef(); - - SECTION("JsonConfigFile::Read w/ valid file") - { - config_file.read(); - REQUIRE_FALSE(json_data.empty()); - REQUIRE(json_data.size() == 2); - - REQUIRE(json_data["key1"] == "value1"); - REQUIRE(json_data["key2"] == "value2"); - } - SECTION("JsonConfigFile::Read w/ bad file throws exception") - { - if (!fs::exists(kBADFILE_PATH)) { - std::ofstream fileout(kBADFILE_PATH); - fileout << R"({"Hello World"})" << std::endl; - fileout.close(); - } - REQUIRE_THROWS_AS( - [&]() { - auto bad_config = - JsonConfigFile(kBADFILE_PATH); - - bad_config.read(); - }(), - IOCore::Exception - ); - } - if (fs::exists(kBADFILE_PATH)) { - fs::remove(kBADFILE_PATH); - } - } - TEST("JsonConfigFile::Write()") - { - SECTION("Create File and Read It back In") - { - auto config_file = JsonConfigFile(kINPUT_FILE_PATH); - auto& test_data = config_file.jsonDataRef(); - - test_data["one"] = "1"; - test_data["resolution"] = "1280x720"; - test_data["Hello"] = "world"; - - config_file.write(); - - std::ifstream resulting_file(kINPUT_FILE_PATH); - nlohmann::json jobject; - - resulting_file >> jobject; - auto written_data = - jobject.get>(); - - REQUIRE( - written_data["one"] == - test_data["one"].get() - ); - REQUIRE( - written_data["resolution"] == - test_data["resolution"].get() - ); - REQUIRE( - written_data["Hello"] == - test_data["Hello"].get() - ); - } - fs::remove(kINPUT_FILE_PATH); - } - - FIXTURE_TEST( - "JsonConfigFile::Get() basically wraps nlohmann::json::get()" - ) - { - auto config_file = JsonConfigFile(kINPUT_FILE_PATH); - auto& json_data = config_file.jsonDataRef(); - - config_file.read(); - auto obtained_data = - config_file.get>(); - - REQUIRE(obtained_data["key1"] == "value1"); - REQUIRE(obtained_data["key2"] == "value2"); - } - FIXTURE_TEST( - "JsonConfigFile::Set() basically wraps nlohmann::json::operator=()" - ) - { - auto config_file = JsonConfigFile(kINPUT_FILE_PATH); - IOCore::Dictionary test_data; - - test_data["one"] = "1"; - test_data["resolution"] = "1280x720"; - test_data["Hello"] = "world"; - - config_file.set(test_data); - - auto& json_data = config_file.jsonDataRef(); - - REQUIRE(json_data["one"] == test_data["one"]); - REQUIRE(json_data["resolution"] == test_data["resolution"]); - REQUIRE(json_data["Hello"] == test_data["Hello"]); - } -} -// clang-format off -// vim: set foldmethod=syntax textwidth=80 ts=8 sts=0 sw=8 noexpandtab ft=cpp.doxygen :