2#ifndef LIBSBX_CORE_SETTINGS_HPP_
3#define LIBSBX_CORE_SETTINGS_HPP_
11#include <unordered_map>
15#include <libsbx/utility/hashed_string.hpp>
17#include <libsbx/memory/observer_ptr.hpp>
23template<std::default_initializable Type>
29template<
typename Type>
31 std::string_view name;
32 std::optional<setting_range<Type>> range{std::nullopt};
39 template<
typename Type>
41 auto lock = std::scoped_lock{_mutex};
43 _data[std::string{key.name}] = std::move(value);
46 template<
typename Type>
48 auto lock = std::scoped_lock{_mutex};
50 auto entry = _data.find(std::string{key.name});
52 if (entry == _data.end()) {
53 throw std::runtime_error(
"setting not found");
56 return std::any_cast<Type>(entry->second);
59 template<
typename Type>
61 auto lock = std::scoped_lock{_mutex};
63 auto entry = _data.find(std::string{key.name});
65 if (entry == _data.end()) {
69 return std::any_cast<Type>(entry->second);
74 static inline std::unordered_map<std::string, std::any> _data;
75 static inline std::mutex _mutex;
81template<
typename Type>
82concept setting_type = std::is_same_v<Type, bool> || std::is_same_v<Type, std::uint32_t> || std::is_same_v<Type, std::int32_t> || std::is_same_v<Type, std::float_t> || std::is_same_v<Type, std::string>;
88 using entry_type = std::variant<std::monostate, bool, std::uint32_t, std::int32_t, std::float_t, std::string>;
103 std::vector<group_entry> entries;
108 template<setting_type Type>
110 _settings[key] =
value_type{value, std::monostate{}, std::monostate{}};
113 template<setting_type Type>
114 auto set(
const utility::hashed_string& key,
const Type& value,
const Type& min,
const Type& max) ->
void {
115 _settings[key] = value_type{value, min, max};
118 template<setting_type Type>
119 auto get(
const utility::hashed_string& key)
const -> memory::observer_ptr<const Type> {
120 if (
auto entry = _settings.find(key); entry != _settings.end()) {
121 return std::get_if<Type>(&entry->second.entry);
138 template<
typename Callable>
139 requires (std::is_invocable_v<Callable, const utility::hashed_string&, group&>)
140 auto for_each(Callable&& callable) ->
void {
141 auto grouped = std::unordered_map<utility::hashed_string, group>{};
143 for (
auto& [key, value] : _settings) {
144 const auto position = key.rfind(
"::");
146 const auto has_namespace = (position != utility::hashed_string::npos);
148 const auto group_name = has_namespace ? key.substr(0, position) : key;
149 const auto entry_name = has_namespace ? key.substr(position + 2u) : key;
151 grouped[group_name].name = group_name;
152 grouped[group_name].entries.emplace_back(group_entry{entry_name, value});
155 for (
auto& [group_name, group] : grouped) {
156 std::invoke(callable, group_name, group);
162 std::unordered_map<utility::hashed_string, value_type> _settings;
Definition: settings.hpp:35
Definition: settings.hpp:84
Definition: hashed_string.hpp:17
Definition: settings.hpp:30
Definition: settings.hpp:24
Definition: settings.hpp:96
Definition: settings.hpp:101
Definition: settings.hpp:90