#ifndef KZSETTINGS_H #define KZSETTINGS_H #include #include #include #include #include /** @brief Key type for settings, composed of category and name */ using KzSettingKey = std::pair; /** @brief Value type that can hold string, int, double or boolean */ using KzSettingValue = std::variant; namespace KaZoe { class KzSettingsPrivate; /** * @brief Main class for managing KaZoe settings * * This class provides a thread-safe interface for storing and retrieving * configuration settings with support for different value types. */ class KzSettings { public: /** @brief Constructs a new Settings instance */ explicit KzSettings(); /** @brief Virtual destructor */ virtual ~KzSettings(); /** * @brief Retrieves a setting value * @param key The setting key * @param category The setting category (optional) * @param def Default value if setting not found (optional) * @return The setting value or default if not found */ KzSettingValue get(const std::string &key, const std::string &category = "", KzSettingValue def = KzSettingValue()) const; /** * @brief Sets a setting value * @param key The setting key * @param value The value to set * @param category The setting category (optional) * @return true if successful, false otherwise */ bool set(const std::string &key, KzSettingValue value, const std::string &category = ""); /** * @brief Gets the current instance identifier * @return The instance ID string, by default, this is the excecutable filename */ std::string id() const; /** * @brief Sets the instance identifier * @param newid The new ID to set */ void setId(const std::string &newid); /** * @brief Sets a callback for setting changes notification * @param callback Function to call when settings change */ void setNotifier(const std::function& callback); /** * @brief Gets the number of settings * @return The total count of settings */ std::size_t size() const; /** * @brief Iterates over all settings in a thread-safe manner * @param callback Function called for each key-value pair */ void forEach(const std::function& callback) const; private: std::unique_ptr m_ptr; ///< Private implementation pointer }; /** * @brief Functor to convert SettingValue variants to string * * Provides string conversion for all supported setting value types */ struct settingValueFunctor { std::string operator()(const std::string &x) const { return x; } std::string operator()(int x) const { return std::to_string(x); } std::string operator()(double x) const { return std::to_string(x); } std::string operator()(bool x) const { return x ? "true" : "false"; } }; /** * @brief Convert a SettingValue into a string for display * @param value Input SettingValue to convert * @return std::string containing the converted value */ static inline std::string valueToStr(const KzSettingValue &value) { return std::visit(settingValueFunctor(), value); } /** * @brief Check if a string represents a valid numeric value * @param str String to check * @return true if string is numeric, false otherwise */ static inline bool is_numeric(const std::string& str) { return !str.empty() && str.find_first_not_of("0123456789.-") == std::string::npos && (std::count(str.begin(), str.end(), '.') <= 1) && (std::count(str.begin(), str.end(), '-') <= 1) && (str[0] == '-' || std::isdigit(str[0])); } /** * @brief Convert a string to appropriate SettingValue type * @param value Input string to convert * @return SettingValue containing the converted value * * Conversion rules: * - Quoted strings -> string without quotes * - Numeric values -> int or double * - "true"/"on" -> boolean true * - "false"/"off" -> boolean false * - Other -> string */ static inline KzSettingValue makeValue(const std::string &value) { if(value.starts_with('"') || value.starts_with('\'')) { return value.substr(1, value.length() - 2); } if(is_numeric(value)) { // double if(value.find('.') != value.npos) { return std::stod(value); } else { return std::stoi(value); } } // To Lower case std::string lvalue = value; std::transform(lvalue.begin(), lvalue.end(), lvalue.begin(), [](unsigned char c){ return std::tolower(c); }); // bool true if(lvalue == "true" || lvalue == "on") { return true; } // bool false if(lvalue == "false" || lvalue == "off") { return false; } // else, string without quote return value; } }; #endif // KZSETTINGS_H