Overte C++ Documentation
SettingHandle.h
1 //
2 // SettingHandle.h
3 //
4 //
5 // Created by Clement on 1/18/15.
6 // Copyright 2015 High Fidelity, Inc.
7 // Copyright 2022 Overte e.V.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #ifndef hifi_SettingHandle_h
14 #define hifi_SettingHandle_h
15 
16 #include <type_traits>
17 
18 #include <QtCore/QStack>
19 #include <QtCore/QString>
20 #include <QtCore/QVariant>
21 #include <QtCore/QReadWriteLock>
22 #include <QtCore/QSharedPointer>
23 #include <QtCore/QDebug>
24 #include <QLoggingCategory>
25 
26 #include <glm/glm.hpp>
27 #include <glm/gtc/quaternion.hpp>
28 
29 #include "SettingInterface.h"
30 
31 
32 Q_DECLARE_LOGGING_CATEGORY(settings_handle)
33 
34 
41 extern const QString SETTINGS_FULL_PRIVATE_GROUP_NAME;
42 
56 class Settings {
57 public:
58 
59  class Group {
60  public:
61 
62  Group(const QString &groupName = QString()) {
63  _name = groupName;
64  }
65 
66  QString name() const { return _name; }
67 
68  bool isArray() const { return _arraySize != -1; }
69 
70  void setIndex(int i) {
71  if ( _arraySize < i+1) {
72  _arraySize = i+1;
73  }
74 
75  _arrayIndex = i;
76  }
77 
78  int index() const { return _arrayIndex; }
79  int size() const { return _arraySize; }
80  void setSize(int sz) { _arraySize = sz; }
81 
82  private:
83 
84  QString _name;
85  int _arrayIndex{0};
86  int _arraySize{-1};
87  };
88 
89  static const QString firstRun;
90  Settings();
91 
92  QString fileName() const;
93 
94  void remove(const QString& key);
95 
96  // These are not currently being used
97  // QStringList childGroups() const;
98  // QStringList childKeys() const;
99 
100  QStringList allKeys() const;
101  bool contains(const QString& key) const;
102  int beginReadArray(const QString & prefix);
103  void beginWriteArray(const QString& prefix, int size = -1);
104  void endArray();
105  void setArrayIndex(int i);
106 
107  void beginGroup(const QString& prefix);
108  void endGroup();
109 
110  void setValue(const QString& name, const QVariant& value);
111  QVariant value(const QString& name, const QVariant& defaultValue = QVariant()) const;
112 
113  void getFloatValueIfValid(const QString& name, float& floatValue);
114  void getBoolValue(const QString& name, bool& boolValue);
115 
116  void setVec3Value(const QString& name, const glm::vec3& vecValue);
117  void getVec3ValueIfValid(const QString& name, glm::vec3& vecValue);
118 
119  void setQuatValue(const QString& name, const glm::quat& quatValue);
120  void getQuatValueIfValid(const QString& name, glm::quat& quatValue);
121 
122  void clear();
123 
124 private:
125  QString getGroupPrefix() const;
126  QString getPath(const QString &value) const;
127 
128  QSharedPointer<Setting::Manager> _manager;
129  QStack<Group> _groups;
130  QString _groupPrefix;
131 };
132 
133 namespace Setting {
134 
143  template <typename T>
144  class Handle : public Interface {
145  public:
146 
152  Handle(const QString& key) : Interface(key) {}
153 
159  Handle(const QStringList& path) : Interface(path.join("/")) {}
160 
167  Handle(const QString& key, const T& defaultValue) : Interface(key), _defaultValue(defaultValue) {}
168 
175  Handle(const QStringList& path, const T& defaultValue) : Handle(path.join("/"), defaultValue) {}
176 
185  static Handle Deprecated(const QString& key) {
186  Handle handle = Handle(key);
187  handle.deprecate();
188  return handle;
189  }
190 
199  static Handle Deprecated(const QStringList& path) {
200  return Deprecated(path.join("/"));
201  }
202 
212  static Handle Deprecated(const QString& key, const T& defaultValue) {
213  Handle handle = Handle(key, defaultValue);
214  handle.deprecate();
215  return handle;
216  }
217 
227  static Handle Deprecated(const QStringList& path, const T& defaultValue) {
228  return Deprecated(path.join("/"), defaultValue);
229  }
230 
231  virtual ~Handle() {
232  deinit();
233  }
234 
240  T get() const {
241  return get(_defaultValue);
242  }
243 
250  T get(const T& other) const {
251  maybeInit();
252  return (_isSet) ? _value : other;
253  }
254 
261  bool isSet() const {
262  maybeInit();
263  return _isSet;
264  }
265 
271  const T& getDefault() const {
272  return _defaultValue;
273  }
274 
279  void reset() {
280  set(_defaultValue);
281  }
282 
290  void set(const T& value) {
291  maybeInit();
292 
293  // qCDebug(settings_handle) << "Setting" << this->getKey() << "to" << value;
294 
295  if ((!_isSet && (value != _defaultValue)) || _value != value) {
296  _value = value;
297  _isSet = true;
298  save();
299  }
300  if (_isDeprecated) {
301  deprecate();
302  }
303  }
304 
311  void remove() {
312  maybeInit();
313  if (_isSet) {
314  _isSet = false;
315  save();
316  }
317  }
318 
319  protected:
320  virtual void setVariant(const QVariant& variant) override;
321  virtual QVariant getVariant() override { return QVariant::fromValue(get()); }
322 
323  private:
324  void deprecate() {
325  if (_isSet) {
326  if (get() != getDefault()) {
327  qCInfo(settings_handle).nospace() << "[DEPRECATION NOTICE] " << _key << "(" << get() << ") has been deprecated, and has no effect";
328  } else {
329  remove();
330  }
331  }
332  _isDeprecated = true;
333  }
334 
335  T _value;
336  const T _defaultValue;
337  bool _isDeprecated{ false };
338  };
339 
340  template <typename T>
341  void Handle<T>::setVariant(const QVariant& variant) {
342  if (variant.canConvert<T>() || std::is_same<T, QVariant>::value) {
343  set(variant.value<T>());
344  }
345  }
346 }
347 
348 #endif // hifi_SettingHandle_h
Handle to a setting of type T.
Definition: SettingHandle.h:144
static Handle Deprecated(const QString &key)
Construct a handle to a deprecated setting.
Definition: SettingHandle.h:185
static Handle Deprecated(const QStringList &path, const T &defaultValue)
Construct a handle to a deprecated setting with a default value.
Definition: SettingHandle.h:227
void reset()
Sets the value to the default.
Definition: SettingHandle.h:279
Handle(const QString &key)
Construct handle to a setting.
Definition: SettingHandle.h:152
T get(const T &other) const
Returns the value of the setting, or 'other' if not found.
Definition: SettingHandle.h:250
Handle(const QStringList &path, const T &defaultValue)
Construct a handle to a setting with a default value.
Definition: SettingHandle.h:175
bool isSet() const
Returns whether the setting is set to a value.
Definition: SettingHandle.h:261
T get() const
Returns the value of the setting, or the default value if not found.
Definition: SettingHandle.h:240
void set(const T &value)
Set the setting to the specified value.
Definition: SettingHandle.h:290
const T & getDefault() const
Returns the default value for this setting.
Definition: SettingHandle.h:271
Handle(const QStringList &path)
Construct a handle to a setting.
Definition: SettingHandle.h:159
Handle(const QString &key, const T &defaultValue)
Construct handle to a setting with a default value.
Definition: SettingHandle.h:167
static Handle Deprecated(const QString &key, const T &defaultValue)
Construct a handle to a deprecated setting with a default value.
Definition: SettingHandle.h:212
static Handle Deprecated(const QStringList &path)
Construct a handle to a deprecated setting.
Definition: SettingHandle.h:199
void remove()
Remove the value from the setting.
Definition: SettingHandle.h:311
QSettings analog.
Definition: SettingHandle.h:56