From b43cea390c0e0b552bb655757c8c6b123afb40d5 Mon Sep 17 00:00:00 2001
From: Leon Niklas Lux <leon-niklas.lux@informatik.hs-fulda.de>
Date: Mon, 3 Feb 2025 22:07:35 +0100
Subject: [PATCH] Konfigurationsmanagement mit CRTP und Boost Property Trees

---
 editor/CMakeLists.txt        | 14 ++++++++++--
 editor/src/Config.cpp        | 21 ++++++++++++++++++
 editor/src/Config.hpp        | 16 ++++++++++++++
 editor/src/ConfigSection.hpp | 21 ++++++++++++++++++
 editor/src/ConfigSection.tcc | 16 ++++++++++++++
 editor/src/ObjectConfig.cpp  | 41 ++++++++++++++++++++++++++++++++++++
 editor/src/ObjectConfig.hpp  | 31 +++++++++++++++++++++++++++
 editor/src/TileConfig.cpp    | 38 +++++++++++++++++++++++++++++++++
 editor/src/TileConfig.hpp    | 31 +++++++++++++++++++++++++++
 9 files changed, 227 insertions(+), 2 deletions(-)
 create mode 100644 editor/src/Config.cpp
 create mode 100644 editor/src/Config.hpp
 create mode 100644 editor/src/ConfigSection.hpp
 create mode 100644 editor/src/ConfigSection.tcc
 create mode 100644 editor/src/ObjectConfig.cpp
 create mode 100644 editor/src/ObjectConfig.hpp
 create mode 100644 editor/src/TileConfig.cpp
 create mode 100644 editor/src/TileConfig.hpp

diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt
index ddda5b2..003998e 100644
--- a/editor/CMakeLists.txt
+++ b/editor/CMakeLists.txt
@@ -13,7 +13,11 @@ set(EDITOR_SOURCES src/main.cpp src/EditorApp.cpp
         src/TileBar.hpp
         src/GridItem.cpp
         src/GridItem.hpp
-        src/HDF5Handler.cpp)
+        src/HDF5Handler.cpp
+        src/ConfigSection.hpp
+        src/TileConfig.cpp
+        src/ObjectConfig.cpp
+        src/Config.cpp)
 
 set(CMAKE_AUTOMOC ON)
 
@@ -32,7 +36,13 @@ endif()
 set(Qt6_DIR "/usr/lib64/cmake/Qt6")
 find_package(Qt6 REQUIRED COMPONENTS Widgets)
 
+find_package(Boost CONFIG)
+if(Boost_FOUND)
+    message(STATUS "Boost found: ${Boost_INCLUDE_DIRS}")
+endif()
+
 add_executable(Editor ${EDITOR_SOURCES})
 
 target_link_libraries(Editor PRIVATE Qt6::Widgets Liblvl)
-target_include_directories(Editor PRIVATE ${PROJECT_SOURCE_DIR}/../Liblvl/include)
\ No newline at end of file
+target_include_directories(Editor PRIVATE ${PROJECT_SOURCE_DIR}/../Liblvl/include)
+target_include_directories(Editor PRIVATE ${Boost_INCLUDE_DIRS})
\ No newline at end of file
diff --git a/editor/src/Config.cpp b/editor/src/Config.cpp
new file mode 100644
index 0000000..f09bf98
--- /dev/null
+++ b/editor/src/Config.cpp
@@ -0,0 +1,21 @@
+//
+// Created by llux on 02.02.25.
+//
+#include "Config.hpp"
+
+namespace editor
+{
+    void Config::load(const pt::ptree& tree)
+    {
+        // Call load for each section explicitly
+        TileConfig::load(tree);
+        ObjectConfig::load(tree);
+    }
+
+    void Config::save(pt::ptree& tree)
+    {
+        // Call save for each section explicitly
+        TileConfig::save(tree);
+        ObjectConfig::save(tree);
+    }
+}
\ No newline at end of file
diff --git a/editor/src/Config.hpp b/editor/src/Config.hpp
new file mode 100644
index 0000000..05150ff
--- /dev/null
+++ b/editor/src/Config.hpp
@@ -0,0 +1,16 @@
+//
+// Created by llux on 02.02.25.
+//
+#pragma once
+#include "ObjectConfig.hpp"
+#include "TileConfig.hpp"
+
+namespace editor
+{
+class Config : public TileConfig, public ObjectConfig
+{
+  public:
+    void load(const pt::ptree &tree);
+    void save(pt::ptree &tree);
+};
+} // namespace editor
\ No newline at end of file
diff --git a/editor/src/ConfigSection.hpp b/editor/src/ConfigSection.hpp
new file mode 100644
index 0000000..7ae638c
--- /dev/null
+++ b/editor/src/ConfigSection.hpp
@@ -0,0 +1,21 @@
+//
+// Created by llux on 02.02.25.
+//
+#pragma once
+#include <boost/property_tree/ptree.hpp>
+
+namespace editor
+{
+
+namespace pt = boost::property_tree;
+
+template <typename Derived> class ConfigSection
+{
+  public:
+    void load(const pt::ptree &tree);
+    void save(pt::ptree &tree);
+};
+
+} // namespace editor
+
+#include "ConfigSection.tcc"
\ No newline at end of file
diff --git a/editor/src/ConfigSection.tcc b/editor/src/ConfigSection.tcc
new file mode 100644
index 0000000..0d34483
--- /dev/null
+++ b/editor/src/ConfigSection.tcc
@@ -0,0 +1,16 @@
+namespace editor
+{
+
+template<typename Derived>
+void ConfigSection<Derived>::load(const pt::ptree &tree)
+{
+    static_cast<Derived*>(this)->loadImpl(tree);
+}
+
+template<typename Derived>
+void ConfigSection<Derived>::save(pt::ptree &tree)
+{
+    static_cast<Derived*>(this)->saveImpl(tree);
+}
+
+}
diff --git a/editor/src/ObjectConfig.cpp b/editor/src/ObjectConfig.cpp
new file mode 100644
index 0000000..606d9e2
--- /dev/null
+++ b/editor/src/ObjectConfig.cpp
@@ -0,0 +1,41 @@
+//
+// Created by llux on 02.02.25.
+//
+//
+// Created by llux on 02.02.25.
+//
+#include "ObjectConfig.hpp"
+
+namespace editor
+{
+
+    void ObjectConfig::loadImpl(const pt::ptree &tree)
+    {
+        for (const auto&[fst, snd] : tree.get_child("config.objects"))
+        {
+            Object obj;
+            obj.id = snd.get<int32_t>("id");
+            obj.name = snd.get<std::string>("name");
+            m_Objects.push_back(obj);
+        }
+    }
+
+    void ObjectConfig::saveImpl(pt::ptree &tree)
+    {
+        pt::ptree objectNodes;
+        for (const auto& tile : m_Objects)
+        {
+            pt::ptree objectNode;
+            objectNode.put("id", tile.id);
+            objectNode.put("name", tile.name);
+            objectNodes.push_back(std::make_pair("", objectNode));
+        }
+        tree.add_child("config.objects", objectNodes);
+    }
+
+    const std::vector<ObjectConfig::Object>& ObjectConfig::getObjects() const
+    {
+        return m_Objects;
+    }
+
+}
\ No newline at end of file
diff --git a/editor/src/ObjectConfig.hpp b/editor/src/ObjectConfig.hpp
new file mode 100644
index 0000000..ecfa671
--- /dev/null
+++ b/editor/src/ObjectConfig.hpp
@@ -0,0 +1,31 @@
+//
+// Created by llux on 02.02.25.
+//
+#pragma once
+#include "ConfigSection.hpp"
+#include <boost/property_tree/ptree.hpp>
+
+namespace editor
+{
+
+namespace pt = boost::property_tree;
+
+class ObjectConfig : public ConfigSection<ObjectConfig>
+{
+  public:
+    struct Object
+    {
+        int32_t id;
+        std::string name;
+    };
+
+    void saveImpl(pt::ptree &tree);
+    void loadImpl(const pt::ptree &tree);
+
+    const std::vector<Object> &getObjects() const;
+
+  private:
+    std::vector<Object> m_Objects;
+};
+
+} // namespace editor
\ No newline at end of file
diff --git a/editor/src/TileConfig.cpp b/editor/src/TileConfig.cpp
new file mode 100644
index 0000000..774ad60
--- /dev/null
+++ b/editor/src/TileConfig.cpp
@@ -0,0 +1,38 @@
+//
+// Created by llux on 02.02.25.
+//
+#include "TileConfig.hpp"
+
+namespace editor
+{
+
+void TileConfig::loadImpl(const pt::ptree &tree)
+{
+    for (const auto&[fst, snd] : tree.get_child("config.tiles"))
+    {
+        Tile tile;
+        tile.id = snd.get<int32_t>("id");
+        tile.name = snd.get<std::string>("name");
+        m_Tiles.push_back(tile);
+    }
+}
+
+void TileConfig::saveImpl(pt::ptree &tree)
+{
+    pt::ptree tileNodes;
+    for (const auto& tile : m_Tiles)
+    {
+        pt::ptree tileNode;
+        tileNode.put("id", tile.id);
+        tileNode.put("name", tile.name);
+        tileNodes.push_back(std::make_pair("", tileNode));
+    }
+    tree.add_child("config.tiles", tileNodes);
+}
+
+const std::vector<TileConfig::Tile>& TileConfig::getTiles() const
+{
+    return m_Tiles;
+}
+
+}
\ No newline at end of file
diff --git a/editor/src/TileConfig.hpp b/editor/src/TileConfig.hpp
new file mode 100644
index 0000000..c77250d
--- /dev/null
+++ b/editor/src/TileConfig.hpp
@@ -0,0 +1,31 @@
+//
+// Created by llux on 02.02.25.
+//
+#pragma once
+#include "ConfigSection.hpp"
+#include <boost/property_tree/ptree.hpp>
+
+namespace editor
+{
+
+namespace pt = boost::property_tree;
+
+class TileConfig : public ConfigSection<TileConfig>
+{
+  public:
+    struct Tile
+    {
+        int32_t id;
+        std::string name;
+    };
+
+    void saveImpl(pt::ptree &tree);
+    void loadImpl(const pt::ptree &tree);
+
+    const std::vector<Tile> &getTiles() const;
+
+  private:
+    std::vector<Tile> m_Tiles;
+};
+
+} // namespace editor
\ No newline at end of file
-- 
GitLab