7#include "utility/module.hpp"
8#include "generator.hpp"
10#include "callback_flags.hpp"
17namespace hi::inline
v1 {
24template<
typename T =
void()>
30template<
typename Result,
typename... Args>
33 static_assert(std::is_same_v<Result, void>,
"Result of a notifier must be void.");
35 using result_type = Result;
36 using callback_proto = Result(Args...);
50 constexpr awaiter_type()
noexcept =
default;
51 constexpr awaiter_type(awaiter_type
const&)
noexcept =
default;
52 constexpr awaiter_type(awaiter_type&&)
noexcept =
default;
53 constexpr awaiter_type& operator=(awaiter_type
const&)
noexcept =
default;
54 constexpr awaiter_type& operator=(awaiter_type&&)
noexcept =
default;
58 [[nodiscard]]
constexpr bool await_ready()
noexcept
63 void await_suspend(std::coroutine_handle<> handle)
noexcept
69 _cbt = _notifier->subscribe(
70 [
this, handle](Args
const&...args) {
78 callback_flags::main | callback_flags::once);
81 constexpr void await_resume()
const noexcept requires(
sizeof...(Args) == 0) {}
83 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) == 1)
85 return std::get<0>(_args);
88 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) > 1)
109 awaiter_type operator co_await() const noexcept
111 return awaiter_type{
const_cast<notifier&
>(*this)};
123 [[nodiscard]] callback_token
126 auto token = std::make_shared<function_type>(
hi_forward(callback));
128 hilet lock = std::scoped_lock(_mutex);
129 _callbacks.emplace_back(token, flags);
140 hilet lock = std::scoped_lock(_mutex);
142 for (
auto& callback : _callbacks) {
143 if (is_synchronous(callback.flags)) {
144 if (
auto func = callback.lock()) {
148 }
else if (is_local(callback.flags)) {
149 loop::local().post_function([=] {
150 if (
auto func = callback.lock()) {
155 }
else if (is_main(callback.flags)) {
156 loop::main().post_function([=] {
157 if (
auto func = callback.lock()) {
162 }
else if (is_timer(callback.flags)) {
163 loop::timer().post_function([=] {
164 if (
auto func = callback.lock()) {
177 if (is_once(callback.flags)) {
185 struct callback_type {
186 weak_callback_token token;
189 [[nodiscard]]
bool expired() const noexcept
191 return token.expired();
194 void reset() noexcept
199 [[nodiscard]] callback_token
lock() const noexcept
205 mutable unfair_mutex _mutex;
211 void clean_up() const noexcept
216 std::erase_if(_callbacks, [](
hilet& item) {
217 return item.expired();
224 mutable bool _notifying =
false;
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:264
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hi_assert_not_null(x,...)
Assert if an expression is not nullptr.
Definition assert.hpp:223
#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:13
callback_flags
Definition callback_flags.hpp:11
A notifier which can be used to call a set of registered callbacks.
Definition notifier.hpp:25
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:124
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:138
True if T is a forwarded type of Forward.
Definition concepts.hpp:130