HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
preferences.hpp
1// Copyright Take Vos 2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#include "URL.hpp"
6#include "datum.hpp"
7#include "log.hpp"
8#include "jsonpath.hpp"
9#include "observable.hpp"
10#include "pickle.hpp"
11#include <typeinfo>
12
13#pragma once
14
15namespace hi::inline v1 {
16class preferences;
17
18namespace detail {
19
21public:
22 preference_item_base(preferences &parent, std::string_view path) noexcept;
23
26 preference_item_base &operator=(preference_item_base const &) = delete;
27 preference_item_base &operator=(preference_item_base &&) = delete;
28 virtual ~preference_item_base() = default;
29
32 virtual void reset() noexcept = 0;
33
36 void load() noexcept;
37
38protected:
39 preferences &_parent;
40 jsonpath _path;
41
46 [[nodiscard]] virtual datum encode() const noexcept = 0;
47
48 virtual void decode(datum const &data) = 0;
49};
50
51template<typename T>
53public:
54 preference_item(preferences &parent, std::string_view path, observable<T> const &value, T init) noexcept :
55 preference_item_base(parent, path), _value(value), _init(std::move(init))
56 {
57 _value_cbt = _value.subscribe([this](auto...) {
58 if (auto tmp = this->encode(); not holds_alternative<std::monostate>(tmp)) {
59 this->_parent.write(_path, this->encode());
60 } else {
61 this->_parent.remove(_path);
62 }
63 });
64 }
65
66 void reset() noexcept override
67 {
68 _value = _init;
69 }
70
71protected:
72 [[nodiscard]] datum encode() const noexcept override
73 {
74 if (*_value != _init) {
75 return hi::pickle<T>{}.encode(*_value);
76 } else {
77 return datum{std::monostate{}};
78 }
79 }
80
81 void decode(datum const &data) override
82 {
83 _value = hi::pickle<T>{}.decode(data);
84 }
85
86private:
87 T _init;
88 observable<T> _value;
89 typename decltype(_value)::token_type _value_cbt;
90};
91
92} // namespace detail
93
112public:
119
126 preferences() noexcept;
127
134 preferences(URL location) noexcept;
135
136 ~preferences();
137 preferences(preferences const &) = delete;
138 preferences(preferences &&) = delete;
139 preferences &operator=(preferences const &) = delete;
140 preferences &operator=(preferences &&) = delete;
141
146 void save() const noexcept;
147
154 void save(URL location) noexcept;
155
160 void load() noexcept;
161
168 void load(URL location) noexcept;
169
172 void reset() noexcept;
173
180 template<typename T>
181 void add(std::string_view path, observable<T> const &item, T init = T{}) noexcept
182 {
183 auto item_ = std::make_unique<detail::preference_item<T>>(*this, path, item, std::move(init));
184 item_->load();
185 _items.push_back(std::move(item_));
186 }
187
188private:
191 URL _location;
192
195 datum _data;
196
200 mutable bool _modified = false;
201
202 loop::timer_token_type _check_modified_cbt;
203
207
208 void _load() noexcept;
209 void _save() const noexcept;
210
213 void check_modified() noexcept;
214
217 void write(jsonpath const &path, datum const value) noexcept;
218
221 datum read(jsonpath const &path) noexcept;
222
225 void remove(jsonpath const &path) noexcept;
226
227 friend class detail::preference_item_base;
228 template<typename T>
229 friend class detail::preference_item;
230};
231
232} // namespace hi::inline v1
STL namespace.
A dynamic data type.
Definition datum.hpp:225
Definition jsonpath.hpp:380
An observable value.
Definition observable.hpp:359
Definition preferences.hpp:20
virtual void reset() noexcept=0
Reset the value.
Definition preferences.hpp:52
void reset() noexcept override
Reset the value.
Definition preferences.hpp:66
user preferences.
Definition preferences.hpp:111
std::mutex mutex
Mutex used to synchronize changes to the preferences.
Definition preferences.hpp:118
preferences() noexcept
Construct a preferences instance.
void load() noexcept
Load the preferences.
Definition URL.hpp:47
T move(T... args)