diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 445a5cb6..1b778966 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,9 @@ target_sources(tomato PUBLIC ./main.cpp ./icon.rc + ./json_to_config.hpp + ./json_to_config.cpp + ./screen.hpp ./start_screen.hpp ./start_screen.cpp diff --git a/src/json_to_config.cpp b/src/json_to_config.cpp new file mode 100644 index 00000000..60fae161 --- /dev/null +++ b/src/json_to_config.cpp @@ -0,0 +1,67 @@ +#include "./json_to_config.hpp" + +#include + +#include + +#include + +bool load_json_into_config(const nlohmann::ordered_json& config_json, SimpleConfigModel& conf) { + if (!config_json.is_object()) { + std::cerr << "TOMATO error: config file is not an json object!!!\n"; + return false; + } + for (const auto& [mod, cats] : config_json.items()) { + for (const auto& [cat, cat_v] : cats.items()) { + if (cat_v.is_object()) { + if (cat_v.contains("default")) { + const auto& value = cat_v["default"]; + if (value.is_string()) { + conf.set(mod, cat, value.get_ref()); + } else if (value.is_boolean()) { + conf.set(mod, cat, value.get_ref()); + } else if (value.is_number_float()) { + conf.set(mod, cat, value.get_ref()); + } else if (value.is_number_integer()) { + conf.set(mod, cat, value.get_ref()); + } else { + std::cerr << "JSON error: wrong value type in " << mod << "::" << cat << " = " << value << "\n"; + return false; + } + } + if (cat_v.contains("entries")) { + for (const auto& [ent, ent_v] : cat_v["entries"].items()) { + if (ent_v.is_string()) { + conf.set(mod, cat, ent, ent_v.get_ref()); + } else if (ent_v.is_boolean()) { + conf.set(mod, cat, ent, ent_v.get_ref()); + } else if (ent_v.is_number_float()) { + conf.set(mod, cat, ent, ent_v.get_ref()); + } else if (ent_v.is_number_integer()) { + conf.set(mod, cat, ent, ent_v.get_ref()); + } else { + std::cerr << "JSON error: wrong value type in " << mod << "::" << cat << "::" << ent << " = " << ent_v << "\n"; + return false; + } + } + } + } else { + if (cat_v.is_string()) { + conf.set(mod, cat, cat_v.get_ref()); + } else if (cat_v.is_boolean()) { + conf.set(mod, cat, cat_v.get_ref()); + } else if (cat_v.is_number_float()) { + conf.set(mod, cat, cat_v.get_ref()); + } else if (cat_v.is_number_integer()) { + conf.set(mod, cat, cat_v.get_ref()); + } else { + std::cerr << "JSON error: wrong value type in " << mod << "::" << cat << " = " << cat_v << "\n"; + return false; + } + } + } + } + + return true; +} + diff --git a/src/json_to_config.hpp b/src/json_to_config.hpp new file mode 100644 index 00000000..5f2b72b8 --- /dev/null +++ b/src/json_to_config.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +// fwd +struct SimpleConfigModel; + +bool load_json_into_config(const nlohmann::ordered_json& config_json, SimpleConfigModel& conf); + diff --git a/src/main.cpp b/src/main.cpp index 88567dea..89822040 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,10 +12,17 @@ #include #include +#include #include #include int main(int argc, char** argv) { + // better args + std::vector args; + for (int i = 0; i < argc; i++) { + args.push_back(argv[i]); + } + // setup hints if (SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1") != SDL_TRUE) { std::cerr << "Failed to set '" << SDL_HINT_VIDEO_ALLOW_SCREENSAVER << "' to 1\n"; @@ -91,7 +98,7 @@ int main(int argc, char** argv) { ImGui_ImplSDL3_InitForSDLRenderer(window.get(), renderer.get()); ImGui_ImplSDLRenderer3_Init(renderer.get()); - std::unique_ptr screen = std::make_unique(renderer.get(), theme); + std::unique_ptr screen = std::make_unique(args, renderer.get(), theme); bool quit = false; diff --git a/src/main_screen.cpp b/src/main_screen.cpp index 798d239b..f8012d29 100644 --- a/src/main_screen.cpp +++ b/src/main_screen.cpp @@ -12,8 +12,9 @@ #include #include -MainScreen::MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector plugins) : +MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector plugins) : renderer(renderer_), + conf(std::move(conf_)), rmm(cr), msnj{cr, {}, {}}, mts(rmm), diff --git a/src/main_screen.hpp b/src/main_screen.hpp index 2b7bb763..7b1f78ee 100644 --- a/src/main_screen.hpp +++ b/src/main_screen.hpp @@ -91,7 +91,7 @@ struct MainScreen final : public Screen { uint64_t _window_hidden_ts {0}; float _time_since_event {0.f}; - MainScreen(SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector plugins); + MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector plugins); ~MainScreen(void); bool handleEvent(SDL_Event& e) override; diff --git a/src/start_screen.cpp b/src/start_screen.cpp index 5fc33c90..020dcb00 100644 --- a/src/start_screen.cpp +++ b/src/start_screen.cpp @@ -2,14 +2,53 @@ #include "./main_screen.hpp" +#include "./json_to_config.hpp" + +#include + #include #include #include #include #include +#include -StartScreen::StartScreen(SDL_Renderer* renderer, Theme& theme) : _renderer(renderer), _theme(theme) { +StartScreen::StartScreen(const std::vector& args, SDL_Renderer* renderer, Theme& theme) : _renderer(renderer), _theme(theme) { + for (size_t ai = 0; ai < args.size(); ai++) { + if (args.at(ai) == "--config" || args.at(ai) == "-c") { + if (args.size() == ai+1) { + std::cerr << "TOMATO error: argument '" << args.at(ai) << "' missing parameter!\n"; + break; + } + ai++; + + const auto& config_path = args.at(ai); + auto config_file = std::ifstream(static_cast(config_path)); + if (!config_file.is_open()) { + std::cerr << "TOMATO error: failed to open config file '" << config_path << "'\n"; + break; + } + + auto config_json = nlohmann::ordered_json::parse(config_file); + if (!load_json_into_config(config_json, _conf)) { + std::cerr << "TOMATO error in config json, exiting...\n"; + break; + } + } else if (args.at(ai) == "--plugin" || args.at(ai) == "-p") { + if (args.size() == ai+1) { + std::cerr << "TOMATO error: argument '" << args.at(ai) << "' missing parameter!\n"; + break; + } + ai++; + + const auto& plugin_path = args.at(ai); + // TODO: check for dups + queued_plugin_paths.push_back(static_cast(plugin_path)); + } else { + std::cerr << "TOMATO error: unknown cli arg: '" << args.at(ai) << "'\n"; + } + } } Screen* StartScreen::render(float, bool&) { @@ -143,7 +182,7 @@ Screen* StartScreen::render(float, bool&) { } } else { if (ImGui::Button("load", {60, 25})) { - auto new_screen = std::make_unique(_renderer, _theme, _tox_profile_path, _password, _user_name, queued_plugin_paths); + auto new_screen = std::make_unique(std::move(_conf), _renderer, _theme, _tox_profile_path, _password, _user_name, queued_plugin_paths); return new_screen.release(); } } diff --git a/src/start_screen.hpp b/src/start_screen.hpp index 78f08be8..f427de83 100644 --- a/src/start_screen.hpp +++ b/src/start_screen.hpp @@ -5,6 +5,8 @@ #include "./chat_gui/theme.hpp" #include "./chat_gui/file_selector.hpp" +#include + #include #include @@ -16,6 +18,7 @@ extern "C" { struct StartScreen final : public Screen { SDL_Renderer* _renderer; Theme& _theme; + SimpleConfigModel _conf; FileSelector _fss; bool _new_save {false}; @@ -28,7 +31,7 @@ struct StartScreen final : public Screen { std::vector queued_plugin_paths; StartScreen(void) = delete; - StartScreen(SDL_Renderer* renderer, Theme& theme); + StartScreen(const std::vector& args, SDL_Renderer* renderer, Theme& theme); ~StartScreen(void) = default; // return nullptr if not next