|
|
@ -174,4 +174,110 @@ namespace Heck { |
|
|
|
DeliverCallback deliver_cb_{}; |
|
|
|
}; |
|
|
|
} // namespace Heck
|
|
|
|
|
|
|
|
namespace Heck { |
|
|
|
template<typename T> class Cache { |
|
|
|
|
|
|
|
public: |
|
|
|
using UpdateCallback = std::function<T(void)>; |
|
|
|
using NotifyChangeCallback = std::function<void(Cache<T>&)>; |
|
|
|
|
|
|
|
Cache() = delete; |
|
|
|
~Cache() = default; |
|
|
|
|
|
|
|
explicit Cache(UpdateCallback update_cb, NotifyChangeCallback notify_change_cb) |
|
|
|
{ |
|
|
|
init(update_cb, notify_change_cb); |
|
|
|
} |
|
|
|
|
|
|
|
Cache(Cache&) = delete; |
|
|
|
Cache& operator=(Cache) = delete; |
|
|
|
|
|
|
|
Cache(Cache&&) = delete; |
|
|
|
Cache& operator=(Cache&&) = delete; |
|
|
|
|
|
|
|
T read() |
|
|
|
{ |
|
|
|
return val_current_; |
|
|
|
} |
|
|
|
|
|
|
|
void set_update_callback(UpdateCallback cb) |
|
|
|
{ |
|
|
|
update_cb_ = cb; |
|
|
|
} |
|
|
|
|
|
|
|
void set_notify_change_callback(NotifyChangeCallback cb) |
|
|
|
{ |
|
|
|
notify_change_cb_ = cb; |
|
|
|
} |
|
|
|
|
|
|
|
bool update_and_notify_change() |
|
|
|
{ |
|
|
|
T val_fetched{ update_cb_() }; |
|
|
|
if (val_fetched != val_current_) { |
|
|
|
val_current_ = val_fetched; |
|
|
|
notify_change_cb_(*this); |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
bool update_and_notify_change_fuzzy(T min_deviation) |
|
|
|
{ |
|
|
|
T val_fetched{ update_cb_() }; |
|
|
|
if (std::abs(val_fetched - val_current_) >= min_deviation) { |
|
|
|
val_current_ = val_fetched; |
|
|
|
notify_change_cb_(*this); |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
void init(UpdateCallback fetch_cb, NotifyChangeCallback deliver_cb) |
|
|
|
{ |
|
|
|
set_update_callback(fetch_cb); |
|
|
|
set_notify_change_callback(deliver_cb); |
|
|
|
} |
|
|
|
|
|
|
|
T val_current_{}; |
|
|
|
UpdateCallback update_cb_{}; |
|
|
|
NotifyChangeCallback notify_change_cb_{}; |
|
|
|
}; |
|
|
|
|
|
|
|
struct DigitalIn { |
|
|
|
public: |
|
|
|
DigitalIn() = default; |
|
|
|
~DigitalIn() = default; |
|
|
|
|
|
|
|
DigitalIn(u8 daisy_pin) |
|
|
|
{ |
|
|
|
init(daisy_pin); |
|
|
|
} |
|
|
|
|
|
|
|
DigitalIn(DigitalIn&) = delete; |
|
|
|
DigitalIn& operator=(DigitalIn&) = delete; |
|
|
|
|
|
|
|
DigitalIn(DigitalIn&&) = delete; |
|
|
|
DigitalIn& operator=(DigitalIn&&) = delete; |
|
|
|
|
|
|
|
void init(u8 daisy_pin) |
|
|
|
{ |
|
|
|
gpio_.Init(ld::DaisySeed::GetPin(daisy_pin), ld::GPIO::Mode::INPUT, ld::GPIO::Pull::PULLUP); |
|
|
|
} |
|
|
|
|
|
|
|
bool read() |
|
|
|
{ |
|
|
|
return !gpio_.Read(); |
|
|
|
} |
|
|
|
|
|
|
|
Cache<bool> cache{ [&]() -> bool { return read(); }, [](Cache<bool>&) {} }; |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
ld::GPIO gpio_{}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
} // namespace Heck
|
|
|
|
#endif // HECK_DAISY_UTILS_HH`
|