8#include "generator.hpp"
10#include "callback_flags.hpp"
16namespace hi::inline v1 {
23template<
typename T =
void()>
29template<
typename Result,
typename... Args>
32 static_assert(std::is_same_v<Result, void>,
"Result of a notifier must be void.");
34 using result_type = Result;
48 constexpr awaiter_type()
noexcept =
default;
49 constexpr awaiter_type(awaiter_type
const&)
noexcept =
default;
50 constexpr awaiter_type(awaiter_type&&)
noexcept =
default;
51 constexpr awaiter_type& operator=(awaiter_type
const&)
noexcept =
default;
52 constexpr awaiter_type& operator=(awaiter_type&&)
noexcept =
default;
56 [[nodiscard]]
constexpr bool await_ready()
noexcept
61 void await_suspend(std::coroutine_handle<> handle)
noexcept
63 hi_axiom(_notifier !=
nullptr);
67 _cbt = _notifier->subscribe(callback_flags::main | callback_flags::once, [
this, handle](Args
const&...args) {
77 constexpr void await_resume()
const noexcept requires(
sizeof...(Args) == 0) {}
79 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) == 1)
81 return std::get<0>(_args);
84 constexpr auto await_resume()
const noexcept requires(
sizeof...(Args) > 1)
89 private :
notifier *_notifier =
nullptr;
104 awaiter_type operator co_await() const noexcept
106 return awaiter_type{
const_cast<notifier&
>(*this)};
117 [[nodiscard]]
token_type subscribe(callback_flags flags, std::invocable<Args...>
auto&& callback)
noexcept
119 auto token = std::make_shared<function_type>(
hi_forward(callback));
120 _callbacks.emplace_back(token, flags);
124 [[nodiscard]] token_type subscribe(std::invocable<Args...>
auto&& callback)
noexcept
126 return subscribe(callback_flags::synchronous,
hi_forward(callback));
136 for (
auto& callback : _callbacks) {
137 if (is_synchronous(callback.flags)) {
138 if (
auto func = callback.lock()) {
142 }
else if (is_local(callback.flags)) {
143 loop::local().post_function([=] {
144 if (
auto func = callback.lock()) {
149 }
else if (is_main(callback.flags)) {
150 loop::main().post_function([=] {
151 if (
auto func = callback.lock()) {
156 }
else if (is_timer(callback.flags)) {
157 loop::timer().post_function([=] {
158 if (
auto func = callback.lock()) {
171 if (is_once(callback.flags)) {
179 struct callback_type {
180 weak_token_type token;
181 callback_flags flags;
183 [[nodiscard]]
bool expired() const noexcept
185 return token.expired();
188 void reset() noexcept
193 [[nodiscard]] token_type
lock() const noexcept
203 void clean_up() const noexcept
206 std::erase_if(_callbacks, [](
hilet& item) {
207 return item.expired();
211#if HI_BUILD_TYPE == HI_BT_DEBUG
214 mutable bool _notifying =
false;
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
#define hi_forward(x)
Forward a value, based on the decltype of the value.
Definition required.hpp:29
A notifier which can be used to call a set of registered callbacks.
Definition notifier.hpp:24
constexpr notifier() noexcept=default
Create a notifier.
token_type subscribe(callback_flags flags, std::invocable< Args... > auto &&callback) noexcept
Add a callback to the notifier.
Definition notifier.hpp:117
void operator()(Args const &...args) const noexcept
Call the subscribed callbacks with the given arguments.
Definition notifier.hpp:134