diff --git a/src/settings_window.cpp b/src/settings_window.cpp index 0a59978d..44681200 100644 --- a/src/settings_window.cpp +++ b/src/settings_window.cpp @@ -1,9 +1,105 @@ #include "./settings_window.hpp" +#include + #include #include -SettingsWindow::SettingsWindow(ConfigModelI& conf) : _conf(conf) { +#include + +#include + +template +void iterateMultMaps(FNCat&& fn_cat, MapTypes& ...map_types) { + // the iterators + std::tuple its{map_types.begin()...}; + + // assuming ever maps returned .begin() has a unique type + // TODO: use index instead + while ( ((std::get(its) != map_types.end()) || ...) ) { + // figure out current module and participants + + std::string_view current_module; + // find current_module + (( + current_module = ( + std::get(its) != map_types.end() && (current_module.empty() || current_module >= std::get(its)->first) + ) ? std::get(its)->first : current_module + ), ...); + + assert(!current_module.empty()); + + fn_cat( + current_module, + (( + std::get(its) != map_types.end() && + current_module == std::get(its)->first + ) ? std::get(its)->second : decltype(map_types.begin()->second){})... + ); + + // increment participanting iterators + (( + ( + std::get(its) != map_types.end() && + current_module == std::get(its)->first + ) ? void(++std::get(its)) : void(0) + ), ...); + } +} + +//template +//static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair, std::map>& cat_dat) { + //if (cat_dat.first.has_value()) { + //T tmp = cat_dat.first.value(); + ////if (ImGui::Checkbox(ccat.data(), &tmp)) { + ////conf.set(cmodule, ccat, tmp); + ////} + //} else if (!cat_dat.second.empty()) { + //ImGui::Text("uhhh"); + //} +//} +static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair, std::map>& cat_dat) { + if (cat_dat.first.has_value()) { + bool tmp = cat_dat.first.value(); + if (ImGui::Checkbox(ccat.data(), &tmp)) { + conf.set(cmodule, ccat, tmp); + } + } else if (!cat_dat.second.empty()) { + ImGui::Text("uhhh"); + } +} +static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair, std::map>& cat_dat) { + if (cat_dat.first.has_value()) { + int64_t tmp = cat_dat.first.value(); + if (ImGui::InputScalar(ccat.data(), ImGuiDataType_S64, &tmp)) { + conf.set(cmodule, ccat, tmp); + } + } else if (!cat_dat.second.empty()) { + ImGui::Text("uhhh"); + } +} +static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair, std::map>& cat_dat) { + if (cat_dat.first.has_value()) { + double tmp = cat_dat.first.value(); + if (ImGui::InputDouble(ccat.data(), &tmp)) { + conf.set(cmodule, ccat, tmp); + } + } else if (!cat_dat.second.empty()) { + ImGui::Text("uhhh"); + } +} +static void renderConfigCat(SimpleConfigModel& conf, std::string_view cmodule, std::string_view ccat, const std::pair, std::map>& cat_dat) { + if (cat_dat.first.has_value()) { + std::string tmp = cat_dat.first.value(); + if (ImGui::InputText(ccat.data(), &tmp)) { + conf.set(cmodule, ccat, CM_ISV{tmp}); + } + } else if (!cat_dat.second.empty()) { + ImGui::Text("uhhh"); + } +} + +SettingsWindow::SettingsWindow(SimpleConfigModel& conf) : _conf(conf) { } void SettingsWindow::render(void) { @@ -27,7 +123,97 @@ void SettingsWindow::render(void) { if (_show_window) { if (ImGui::Begin("Settings", &_show_window)) { - ImGui::Text("Settings here sldjflsadfs"); + ImGui::TextDisabled("most settings are only fetched once at program startup"); + + // ufff + // we need to iterate 4 maps, ideally in lexicographic order + // (pain) + // std::maps should be ordered more or less correctly + // (less pain) + // its recursive + // (pain) + // but the code is reusable + // (less pain) + + iterateMultMaps( + [this](std::string_view cmodule, const auto& ...mod_map_types) { + if (ImGui::CollapsingHeader(cmodule.data())) { + iterateMultMaps( + [this, cmodule](std::string_view ccat, const auto& ...cat_map_types) { + (renderConfigCat(_conf, cmodule, ccat, cat_map_types), ...); + }, + mod_map_types... + ); + } + }, + _conf._map_bool, + _conf._map_int, + _conf._map_double, + _conf._map_string + ); + +#if 0 + auto it_b = _conf._map_bool.begin(); + auto it_i = _conf._map_int.begin(); + auto it_d = _conf._map_double.begin(); + auto it_s = _conf._map_string.begin(); + + while ( + it_b != _conf._map_bool.end() || + it_i != _conf._map_int.end() || + it_d != _conf._map_double.end() || + it_s != _conf._map_string.end() + ) { + // figure out current module + std::string_view current_module; + bool bool_is_curr = false; + bool int_is_curr = false; + bool double_is_curr = false; + bool string_is_curr = false; + + if (it_b != _conf._map_bool.end() && (current_module.empty() || current_module >= it_b->first)) { + //std::cerr << "SET bool\n"; + bool_is_curr = true; + current_module = it_b->first; + } + if (it_i != _conf._map_int.end() && (current_module.empty() || current_module >= it_i->first)) { + //std::cerr << "SET int\n"; + int_is_curr = true; + current_module = it_i->first; + } + if (it_d != _conf._map_double.end() && (current_module.empty() || current_module >= it_d->first)) { + //std::cerr << "SET double\n"; + double_is_curr = true; + current_module = it_d->first; + } + if (it_s != _conf._map_string.end() && (current_module.empty() || current_module >= it_s->first)) { + //std::cerr << "SET string\n"; + string_is_curr = true; + current_module = it_s->first; + } + + assert(!current_module.empty()); + + //ImGui::Text("module '%s'", current_module.data()); + if (ImGui::CollapsingHeader(current_module.data())) { + // ... do the whole 4way iterate again but on categoy + } + + // after the module, increment iterators pointing to current_module + if (bool_is_curr) { + it_b++; + } + if (int_is_curr) { + it_i++; + } + if (double_is_curr) { + it_d++; + } + if (string_is_curr) { + it_s++; + } + } +#endif } ImGui::End(); } diff --git a/src/settings_window.hpp b/src/settings_window.hpp index 9ae52e64..bbe7c41b 100644 --- a/src/settings_window.hpp +++ b/src/settings_window.hpp @@ -1,13 +1,14 @@ #pragma once -struct ConfigModelI; +struct SimpleConfigModel; class SettingsWindow { bool _show_window {false}; - ConfigModelI& _conf; + // TODO: add iteration api to interface + SimpleConfigModel& _conf; public: - SettingsWindow(ConfigModelI& conf); + SettingsWindow(SimpleConfigModel& conf); void render(void); };