8#include "generator.hpp"
10#include "callback_flags.hpp"
11#include "unfair_mutex.hpp"
18namespace hi::inline
v1 {
25template<
typename T =
void()>
31template<
typename Result,
typename... Args>
34 static_assert(std::is_same_v<Result, void>,
"Result of a notifier must be void.");
36 using result_type = Result;
37 using callback_proto = Result(Args...);
51 constexpr awaiter_type()
noexcept =
default;
52 constexpr awaiter_type(awaiter_type
const&)
noexcept =
default;
53 constexpr awaiter_type(awaiter_type&&)
noexcept =
default;
54 constexpr awaiter_type& operator=(awaiter_type
const&)
noexcept =
default;
55 constexpr awaiter_type& operator=(awaiter_type&&)
noexcept =
default;
59 [[nodiscard]]
constexpr bool await_ready()
noexcept
64 void await_suspend(std::coroutine_handle<> handle)
noexcept
70 _cbt = _notifier->subscribe(
71 [
this, handle](Args
const&...args) {
79 callback_flags::main | callback_flags::once);
82 constexpr void await_resume()
const noexcept requires(
sizeof...(Args) == 0) {}
84 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) == 1)
86 return std::get<0>(_args);
89 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) > 1)
110 awaiter_type operator co_await() const noexcept
112 return awaiter_type{
const_cast<notifier&
>(*this)};
124 [[nodiscard]] callback_token
127 auto token = std::make_shared<function_type>(
hi_forward(callback));
129 hilet lock = std::scoped_lock(_mutex);
130 _callbacks.emplace_back(token, flags);
141 hilet lock = std::scoped_lock(_mutex);
143 for (
auto& callback : _callbacks) {
144 if (is_synchronous(callback.flags)) {
145 if (
auto func = callback.lock()) {
149 }
else if (is_local(callback.flags)) {
150 loop::local().post_function([=] {
151 if (
auto func = callback.lock()) {
156 }
else if (is_main(callback.flags)) {
157 loop::main().post_function([=] {
158 if (
auto func = callback.lock()) {
163 }
else if (is_timer(callback.flags)) {
164 loop::timer().post_function([=] {
165 if (
auto func = callback.lock()) {
178 if (is_once(callback.flags)) {
186 struct callback_type {
187 weak_callback_token token;
190 [[nodiscard]]
bool expired() const noexcept
192 return token.expired();
195 void reset() noexcept
200 [[nodiscard]] callback_token
lock() const noexcept
206 mutable unfair_mutex _mutex;
212 void clean_up() const noexcept
217 std::erase_if(_callbacks, [](
hilet& item) {
218 return item.expired();
225 mutable bool _notifying =
false;
#define hi_axiom(expression)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
#define hi_assert_not_null(x)
Assert if an expression is not nullptr.
Definition assert.hpp:118
#define hi_no_default()
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:145
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition utility.hpp:29
DOXYGEN BUG.
Definition algorithm.hpp:15
callback_flags
Definition callback_flags.hpp:12
A notifier which can be used to call a set of registered callbacks.
Definition notifier.hpp:26
callback_token subscribe(forward_of< callback_proto > auto &&callback, callback_flags flags=callback_flags::synchronous) noexcept
Add a callback to the notifier.
Definition notifier.hpp:125
constexpr notifier() noexcept=default
Create a notifier.
void operator()(Args const &...args) const noexcept
Call the subscribed callbacks with the given arguments.
Definition notifier.hpp:139
True if T is a forwarded type of Forward.
Definition concepts.hpp:130