HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
observable_base.hpp
1// Copyright 2020 Pokitec
2// All rights reserved.
3
4#pragma once
5
6#include <functional>
7#include "TTauri/Foundation/cpu_utc_clock.hpp"
8#include "TTauri/Foundation/fast_mutex.hpp"
9#include "TTauri/Foundation/notifier.hpp"
10#include "TTauri/Foundation/required.hpp"
11
12namespace tt::detail {
13
28template<typename T>
30public:
31 using callback_type = std::function<void(T const &)>;
32 using time_point = typename hires_utc_clock::time_point;
33 using duration = typename hires_utc_clock::duration;
34
35protected:
36 mutable fast_mutex mutex;
37
38private:
39 T _previous_value;
40 time_point _last_modified;
42
43public:
44 observable_base(observable_base const &) = delete;
46 observable_base &operator=(observable_base const &) = delete;
47 observable_base &operator=(observable_base &&) = delete;
48 virtual ~observable_base() = default;
49
52 observable_base() noexcept :
53 _previous_value(), _last_modified(), notifier() {}
54
57 [[nodiscard]] T previous_value() const noexcept {
58 ttlet lock = std::scoped_lock(mutex);
59 return _previous_value;
60 }
61
64 [[nodiscard]] time_point time_when_last_modified() const noexcept {
65 ttlet lock = std::scoped_lock(mutex);
66 return _last_modified;
67 }
68
71 [[nodiscard]] duration duration_since_last_modified() const noexcept {
72 return cpu_utc_clock::now() - time_when_last_modified();
73 }
74
80 [[nodiscard]] float animation_progress(duration animation_duration) const noexcept {
81 tt_assume(animation_duration.count() != 0);
82
83 return std::clamp(
84 numeric_cast<float>(duration_since_last_modified().count()) / numeric_cast<float>(animation_duration.count()),
85 0.0f,
86 1.0f
87 );
88 }
89
94 [[nodiscard]] virtual T load() const noexcept = 0;
95
98 [[nodiscard]] T load(duration animation_duration) const noexcept {
99 return mix(animation_progress(animation_duration), previous_value(), load());
100 }
101
110 virtual bool store(T const &new_value) noexcept = 0;
111
116 [[nodiscard]] size_t add_callback(callback_type callback) noexcept {
117 return notifier.add(callback);
118 }
119
123 void remove_callback(size_t id) noexcept {
124 notifier.remove(id);
125 }
126
127protected:
128
133 void notify(T const &old_value, T const &new_value) noexcept {
134 {
135 ttlet lock = std::scoped_lock(mutex);
136 _previous_value = old_value;
137 _last_modified = cpu_utc_clock::now();
138 }
139 notifier(new_value);
140 }
141};
142
143}
Observable abstract base class.
Definition observable_base.hpp:29
virtual T load() const noexcept=0
Get the current value.
float animation_progress(duration animation_duration) const noexcept
The relative time since the start of the animation.
Definition observable_base.hpp:80
virtual bool store(T const &new_value) noexcept=0
Set the value.
size_t add_callback(callback_type callback) noexcept
Add a callback as a listener.
Definition observable_base.hpp:116
void remove_callback(size_t id) noexcept
Remove a callback.
Definition observable_base.hpp:123
T previous_value() const noexcept
Get the previous value.
Definition observable_base.hpp:57
duration duration_since_last_modified() const noexcept
Duration since the value was last modified.
Definition observable_base.hpp:71
observable_base() noexcept
Constructor.
Definition observable_base.hpp:52
time_point time_when_last_modified() const noexcept
Time when the value was modified last.
Definition observable_base.hpp:64
Definition fast_mutex.hpp:14
A notifier which can be used to call a set of registred callbacks.
Definition notifier.hpp:21
void remove(size_t id) noexcept
Remove a callback from the notifier.
Definition notifier.hpp:65
size_t add(callback_type callback) noexcept
Add a callback to the notifier.
Definition notifier.hpp:36