options.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include "base/flags.h"
  9. #include "base/variant.h"
  10. #include "base/required.h"
  11. #ifdef linux // GCC, cmon..
  12. #undef linux
  13. #endif // linux
  14. namespace base::options {
  15. namespace details {
  16. using ValueType = std::variant<bool, int, QString>;
  17. enum class ScopeFlag : uchar {
  18. Windows = (1 << 1),
  19. Mac = (1 << 2),
  20. Linux = (1 << 3),
  21. };
  22. inline constexpr bool is_flag_type(ScopeFlag) { return true; }
  23. using ScopeFlags = base::flags<ScopeFlag>;
  24. using ScopeFn = Fn<bool()>;
  25. using Scope = std::variant<ScopeFlags, ScopeFn>;
  26. class BasicOption {
  27. public:
  28. BasicOption(
  29. const char id[],
  30. const char name[],
  31. const char description[],
  32. ValueType defaultValue,
  33. Scope scope,
  34. bool restartRequired);
  35. BasicOption(const BasicOption&) = delete;
  36. BasicOption operator=(const BasicOption&) = delete;
  37. void set(ValueType value);
  38. [[nodiscard]] const ValueType &value() const;
  39. [[nodiscard]] const ValueType &defaultValue() const;
  40. [[nodiscard]] const QString &id() const;
  41. [[nodiscard]] const QString &name() const;
  42. [[nodiscard]] const QString &description() const;
  43. [[nodiscard]] bool relevant() const;
  44. [[nodiscard]] Scope scope() const;
  45. [[nodiscard]] bool restartRequired() const;
  46. private:
  47. ValueType _value;
  48. ValueType _defaultValue;
  49. QString _id;
  50. QString _name;
  51. QString _description;
  52. Scope _scope;
  53. bool _restartRequired = false;
  54. };
  55. [[nodiscard]] BasicOption &Lookup(const char name[]);
  56. } // namespace details
  57. inline constexpr auto windows = details::ScopeFlag::Windows;
  58. inline constexpr auto macos = details::ScopeFlag::Mac;
  59. inline constexpr auto linux = details::ScopeFlag::Linux;
  60. template <typename Type>
  61. struct descriptor {
  62. required<const char*> id;
  63. const char *name = "";
  64. const char *description = "";
  65. Type defaultValue = Type();
  66. details::Scope scope = windows | macos | linux;
  67. bool restartRequired = false;
  68. };
  69. template <typename Type>
  70. class option final : details::BasicOption {
  71. public:
  72. option(descriptor<Type> &&fields)
  73. : BasicOption(
  74. fields.id,
  75. fields.name,
  76. fields.description,
  77. std::move(fields.defaultValue),
  78. fields.scope,
  79. fields.restartRequired) {
  80. }
  81. using BasicOption::id;
  82. using BasicOption::name;
  83. using BasicOption::description;
  84. using BasicOption::relevant;
  85. using BasicOption::scope;
  86. using BasicOption::restartRequired;
  87. void set(Type value) {
  88. BasicOption::set(std::move(value));
  89. }
  90. [[nodiscard]] Type value() const {
  91. return v::get<Type>(BasicOption::value());
  92. }
  93. [[nodiscard]] Type defaultValue() const {
  94. return v::get<Type>(BasicOption::defaultValue());
  95. }
  96. [[nodiscard]] static option &Wrap(BasicOption &that) {
  97. Expects(v::is<Type>(that.value()));
  98. return static_cast<option&>(that);
  99. }
  100. };
  101. using toggle = option<bool>;
  102. template <typename Type>
  103. [[nodiscard]] inline Type value(const char id[]) {
  104. return v::get<Type>(details::Lookup(id).value());
  105. }
  106. template <typename Type>
  107. [[nodiscard]] inline option<Type> &lookup(const char id[]) {
  108. return option<Type>::Wrap(details::Lookup(id));
  109. }
  110. [[nodiscard]] bool changed();
  111. void reset();
  112. void init(const QString &path);
  113. } // namespace base::options