From bae92cea3bcbacd7883499da61a0e54f13da6d23 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Mon, 26 Nov 2018 20:47:47 +0100 Subject: wanda: architecture rework --- src/setting.hpp | 154 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 130 insertions(+), 24 deletions(-) (limited to 'src/setting.hpp') diff --git a/src/setting.hpp b/src/setting.hpp index 6293dd3..6e10a8a 100644 --- a/src/setting.hpp +++ b/src/setting.hpp @@ -1,48 +1,154 @@ +/** + * @file setting.hpp + * @author Felix Morgner (felix.morgner@gmail.com) + * @since 1.0.0 + */ + #ifndef WANDA_setting_HPP #define WANDA_setting_HPP +#include "deferred_failure.hpp" +#include "type_wrapper.hpp" + #include +#include #include +#include +#include #include #include -#include +#include +#include -#include "type_wrapper.hpp" -#include "variant.hpp" -#include - -namespace wanda { +namespace wanda +{ struct setting; -using schema = type_wrapper; + +/** + * @brief A convenience type to represent setting keys + */ using key = type_wrapper; -namespace literals { -key operator""_key(char const * str, std::size_t len); -std::optional operator""_setting(char const * str, std::size_t len); -} +namespace literals +{ +/** + * @brief UDL to create setting keys + */ +key operator""_key(char const *str, std::size_t len); + +/** + * @brief UDL to create setting schemas + */ +std::optional operator""_setting(char const *str, std::size_t lent); +} // namespace literals + +/** + * @brief A simple wrapper for GSettings Schemas + */ +struct setting +{ + struct entry + { + + using value_type = std::variant>; + + value_type operator*() const; + + template + bool operator=(Type value) + { + struct setting_applier + { + setting_applier(GSettings *setting, gchar const *key, Type value) noexcept + : m_result{[&] { + if constexpr (std::is_same_v) + { + return g_settings_set_boolean(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_int(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_int64(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_uint(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_uint64(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_double(setting, key, value); + } + else if constexpr (std::is_same_v) + { + return g_settings_set_string(setting, key, value.c_str()); + } + else if constexpr (std::is_same_v>) + { + auto temp = std::vector{value.size() + 1}; + std::transform(value.begin(), value.end(), temp.begin(), [](auto const &str) { return str.c_str(); }); + return g_settings_set_strv(setting, key, temp.data()); + } + else + { + static_assert(deferred_failure{}, "Invalid argument type!"); + } + }()} + { + } + + ~setting_applier() + { + g_settings_sync(); + } + + operator bool() const + { + return m_result; + } + + private: + gboolean const m_result; + }; + + return setting_applier{m_settings.get(), m_key.get().c_str(), value}; + } -struct setting { - ~setting(); + private: + entry(setting const &schema, key key); - setting(setting const & other); + std::unique_ptr m_settings; - template std::optional get(key key) const { - auto value = variant{g_settings_get_value(m_value, key.get().c_str())}; - return value.get(); - } + key m_key; -private: - explicit setting(schema schema); + friend setting; + }; - GSettings * m_value; + /** + * @brief Get the entry for the given key + * + * @return An std::optional wrapping the entry associated with + * the given key, or an empty std::optional if the desired key + * does not exist in the setting's schema. + */ + std::optional operator[](key key) const; - friend std::optional literals::operator""_setting(char const *, std::size_t); -}; +private: + explicit setting(GSettingsSchema *schema); + std::unique_ptr m_schema; -} + friend std::optional literals::operator""_setting(char const *, std::size_t); +}; +} // namespace wanda #endif \ No newline at end of file -- cgit v1.2.3