diff --git a/librecomp/CMakeLists.txt b/librecomp/CMakeLists.txt index f698b5f..61db595 100644 --- a/librecomp/CMakeLists.txt +++ b/librecomp/CMakeLists.txt @@ -8,9 +8,6 @@ set(CMAKE_CXX_EXTENSIONS OFF) # Define the library add_library(librecomp STATIC "${CMAKE_CURRENT_SOURCE_DIR}/src/ai.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/src/config/ConfigOption.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/src/config/ConfigRegistry.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/src/config/ConfigStore.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/cont.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/dp.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/eep.cpp" diff --git a/librecomp/include/librecomp/config.hpp b/librecomp/include/librecomp/config.hpp index 4ddbfc3..9df4e77 100644 --- a/librecomp/include/librecomp/config.hpp +++ b/librecomp/include/librecomp/config.hpp @@ -8,10 +8,4 @@ #include #include "json/json.hpp" -// namespace recomp::config - -#include "config/ConfigStore.hpp" -#include "config/ConfigRegistry.hpp" -#include "config/ConfigOption.hpp" - #endif diff --git a/librecomp/src/config/CallbackRegistry.cpp b/librecomp/src/config/CallbackRegistry.cpp deleted file mode 100644 index d7b7585..0000000 --- a/librecomp/src/config/CallbackRegistry.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "CallbackRegistry.hpp" - -namespace recomp::config { - -callback_registry_map callback_registry = {}; - -static recomp_callback_internal nullcb; - -void register_callback(const std::string& config_group, const std::string& key, recomp_callback& callback) { - callback_registry[config_group + "/" + key] = callback; -}; - -const void *get_pointer_from_conf_value(config_store_value& val) { - if (std::holds_alternative(val)) { - return &std::get(val); - } - if (std::holds_alternative(val)) { - return &std::get(val); - } - return nullptr; -} - -void invoke_callback(const std::string& key) { - auto find_it = callback_registry.find(key); - if (find_it == callback_registry.end()) { - printf("ERROR: Could not locate callback at '%s'.\n", key); - return; - } - - auto& cb = callback_registry.at(key); - - config_store_value& val = get_config_store_value(key); - - if (const auto& func = *std::get_if(&cb)) { - func(key, val); - } else if (const auto& func = *std::get_if(&cb)) { - func( - key.c_str(), - get_pointer_from_conf_value(val), - (ConfigStoreValueType)val.index() - ); - } -}; - -} diff --git a/librecomp/src/config/CallbackRegistry.hpp b/librecomp/src/config/CallbackRegistry.hpp deleted file mode 100644 index 1f1e782..0000000 --- a/librecomp/src/config/CallbackRegistry.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __RECOMP_CALLBACK_REGISTRY_H__ -#define __RECOMP_CALLBACK_REGISTRY_H__ - -#include -#include -#include -#include -#include -#include -#include "json/json.hpp" -#include "ConfigStore.hpp" - -namespace recomp::config { - using recomp_callback_internal = std::function; - - using recomp_callback_external = std::function; - - using recomp_callback = std::variant; - - using callback_registry_map = std::unordered_map; - - extern callback_registry_map callback_registry; - - void register_callback(const std::string& config_group, const std::string& key, recomp_callback& callback); -} -#endif diff --git a/librecomp/src/config/ConfigOption.cpp b/librecomp/src/config/ConfigOption.cpp deleted file mode 100644 index c6ca3f2..0000000 --- a/librecomp/src/config/ConfigOption.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include "config.hpp" - -#include -#include - -using json = nlohmann::json; -namespace recomp::config { - -bool ConfigOption::validate(json& opt_json) { - auto type_struct = get_type_structure(); - for (const auto& [key, expected_type] : type_struct) { - if (!opt_json.contains(key) || opt_json[key].type() != expected_type) { - return false; - } - } - return true; -} - -ConfigOption::ConfigOption(json& opt_json) -{ - type = opt_json[ConfigOption::schema::type]; - key = opt_json[ConfigOption::schema::key]; -} - -ConfigOption::~ConfigOption() -{ - -} - -} // namespace Rml diff --git a/librecomp/src/config/ConfigOption.hpp b/librecomp/src/config/ConfigOption.hpp deleted file mode 100644 index fef446f..0000000 --- a/librecomp/src/config/ConfigOption.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __RECOMP_CONFIG_OPTION_H__ -#define __RECOMP_CONFIG_OPTION_H__ - -#include -#include "json/json.hpp" - -namespace recomp::config { - -enum class ConfigOptionType { - Label, // todo - // Base types - Checkbox, - RadioTabs, - Dropdown, - Range, - Color, - Button, // todo - TextField, - // Group types - CheckboxGroup, - Group, - OptionCount -}; - -NLOHMANN_JSON_SERIALIZE_ENUM(ConfigOptionType, { - {ConfigOptionType::Label, "Label"}, - {ConfigOptionType::Checkbox, "Checkbox"}, - {ConfigOptionType::RadioTabs, "RadioTabs"}, - {ConfigOptionType::Dropdown, "Dropdown"}, - {ConfigOptionType::Range, "Range"}, - {ConfigOptionType::Color, "Color"}, - {ConfigOptionType::Button, "Button"}, - {ConfigOptionType::TextField, "TextField"}, - {ConfigOptionType::CheckboxGroup, "CheckboxGroup"}, - {ConfigOptionType::Group, "Group"} -}); - -typedef std::unordered_map config_type_structure; - -inline bool config_option_is_group(ConfigOptionType option_type) { - return option_type == ConfigOptionType::Group || option_type == ConfigOptionType::CheckboxGroup; -} - -/** - Base Config Option class. Defines what type of option or group it is, and - sets the key. - */ - -class ConfigOption { -public: - ConfigOption(nlohmann::json& opt_json); - virtual ~ConfigOption(); - - bool validate(nlohmann::json& opt_json); - - ConfigOptionType type; - std::string key; - - struct schema { - static constexpr const char* type = "type"; - static constexpr const char* key = "key"; - }; - -protected: - virtual const config_type_structure& get_type_structure() const = 0; -}; - -} -#endif diff --git a/librecomp/src/config/ConfigRegistry.cpp b/librecomp/src/config/ConfigRegistry.cpp deleted file mode 100644 index 199dad8..0000000 --- a/librecomp/src/config/ConfigRegistry.cpp +++ /dev/null @@ -1,288 +0,0 @@ -#include "config.hpp" - -using json = nlohmann::json; - -namespace recomp::config { - -ConfigRegistry config_registry = {{}, {}}; - -#define TODO_PARSE_ERROR(m, t) printf("Value at key: \"%s\" was invalid. Expected: \"%s\"\n", m, t) - -std::string get_string_in_json(const json& j, const std::string& key) { - std::string ret; - - auto find_it = j.find(key); - if (find_it != j.end()) { - auto at_val = j.at(key); - if (!at_val.is_string()) { - TODO_PARSE_ERROR(key, "string"); - } - - find_it->get_to(ret); - } - - return ret; -} - -std::string get_string_in_json_with_default(const json& j, const std::string& key, const std::string& default_val) { - std::string ret; - - auto find_it = j.find(key); - if (find_it != j.end()) { - auto at_val = j.at(key); - if (!at_val.is_string()) { - return default_val; - } - - find_it->get_to(ret); - } else { - return default_val; - } - - return ret; -} - -static bool validate_json_value_is_array(const json &j, const std::string& json_path, const std::string& arr_key) { - const auto &options = j.find(arr_key); - if (options == j.end()) { - TODO_PARSE_ERROR(json_path + "/" + arr_key, "array"); - return false; - } - const auto &opt_array = j[arr_key]; - - if (!opt_array.is_array()) { - TODO_PARSE_ERROR(json_path + "/" + arr_key, "array"); - return false; - } - - return true; -} - -// Option -void register_config_option( - const json& j, - const std::string& previous_key, // previous path before current key - const std::string& config_group, - const std::string& json_path // path to this json object from the root -) { - const std::string key = get_string_in_json(j, ConfigOption::schema::key); - const std::string this_key = previous_key + "/" + key; - - ConfigOptionType type = get_value_in_json(j, ConfigOption::schema::type); - - config_registry.key_ref_map[this_key] = { config_group, json_path }; - - switch (type) { - case ConfigOptionType::Button: { - if (j.find("callback") != j.end()) { - if (!j["callback"].is_string()) { - TODO_PARSE_ERROR(this_key + "/callback" , "string"); - return; - } - } - if (j.find("variant") != j.end()) { - if (!j["variant"].is_string()) { - TODO_PARSE_ERROR(this_key + "/variant" , "string"); - return; - } - } - - break; - } - case ConfigOptionType::TextField: { - std::string default_val = ""; - if (j.find("default") != j.end()) { - default_val = get_string_in_json(j, "default"); - } - if (j.find("maxlength") != j.end()) { - if (!j["maxlength"].is_number()) { - TODO_PARSE_ERROR(this_key + "/maxlength" , "number"); - return; - } - } - set_config_store_value_and_default(this_key, default_val, default_val); - break; - } - case ConfigOptionType::Checkbox: { - bool default_val = false; - if (j.find("default") != j.end()) { - default_val = get_value_in_json(j, "default"); - } - set_config_store_value_and_default(this_key, default_val, default_val); - break; - } - case ConfigOptionType::Color: { - const std::string rgb_strings[] = {"r", "g", "b"}; - - // read and ensure default is an array of numbers - if (j.find("default") != j.end()) { - if (!validate_json_value_is_array(j, json_path, "default")) { - return; - } - - const auto &col_array = j["default"]; - - for (int i = 0; i < col_array.size(); i++) { - const auto &j_opt = col_array[i]; - if (!j_opt.is_number()) { - TODO_PARSE_ERROR(this_key + "/default/" + std::to_string(i) , "number"); - return; - } - const int opt_val = j_opt.get(); - set_config_store_value_and_default(this_key + ":" + rgb_strings[i], opt_val, opt_val); - } - } else { - // "default" doesn't exist, set to black - set_config_store_value_and_default(this_key + ":" + rgb_strings[0], 0, 0); - set_config_store_value_and_default(this_key + ":" + rgb_strings[1], 0, 0); - set_config_store_value_and_default(this_key + ":" + rgb_strings[2], 0, 0); - } - - break; - } - case ConfigOptionType::Dropdown: - case ConfigOptionType::RadioTabs: { - if (!validate_json_value_is_array(j, json_path, "values")) { - return; - } - - int default_val = 0; - if (j.find("default") != j.end()) { - const auto &opt_array = j["values"]; - const std::string default_val_string = get_string_in_json(j, "default"); - // Based on default value's string, find which option index corresponds - for (int i = 0; i < opt_array.size(); i++) { - const auto &j_opt = opt_array[i]; - if (!j_opt.is_string()) { - TODO_PARSE_ERROR(key + "/values/" + std::to_string(i) , "string"); - return; - } - const std::string opt_val = j_opt.get(); - if (opt_val == default_val_string) { - default_val = i; - break; - } - } - } - set_config_store_value_and_default(this_key, default_val, default_val); - break; - } - case ConfigOptionType::Range: { - int default_val = 0; - int max = 0; - int min = 0; - int step = 1; - - if (j.find("default") != j.end()) { - default_val = get_value_in_json(j, "default"); - } - - // Max is required - if (j.find("max") != j.end()) { - max = get_value_in_json(j, "max"); - if (default_val > max) default_val = max; - } else { - TODO_PARSE_ERROR(key + "/max", "int"); - return; - } - - if (j.find("min") != j.end()) { - min = get_value_in_json(j, "min"); - if (default_val < min) default_val = min; - } - - if (j.find("step") != j.end()) { - step = get_value_in_json(j, "step"); - } - - assert(max > min); - assert(step < max - min); - set_config_store_value_and_default(this_key, default_val, default_val); - break; - } - } - if (j.find("label") != j.end()) { - const std::string label = get_string_in_json(j, "label"); - set_config_store_value(this_key, label); - } - - if ((type == ConfigOptionType::Group || type == ConfigOptionType::CheckboxGroup) && j.find("options") != j.end()) { - if (!validate_json_value_is_array(j, json_path, "options")) { - return; - } - - const auto &opt_array = j["options"]; - - for (int i = 0; i < opt_array.size(); i++) { - const auto &el = opt_array[i]; - register_config_option( - el, - this_key, - config_group, - json_path + "/options/" + std::to_string(i) - ); - } - } -} - -void register_config(const std::string &json_str, const std::string &config_group) { - config_registry.group_json_map[config_group] = json::parse(json_str); - const auto &j = config_registry.group_json_map[config_group]; - - if (!j.is_array()) { - TODO_PARSE_ERROR("/", "array"); - return; - } - - for (int i = 0; i < j.size(); i++) { - const auto &el = j[i]; - register_config_option( - el, - config_group, - config_group, - "/" + std::to_string(i) // json_path at top level - ); - } -} - -void register_translation(const std::string &json_str, const std::string &config_group) { - const auto &j = json::parse(json_str); - - if (!j.is_object()) { - TODO_PARSE_ERROR("/", "object"); - return; - } - - for (auto& el : j.items()) - { - std::string translation_key = "translations/" + config_group + "/" + el.key(); - const std::string value = el.value(); - set_config_store_value(translation_key, value); - } -} - -json get_json_from_key(const std::string &config_key) { - if (config_registry.key_ref_map.find(config_key) == config_registry.key_ref_map.end()) { - // TODO: handle not finding config_key - printf("FAILURE: AddOptionTypeElement failed to find config_key '%s' in config_registry.key_ref_map\n", config_key); - } - const JSONRef& json_ref = config_registry.key_ref_map[config_key]; - const json& group_json = config_registry.group_json_map[json_ref.config_group]; - json::json_pointer pointer(json_ref.json_path); - return group_json[pointer]; -} - -bool config_key_is_base_group(const std::string &config_group_key) { - // determine if the key references a base group by checking the group_json_map - if (config_registry.group_json_map.find(config_group_key) == config_registry.group_json_map.end()) { - return false; - } - return true; -} - -json& get_group_json(const std::string &config_group_key) { - return config_registry.group_json_map[config_group_key]; -} - - -} // namespace recompui diff --git a/librecomp/src/config/ConfigRegistry.hpp b/librecomp/src/config/ConfigRegistry.hpp deleted file mode 100644 index e9dd19d..0000000 --- a/librecomp/src/config/ConfigRegistry.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __RECOMP_CONFIG_REGISTRY_H__ -#define __RECOMP_CONFIG_REGISTRY_H__ - -#include -#include -#include -#include -#include -#include -#include "json/json.hpp" - -namespace recomp::config { - struct JSONRef { - std::string config_group; - std::string json_path; // used as a json pointer - }; - // config key -> JSONRef - using config_registry_key_reference_map = std::unordered_map; - // config group -> json - using config_registry_group_json_map = std::unordered_map; - - struct ConfigRegistry { - config_registry_key_reference_map key_ref_map; - config_registry_group_json_map group_json_map; - }; - - extern ConfigRegistry config_registry; - - void register_config(const std::string& json_str, const std::string& config_group); - void register_translation(const std::string &json_str, const std::string &config_group); - - nlohmann::json get_json_from_key(const std::string &config_key); - std::string get_string_in_json(const nlohmann::json& j, const std::string& key); - std::string get_string_in_json_with_default(const nlohmann::json& j, const std::string& key, const std::string& default_val); - bool config_key_is_base_group(const std::string &config_group_key); - nlohmann::json& get_group_json(const std::string &config_group_key); - - #define TODO_PARSE_ERROR(m, t) printf("Value at key: \"%s\" was invalid. Expected: \"%s\"\n", m, t) - - template - T get_value_in_json(const nlohmann::json& j, const std::string& key) { - T ret; - - auto find_it = j.find(key); - if (find_it != j.end()) { - auto at_val = j.at(key); - find_it->get_to(ret); - } - - return ret; - } - - template - T get_value_in_json_with_default(const nlohmann::json& j, const std::string& key, T default_val) { - T ret = default_val; - - auto find_it = j.find(key); - if (find_it != j.end()) { - auto at_val = j.at(key); - find_it->get_to(ret); - } - - return ret; - } -} -#endif diff --git a/librecomp/src/config/ConfigStore.cpp b/librecomp/src/config/ConfigStore.cpp deleted file mode 100644 index ad01966..0000000 --- a/librecomp/src/config/ConfigStore.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "config.hpp" - -namespace recomp::config { - -ConfigStore config_store = {{}, {}}; - -void set_config_store_value(std::string_view key, config_store_value value) { - std::lock_guard lock{ config_store.store_mutex }; - config_store.map[std::string{key}] = value; -} - -void set_config_store_default_value(std::string_view key, config_store_value value) { - std::lock_guard lock{ config_store.default_store_mutex }; - config_store.default_map[std::string{key}] = value; -} - -void set_config_store_value_and_default(std::string_view key, config_store_value value, config_store_value default_value) { - set_config_store_value(key, value); - set_config_store_default_value(key, default_value); -} - -} diff --git a/librecomp/src/config/ConfigStore.hpp b/librecomp/src/config/ConfigStore.hpp deleted file mode 100644 index 20a2f75..0000000 --- a/librecomp/src/config/ConfigStore.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef __RECOMP_CONFIG_STORE_H__ -#define __RECOMP_CONFIG_STORE_H__ - -#include -#include -#include -#include -#include - -// Use a custom hash class to enable hetereogenous lookup -struct string_hash { - using is_transparent = void; - [[nodiscard]] size_t operator()(const char *txt) const { - return std::hash{}(txt); - } - [[nodiscard]] size_t operator()(std::string_view txt) const { - return std::hash{}(txt); - } - [[nodiscard]] size_t operator()(const std::string &txt) const { - return std::hash{}(txt); - } -}; - -namespace recomp::config { - using config_store_value = std::variant; - using config_store_map = std::unordered_map>; - - struct ConfigStore { - config_store_map map; - config_store_map default_map; - std::mutex store_mutex; - std::mutex default_store_mutex; - }; - - extern ConfigStore config_store; - - // Index of variant type config_store_value - enum class ConfigStoreValueType { - Null, - String, - Int - }; - - void set_config_store_value(std::string_view key, config_store_value value); - void set_config_store_default_value(std::string_view key, config_store_value value); - void set_config_store_value_and_default(std::string_view key, config_store_value value, config_store_value default_value); - - template - T get_config_store_default_value(std::string_view key) { - std::lock_guard lock{ config_store.default_store_mutex }; - auto it = config_store.default_map.find(key); - if (it != config_store.default_map.end()) { - if (std::holds_alternative(it->second)) { - return std::get(it->second); - } else { - throw std::runtime_error("Stored value is not of requested type"); - } - } else { - throw std::runtime_error("Key not found"); - } - }; - - // Get a value from the config store, if it doesn't exist then return the default value - template - T get_config_store_value(std::string_view key) { - std::lock_guard lock{ config_store.store_mutex }; - auto it = config_store.map.find(key); - if (it != config_store.map.end()) { - if (std::holds_alternative(it->second)) { - return std::get(it->second); - } else { - throw std::runtime_error("Stored value is not of requested type"); - } - } else { - return get_config_store_default_value(key); - } - }; - - // Get a value from the config store, if it doesn't exist then return the supplied value - template - T get_config_store_value_with_default(std::string_view key, T default_value) { - std::lock_guard lock{ config_store.store_mutex }; - auto it = config_store.map.find(key); - if (it != config_store.map.end()) { - if (std::holds_alternative(it->second)) { - return std::get(it->second); - } else { - throw std::runtime_error("Stored value is not of requested type"); - } - } else { - return default_value; - } - }; -}; - -#endif