7#include "../utility/utility.hpp"
9#include "callback_flags.hpp"
10#include "../macros.hpp"
19namespace hi::inline
v1 {
26template<
typename T =
void()>
32template<
typename Result,
typename... Args>
35 static_assert(std::is_same_v<Result, void>,
"Result of a notifier must be void.");
37 using result_type = Result;
38 using callback_proto = Result(Args...);
52 constexpr awaiter_type()
noexcept =
default;
53 constexpr awaiter_type(awaiter_type
const&)
noexcept =
default;
54 constexpr awaiter_type(awaiter_type&&)
noexcept =
default;
55 constexpr awaiter_type& operator=(awaiter_type
const&)
noexcept =
default;
56 constexpr awaiter_type& operator=(awaiter_type&&)
noexcept =
default;
60 [[nodiscard]]
constexpr bool await_ready()
noexcept
65 void await_suspend(std::coroutine_handle<> handle)
noexcept
67 hi_assert_not_null(_notifier);
71 _cbt = _notifier->subscribe(
72 [
this, handle](Args
const&...args) {
83 constexpr void await_resume()
const noexcept requires(
sizeof...(Args) == 0) {}
85 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) == 1)
87 return std::get<0>(_args);
90 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) > 1)
130 hilet lock = std::scoped_lock(_mutex);
131 _callbacks.emplace_back(token, flags);
136 void loop_local_post_function(F&&) const noexcept;
138 void loop_main_post_function(F&&) const noexcept;
140 void loop_timer_post_function(F&&) const noexcept;
147 void operator()(Args const&...args) const noexcept
149 hilet lock = std::scoped_lock(_mutex);
151 for (
auto& callback : _callbacks) {
152 if (is_synchronous(callback.flags)) {
153 if (
auto func = callback.lock()) {
157 }
else if (is_local(callback.flags)) {
158 loop_local_post_function([=] {
159 if (
auto func = callback.lock()) {
164 }
else if (is_main(callback.flags)) {
165 loop_main_post_function([=] {
166 if (
auto func = callback.lock()) {
171 }
else if (is_timer(callback.flags)) {
172 loop_timer_post_function([=] {
173 if (
auto func = callback.lock()) {
186 if (is_once(callback.flags)) {
194 struct callback_type {
195 weak_callback_token token;
198 [[nodiscard]]
bool expired() const noexcept
200 return token.expired();
203 void reset() noexcept
208 [[nodiscard]] callback_token
lock() const noexcept
214 mutable unfair_mutex _mutex;
218 mutable std::vector<callback_type> _callbacks;
220 void clean_up() const noexcept
222 hi_axiom(_mutex.is_locked());
225 std::erase_if(_callbacks, [](hilet& item) {
226 return item.expired();
233 mutable bool _notifying =
false;
Definition of the unfair_mutex.
DOXYGEN BUG.
Definition algorithm.hpp:16
callback_flags
Definition callback_flags.hpp:14
@ synchronous
Call the function synchronously.
Definition callback_flags.hpp:17
@ once
Call the function once, then automatically unsubscribe.
Definition callback_flags.hpp:33
@ main
Call the function asynchronously from the main thread's loop.
Definition callback_flags.hpp:25
A notifier which can be used to call a set of registered callbacks.
Definition notifier.hpp:27
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:126
constexpr notifier() noexcept=default
Create a notifier.
An awaiter object which can wait on a notifier.
Definition notifier.hpp:50