68 std::optional<f64> min;
69 std::optional<f64> max;
85 std::vector<std::string> values;
87 template <
typename... Texts>
88 explicit Allowed(Texts... texts) : values{std::string(texts)...} {}
93inline constexpr SettingLife kUntilLaunch = SettingLife::kUntilLaunch;
102class REX_API SettingBase :
public NonCopyable {
104 virtual ~SettingBase();
109 const std::string& GetHelp()
const;
118 SettingOwner& GetOwner()
const;
134 std::string GetDefaultText()
const;
157 SettingBase(SettingOwner& owner, std::string_view name,
SettingType type, std::string_view help);
172 friend class SettingOwner;
173 friend class SettingsRegistry;
175 virtual bool Store(std::string_view text) = 0;
176 virtual void Publish() = 0;
177 virtual std::string Render()
const = 0;
178 virtual std::string RenderDefault()
const = 0;
179 virtual void Notify() = 0;
182 std::unique_ptr<State> state_;
198 template <
typename... Traits>
199 Setting(SettingOwner* owner, std::string_view name,
const T& default_value, std::string_view help,
228 static constexpr bool kScalar =
229 !std::is_same_v<T, std::string> && !std::is_same_v<T, std::filesystem::path>;
230 using Storage = std::conditional_t<kScalar, std::atomic<T>, T>;
232 bool Store(std::string_view text)
override;
233 void Publish()
override;
234 std::string Render()
const override;
235 std::string RenderDefault()
const override;
236 void Notify()
override;
243 mutable std::mutex mutex_;
245 std::vector<std::pair<u64, std::shared_ptr<
MoveOnlyFunction<void(
const T&)>>>> watches_;
259 const std::string& GetScope()
const;
267 friend class SettingBase;
268 friend class ConsoleCommand;
269 friend class SettingsRegistry;
271 std::unique_ptr<State> state_;
276REX_API bool ParseSetting(std::string_view text,
bool& out);
277REX_API bool ParseSetting(std::string_view text, i32& out);
278REX_API bool ParseSetting(std::string_view text, i64& out);
279REX_API bool ParseSetting(std::string_view text, u32& out);
280REX_API bool ParseSetting(std::string_view text, u64& out);
281REX_API bool ParseSetting(std::string_view text, f64& out);
282REX_API bool ParseSetting(std::string_view text, std::string& out);
283REX_API bool ParseSetting(std::string_view text, std::filesystem::path& out);
285REX_API std::string RenderSetting(
bool value);
286REX_API std::string RenderSetting(i32 value);
287REX_API std::string RenderSetting(i64 value);
288REX_API std::string RenderSetting(u32 value);
289REX_API std::string RenderSetting(u64 value);
290REX_API std::string RenderSetting(f64 value);
291REX_API std::string RenderSetting(
const std::string& value);
292REX_API std::string RenderSetting(
const std::filesystem::path& value);
294REX_API std::filesystem::path ResolveSettingPath(
const std::filesystem::path& value);
298 if constexpr (std::is_same_v<T, bool>)
299 return SettingType::kBool;
300 else if constexpr (std::is_same_v<T, i32>)
301 return SettingType::kI32;
302 else if constexpr (std::is_same_v<T, i64>)
303 return SettingType::kI64;
304 else if constexpr (std::is_same_v<T, u32>)
305 return SettingType::kU32;
306 else if constexpr (std::is_same_v<T, u64>)
307 return SettingType::kU64;
308 else if constexpr (std::is_same_v<T, f64>)
309 return SettingType::kF64;
310 else if constexpr (std::is_same_v<T, std::string>)
311 return SettingType::kString;
316inline void ApplyTrait(SettingConstraints& c,
const Range& r) {
320inline void ApplyTrait(SettingConstraints& c,
const Allowed& a) {
321 c.allowed = a.values;
323inline void ApplyTrait(SettingConstraints& c,
SettingLife life) {
326inline void ApplyTrait(SettingConstraints& c, NoSave) {
329inline void ApplyTrait(SettingConstraints& c, DebugOnly) {
332inline void ApplyTrait(SettingConstraints& c, KeyChordTrait) {
339template <
typename... Traits>
341 std::string_view help, Traits... traits)
342 : SettingBase(*owner, name, detail::TypeOf<T>(), help),
343 default_(default_value),
344 staged_(default_value),
345 active_(default_value) {
350T Setting<T>::GetActive()
const {
351 if constexpr (kScalar) {
352 return active_.load(std::memory_order_relaxed);
354 std::lock_guard lock(mutex_);
361 if constexpr (std::is_same_v<T, std::filesystem::path>) {
362 return detail::ResolveSettingPath(GetActive());
382 std::lock_guard lock(mutex_);
384 watches_.emplace_back(
id, std::make_shared<
MoveOnlyFunction<
void(
const T&)>>(std::move(fn)));
387 std::lock_guard lock(mutex_);
388 std::erase_if(watches_, [
id](
const auto& entry) {
return entry.first == id; });
393bool Setting<T>::Store(std::string_view text) {
395 if (!detail::ParseSetting(text, parsed)) {
398 std::lock_guard lock(mutex_);
399 staged_ = std::move(parsed);
404void Setting<T>::Publish() {
405 std::lock_guard lock(mutex_);
406 if constexpr (kScalar) {
407 active_.store(staged_, std::memory_order_relaxed);
414std::string Setting<T>::Render()
const {
415 std::lock_guard lock(mutex_);
416 return detail::RenderSetting(staged_);
420std::string Setting<T>::RenderDefault()
const {
421 return detail::RenderSetting(default_);
425void Setting<T>::Notify() {
427 T value = GetActive();
429 std::lock_guard lock(mutex_);
430 for (
auto& entry : watches_) {
431 calls.push_back(entry.second);
434 for (
auto& call : calls) {
451#define REX_SETTING(Type, name, default_value, help, ...) \
452 ::rex::Setting<Type> name { \
453 this, #name, default_value, help __VA_OPT__(, ) __VA_ARGS__ \
Definition console_command.h:26
SettingLayer GetLayer() const
Result< void > SetFromCode(std::string_view text)
bool IsRestartPending() const
std::string GetText() const
Result< void > SetText(SettingLayer layer, std::string_view text)
SettingConstraints & EditConstraints()
Result< void > Check(std::string_view text) const
const SettingConstraints & GetConstraints() const
const std::string & GetName() const
std::span< SettingBase *const > GetOwnedSettings() const
SettingOwner(std::string_view scope)
Result< void > Set(const T &value)
Definition setting.h:369
ScopeGuard OnChange(MoveOnlyFunction< void(const T &)> fn)
Definition setting.h:379
Setting(SettingOwner *owner, std::string_view name, const T &default_value, std::string_view help, Traits... traits)
Definition setting.h:340
Result< void > Lock(const T &value)
Definition setting.h:374
T Get() const
Definition setting.h:360
Definition settings_registry.h:139
Interfaces, factory and module declaration.
SettingLife
Definition setting.h:60
@ kRestart
Definition setting.h:62
@ kLive
Definition setting.h:61
@ kStartupOnly
Definition setting.h:63
SettingType
Definition setting.h:38
@ kPath
Definition setting.h:46
typename detail::MoveOnlyFunctionFor< Signature >::type MoveOnlyFunction
Definition utility.h:254
std::expected< T, Error > Result
Definition result.h:98
SettingLayer
Definition setting.h:50
@ kEnvironment
Definition setting.h:54
@ kCommandLine
Definition setting.h:55
@ kLock
Definition setting.h:57
bool debug_only
Definition setting.h:73
bool key_chord
Definition setting.h:74
std::vector< std::string > allowed
Definition setting.h:70
bool no_save
Definition setting.h:72
Integer types, byte order wrappers and size literals.
Move only function, const propagating pointer and scope guard.