roo_prefs
API Documentation for roo_prefs
Loading...
Searching...
No Matches
lazy_write_pref.h
Go to the documentation of this file.
1#pragma once
2
3/// Similar to `Pref<T>`, but does not immediately store written data in
4/// persistent storage. Instead, writes with a delay, which depends on whether
5/// the data stabilized or keeps changing.
6///
7/// Depends on the "dejwk/roo_scheduler" library.
8
9#include "roo_prefs/pref.h"
10#include "roo_scheduler.h"
11#include "roo_time.h"
12
13namespace roo_prefs {
14
15template <typename T>
17 public:
18 /// Creates a lazy-write preference. The data is flushed to persistent storage
19 /// using `scheduler`, after it has been stable for at least
20 /// `stable_write_latency` seconds, but no later than
21 /// `unstable_write_latency_s` after the last write.
22 LazyWritePref(Collection& collection, roo_scheduler::Scheduler& scheduler,
23 const char* key, T default_value = T(),
24 uint8_t stable_write_latency_s = 2,
25 uint8_t unstable_write_latency_s = 10);
26
27 bool isSet() const;
28
29 const T& get() const;
30
31 bool set(const T& value);
32
33 bool clear();
34
35 private:
36 bool has_pending_write() const { return flusher_.is_scheduled(); }
37 void maybeFlush();
38
39 Pref<T> pref_;
40 uint8_t stable_write_latency_s_;
41 uint8_t unstable_write_latency_s_;
42 T pending_write_;
43 roo_scheduler::SingletonTask flusher_;
44 uint32_t last_write_ms_;
45 uint32_t last_change_ms_;
46};
47
59
60template <typename T>
62 roo_scheduler::Scheduler& scheduler,
63 const char* key, T default_value,
64 uint8_t stable_write_latency_s,
65 uint8_t unstable_write_latency_s)
66 : pref_(collection, key, std::move(default_value)),
67 stable_write_latency_s_(stable_write_latency_s),
68 unstable_write_latency_s_(unstable_write_latency_s),
69 flusher_(scheduler, [this]() { maybeFlush(); }) {
70 if (unstable_write_latency_s_ < stable_write_latency_s_) {
71 unstable_write_latency_s_ = stable_write_latency_s_;
72 }
73}
74
75template <typename T>
77 return has_pending_write() || pref_.isSet();
78}
79
80template <typename T>
81const T& LazyWritePref<T>::get() const {
82 return has_pending_write() ? pending_write_ : pref_.get();
83}
84
85template <typename T>
86bool LazyWritePref<T>::set(const T& value) {
87 if (pending_write_ == value) return true;
88 pending_write_ = value;
89 last_change_ms_ = roo_time::Uptime::Now().inMillis();
90 if (!has_pending_write()) {
91 flusher_.scheduleAfter(roo_time::Seconds(stable_write_latency_s_));
92 }
93 return true;
94}
95
96template <typename T>
98 uint32_t now = roo_time::Uptime::Now().inMillis();
99 uint32_t ms_elapsed_since_last_write_s = (now - last_write_ms_) / 1000;
100 uint32_t ms_elapsed_since_last_change_s = (now - last_change_ms_) / 1000;
101 if (ms_elapsed_since_last_write_s >= unstable_write_latency_s_ ||
102 ms_elapsed_since_last_change_s >= stable_write_latency_s_) {
103 if (pref_.set(pending_write_)) {
104 last_write_ms_ = now;
105 return;
106 }
107 }
108 /// Reschedule the update.
109 flusher_.scheduleAfter(roo_time::Seconds(stable_write_latency_s_),
110 roo_scheduler::PRIORITY_BACKGROUND);
111}
112
113template <typename T>
115 return pref_.clear();
116}
117
118} // namespace roo_prefs
Collection corresponds to a preferences namespace. Use it to group related preferences.
Definition collection.h:14
LazyWritePref(Collection &collection, roo_scheduler::Scheduler &scheduler, const char *key, T default_value=T(), uint8_t stable_write_latency_s=2, uint8_t unstable_write_latency_s=10)
Creates a lazy-write preference. The data is flushed to persistent storage using scheduler,...
bool set(const T &value)
Persistent preference of a specific type. The preference will store its value in the preferences coll...
Definition pref.h:51
Similar to Pref<T>, but does not immediately store written data in persistent storage....
Definition collection.h:6