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) {
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)
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)) {
150 if (
auto func = callback.lock()) {
155 }
else if (is_main(callback.flags)) {
157 if (
auto func = callback.lock()) {
162 }
else if (is_timer(callback.flags)) {
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;
209 mutable std::vector<callback_type> _callbacks;
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:279
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hi_assert_not_null(x,...)
Assert if an expression is not nullptr.
Definition assert.hpp:238
#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
@ synchronous
Call the function synchronously.
Definition callback_flags.hpp:14
@ once
Call the function once, then automatically unsubscribe.
Definition callback_flags.hpp:30
@ main
Call the function asynchronously from the main thread's loop.
Definition callback_flags.hpp:22
static hi_no_inline loop & timer() noexcept
Get or create the timer event-loop.
Definition loop.hpp:153
static hi_no_inline loop & local() noexcept
Get or create the thread-local loop.
Definition loop.hpp:124
static hi_no_inline loop & main() noexcept
Get or create the main-loop.
Definition loop.hpp:137
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
An awaiter object which can wait on a notifier.
Definition notifier.hpp:48
True if T is a forwarded type of Forward.
Definition concepts.hpp:130