From 6ff4c88aa7e951e21466d1f44ba5e9130bbca41b Mon Sep 17 00:00:00 2001 From: Emily Boudreaux Date: Sat, 6 Dec 2025 11:04:55 -0500 Subject: [PATCH] feat(reflection): Bring in new libconfig This version of fourdst (v0.9.14) brings in the version libconfig which includes reflection based config filed (v2.0.2). This is a breaking change as any code which used versions of libconfig < v2.0.0 will no longer function when linked against this version of fourdst --- .gitignore | 4 ++ build-config/libconfig/meson.build | 3 -- build-python/meson.build | 3 +- meson.build | 4 +- src-pybind/bindings.cpp | 6 +-- src-pybind/config/bindings.cpp | 60 ++++++------------------------ src-pybind/config/bindings.h | 23 +++++++++++- src-pybind/meson.build | 4 -- subprojects/libconfig.wrap | 2 +- 9 files changed, 43 insertions(+), 66 deletions(-) delete mode 100644 src-pybind/meson.build diff --git a/.gitignore b/.gitignore index c759f8f..9f334bb 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,8 @@ subprojects/libplugin/ subprojects/minizip-ng-* subprojects/.wraplock subprojects/openssl-* +subprojects/glaze/ +subprojects/tomlplusplus-*/ *.csv *.dot @@ -87,6 +89,8 @@ quill.wrap yaml-cpp.wrap minizip-ng.wrap openssl.wrap +glaze.wrap +tomlplusplus.wrap .vscode/ diff --git a/build-config/libconfig/meson.build b/build-config/libconfig/meson.build index 7de01a1..8c7ec5d 100644 --- a/build-config/libconfig/meson.build +++ b/build-config/libconfig/meson.build @@ -5,6 +5,3 @@ config_p = subproject('libconfig', 'build_examples=false' ]) config_dep = config_p.get_variable('config_dep') -libconfig = config_p.get_variable('libconfig') - -alias_target('build-libconfig', libconfig) diff --git a/build-python/meson.build b/build-python/meson.build index cd24957..4d07bd7 100644 --- a/build-python/meson.build +++ b/build-python/meson.build @@ -1,8 +1,7 @@ -# --- Python Extension Setup --- py_installation = import('python').find_installation('python3', pure: false) py_mod = py_installation.extension_module( - '_phys', # Name of the generated .so/.pyd file (without extension) + '_phys', sources: [ meson.project_source_root() + '/src-pybind/bindings.cpp', meson.project_source_root() + '/src-pybind/composition/bindings.cpp', diff --git a/meson.build b/meson.build index a32500d..24a26f3 100644 --- a/meson.build +++ b/meson.build @@ -1,4 +1,4 @@ -project('fourdst', 'cpp', version: 'v0.9.13', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0') +project('fourdst', 'cpp', version: 'v0.9.14', default_options: ['cpp_std=c++23'], meson_version: '>=1.5.0') add_project_arguments('-fvisibility=default', language: 'cpp') @@ -9,7 +9,5 @@ subdir('build-config') # Configure python bindings if get_option('build_python') subdir('build-python') - - subdir('src-pybind') endif diff --git a/src-pybind/bindings.cpp b/src-pybind/bindings.cpp index 6faf1ed..f1d7b38 100644 --- a/src-pybind/bindings.cpp +++ b/src-pybind/bindings.cpp @@ -21,6 +21,6 @@ PYBIND11_MODULE(_phys, m) { auto constMod = m.def_submodule("constants", "Constants-module bindings"); register_const_bindings(constMod); - auto configMod = m.def_submodule("config", "Configuration-module bindings"); - register_config_bindings(configMod); -} + const auto configMod = m.def_submodule("config", "Configuration-module bindings"); + register_config_enums(configMod); +} \ No newline at end of file diff --git a/src-pybind/config/bindings.cpp b/src-pybind/config/bindings.cpp index be7e92c..ea1c18a 100644 --- a/src-pybind/config/bindings.cpp +++ b/src-pybind/config/bindings.cpp @@ -1,55 +1,17 @@ -#include -#include // Needed for vectors, maps, sets, strings -#include // Needed for binding std::vector, std::map etc if needed directly - -#include #include "bindings.h" +#include #include "fourdst/config/config.h" -namespace py = pybind11; +void register_config_enums(const pybind11::module_& m) { + using namespace fourdst::config; + pybind11::enum_(m, "ConfigState") + .value("DEFAULT", ConfigState::DEFAULT) + .value("LOADED_FROM_FILE", ConfigState::LOADED_FROM_FILE) + .export_values(); -// Helper function template for binding Config::get -template -void def_config_get(py::module &m) { - m.def("get", - [](const std::string &key, T defaultValue) { - return fourdst::config::Config::getInstance().get(key, defaultValue); - }, - py::arg("key"), py::arg("defaultValue"), - "Get configuration value (type inferred from default)"); -} - -void register_config_bindings(pybind11::module &config_submodule) { - def_config_get(config_submodule); - def_config_get(config_submodule); - def_config_get(config_submodule); - def_config_get(config_submodule); - - config_submodule.def("loadConfig", - [](const std::string& configFilePath) { - return fourdst::config::Config::getInstance().loadConfig(configFilePath); - }, - py::arg("configFilePath"), - "Load configuration from a YAML file."); - - config_submodule.def("has", - [](const std::string &key) { - return fourdst::config::Config::getInstance().has(key); - }, - py::arg("key"), - "Check if a key exists in the configuration."); - - config_submodule.def("keys", - []() { - return py::cast(fourdst::config::Config::getInstance().keys()); - }, - "Get a list of all configuration keys."); - - config_submodule.def("__repr__", - []() { - std::ostringstream oss; - oss << fourdst::config::Config::getInstance(); // Use the existing operator<< - return std::string("\n") + oss.str(); - }); + pybind11::enum_(m, "RootNameLoadPolicy") + .value("FROM_FILE", RootNameLoadPolicy::FROM_FILE) + .value("KEEP_CURRENT", RootNameLoadPolicy::KEEP_CURRENT) + .export_values(); } diff --git a/src-pybind/config/bindings.h b/src-pybind/config/bindings.h index 30fcae7..671eaf9 100644 --- a/src-pybind/config/bindings.h +++ b/src-pybind/config/bindings.h @@ -1,5 +1,26 @@ #pragma once #include +#include "fourdst/config/config.h" -void register_config_bindings(pybind11::module &config_submodule); +#include +#include + +void register_config_enums(const pybind11::module_& m); + +template +pybind11::class_ bind_config_specialization(pybind11::module_& m , const std::string& name) { + return pybind11::class_(m, name.c_str()) + .def(pybind11::init<>()) + .def("load", &ConfigType::load, pybind11::arg("file_path"), "Load configuration from a file.") + .def("save", &ConfigType::save, pybind11::arg("file_path") = "config_output.toml", "Save configuration to a file.") + .def("save_schema", &ConfigType::save_schema, pybind11::arg("directory") = ".", "Save the configuration schema to a directory.") + .def("get_state", &ConfigType::get_state, "Get the current state of the configuration.") + .def("describe_state", &ConfigType::describe_state, "Get the current state of the configuration.") + .def("__repr__", + [](const ConfigType &cfg) -> std::string { + return std::format("{}", cfg); + } + ); + +} \ No newline at end of file diff --git a/src-pybind/meson.build b/src-pybind/meson.build deleted file mode 100644 index 3181abe..0000000 --- a/src-pybind/meson.build +++ /dev/null @@ -1,4 +0,0 @@ -subdir('composition') -subdir('constants') -subdir('config') - diff --git a/subprojects/libconfig.wrap b/subprojects/libconfig.wrap index 562efc5..7a63091 100644 --- a/subprojects/libconfig.wrap +++ b/subprojects/libconfig.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://github.com/4D-STAR/libconfig.git -revision = v1.1.4 +revision = v2.0.2 depth = 1