HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
observable_base.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#pragma once
6
7#include <functional>
8#include "../cpu_utc_clock.hpp"
9#include "../unfair_mutex.hpp"
10#include "../notifier.hpp"
11#include "../required.hpp"
12
13namespace tt::detail {
14
29template<typename T>
31public:
32 using value_type = T;
33 using notifier_type = notifier<void()>;
34 using callback_type = typename notifier_type::callback_type;
35 using callback_ptr_type = typename notifier_type::callback_ptr_type;
36 using time_point = typename hires_utc_clock::time_point;
37 using duration = typename hires_utc_clock::duration;
38
39 observable_base(observable_base const &) = delete;
41 observable_base &operator=(observable_base const &) = delete;
42 observable_base &operator=(observable_base &&) = delete;
43 virtual ~observable_base() = default;
44
47 observable_base() noexcept : _previous_value(), _last_modified(), _notifier() {}
48
51 [[nodiscard]] value_type previous_value() const noexcept
52 {
53 ttlet lock = std::scoped_lock(_mutex);
54 return _previous_value;
55 }
56
59 [[nodiscard]] time_point time_when_last_modified() const noexcept
60 {
61 ttlet lock = std::scoped_lock(_mutex);
62 return _last_modified;
63 }
64
67 [[nodiscard]] duration duration_since_last_modified() const noexcept
68 {
69 return cpu_utc_clock::now() - time_when_last_modified();
70 }
71
77 [[nodiscard]] float animation_progress(duration animation_duration) const noexcept
78 {
79 tt_axiom(animation_duration.count() != 0);
80
81 return std::clamp(
82 narrow_cast<float>(duration_since_last_modified().count()) / narrow_cast<float>(animation_duration.count()),
83 0.0f,
84 1.0f);
85 }
86
91 [[nodiscard]] virtual value_type load() const noexcept = 0;
92
95 [[nodiscard]] value_type load(duration animation_duration) const noexcept
96 {
97 return mix(animation_progress(animation_duration), previous_value(), load());
98 }
99
108 virtual bool store(value_type const &new_value) noexcept = 0;
109
114 template<typename Callback>
115 [[nodiscard]] callback_ptr_type subscribe(Callback &&callback) noexcept
116 {
117 return _notifier.subscribe(std::forward<Callback>(callback));
118 }
119
123 void unsubscribe(callback_ptr_type callback_ptr) noexcept
124 {
125 _notifier.unsubscribe(callback_ptr);
126 }
127
128protected:
129 mutable unfair_mutex _mutex;
130
135 void notify(value_type const &old_value, value_type const &new_value) noexcept
136 {
137 {
138 ttlet lock = std::scoped_lock(_mutex);
139 _previous_value = old_value;
140 _last_modified = cpu_utc_clock::now();
141 }
142 _notifier();
143 }
144
145private:
146 value_type _previous_value;
147 time_point _last_modified;
148 notifier_type _notifier;
149};
150
151} // namespace tt::detail
Observable abstract base class.
Definition observable_base.hpp:30
void unsubscribe(callback_ptr_type callback_ptr) noexcept
Remove a callback.
Definition observable_base.hpp:123
virtual bool store(value_type const &new_value) noexcept=0
Set the value.
float animation_progress(duration animation_duration) const noexcept
The relative time since the start of the animation.
Definition observable_base.hpp:77
value_type previous_value() const noexcept
Get the previous value.
Definition observable_base.hpp:51
callback_ptr_type subscribe(Callback &&callback) noexcept
Add a callback as a listener.
Definition observable_base.hpp:115
virtual value_type load() const noexcept=0
Get the current value.
duration duration_since_last_modified() const noexcept
Duration since the value was last modified.
Definition observable_base.hpp:67
observable_base() noexcept
Constructor.
Definition observable_base.hpp:47
time_point time_when_last_modified() const noexcept
Time when the value was modified last.
Definition observable_base.hpp:59
An unfair mutex This is a fast implementation of a mutex which does not fairly arbitrate between mult...
Definition unfair_mutex.hpp:32