21#include <idfxx/chrono>
50#define IDFXX_EVENT_DEFINE_BASE(name, id_enum) \
51 inline constexpr char _##name##_base[] = #name; \
52 inline constexpr ::idfxx::event_base<id_enum> name { \
58template<
typename IdEnum>
61template<
typename IdEnum>
83template<
typename IdEnum>
118 [[nodiscard]]
constexpr esp_event_base_t
idf_base() const noexcept {
return _base; }
133 esp_event_base_t _base;
147template<
typename IdEnum>
158 [[nodiscard]]
constexpr esp_event_base_t
idf_base()
const {
return base.idf_base(); }
164 [[nodiscard]]
constexpr int32_t
idf_id()
const {
return static_cast<int32_t
>(
id); }
168template<
typename IdEnum>
172template<
typename IdEnum>
185template<
typename IdEnum>
220#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
281#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
292 static std::unique_ptr<user_event_loop>
make_user(
size_t queue_size = 32);
333#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
345 template<
typename IdEnum>
359 template<
typename IdEnum>
372 template<
typename IdEnum>
385 template<
typename IdEnum>
397 template<
typename IdEnum>
409 template<
typename IdEnum>
417#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
440#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
452 template<
typename IdEnum>
471 template<
typename IdEnum,
typename Rep,
typename Period>
477 const std::chrono::duration<Rep, Period>&
timeout
492 template<
typename IdEnum>
510 template<
typename IdEnum,
typename Rep,
typename Period>
527 template<
typename IdEnum>
530 if (_handle ==
nullptr) {
531 return wrap(esp_event_post(base.
idf_base(),
static_cast<int32_t
>(
id), data, size, portMAX_DELAY));
533 return wrap(esp_event_post_to(_handle, base.
idf_base(),
static_cast<int32_t
>(
id), data, size, portMAX_DELAY));
549 template<
typename IdEnum,
typename Rep,
typename Period>
555 const std::chrono::duration<Rep, Period>&
timeout
558 if (_handle ==
nullptr) {
559 return wrap(esp_event_post(base.
idf_base(),
static_cast<int32_t
>(
id), data, size, ticks));
561 return wrap(esp_event_post_to(_handle, base.
idf_base(),
static_cast<int32_t
>(
id), data, size, ticks));
573 template<
typename IdEnum>
590 template<
typename IdEnum,
typename Rep,
typename Period>
595 const std::chrono::duration<Rep, Period>&
timeout
604 [[nodiscard]] esp_event_loop_handle_t
idf_handle()
const {
return _handle; }
626 esp_event_loop_handle_t loop,
627 esp_event_base_t base,
629 std::move_only_function<
void(esp_event_base_t, int32_t,
void*)
const> callback
632 template<
typename IdEnum>
634 register_listener(esp_event_loop_handle_t loop, esp_event_base_t base, int32_t
id,
event_callback<IdEnum> callback);
637 esp_event_loop_handle_t loop,
638 esp_event_handler_instance_t instance,
639 esp_event_base_t base,
643 esp_event_loop_handle_t _handle;
666 esp_event_loop_handle_t loop,
667 esp_event_handler_instance_t instance,
668 esp_event_base_t base,
672 , _instance(instance)
676 esp_event_loop_handle_t _loop =
nullptr;
677 esp_event_handler_instance_t _instance =
nullptr;
678 esp_event_base_t _base =
nullptr;
706 : _handle(other._handle) {
714 if (
this != &other) {
716 _handle = other._handle;
749 [[nodiscard]] explicit operator
bool() const noexcept {
return _handle._instance !=
nullptr; }
782#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
798 template<
typename Rep,
typename Period>
799 void run(
const std::chrono::duration<Rep, Period>& duration) {
814 template<
typename Rep,
typename Period>
833#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
836 return std::move(
result).transform_error([](
auto ec) -> std::error_code {
throw std::system_error(ec); }).value();
841 return std::move(
result).transform_error([](
auto ec) -> std::error_code {
throw std::system_error(ec); }).value();
844template<
typename IdEnum>
850template<
typename IdEnum>
856template<
typename IdEnum>
867template<
typename IdEnum>
869 esp_event_loop_handle_t loop,
870 esp_event_base_t base,
874 return register_listener(loop, base,
id, [cb = std::move(callback)](esp_event_base_t b, int32_t i,
void* data) {
879template<
typename IdEnum>
885 return register_listener<IdEnum>(_handle, base.
idf_base(),
static_cast<int32_t
>(
id), std::move(callback));
888template<
typename IdEnum>
891 return register_listener<IdEnum>(_handle, base.
idf_base(), ESP_EVENT_ANY_ID, std::move(callback));
894template<
typename IdEnum>
Typed event base template.
constexpr esp_event_base_t idf_base() const noexcept
Returns the underlying ESP-IDF event base.
constexpr event_base(esp_event_base_t base) noexcept
Constructs from an ESP-IDF event base pointer.
IdEnum id_type
The enum type for event IDs.
Handle to a registered event listener.
listener_handle()=default
Default constructor creates an invalid handle.
RAII handle for event listener registration.
unique_listener_handle() noexcept=default
Constructs an empty handle.
unique_listener_handle & operator=(unique_listener_handle &&other) noexcept
Move assignment.
listener_handle release() noexcept
Releases ownership without removing the listener.
unique_listener_handle(const unique_listener_handle &)=delete
~unique_listener_handle()
Destructor.
unique_listener_handle & operator=(const unique_listener_handle &)=delete
unique_listener_handle(unique_listener_handle &&other) noexcept
Move constructor.
void reset() noexcept
Removes the listener and resets to empty.
Base class for event loops.
event_loop(event_loop &&)=delete
void post(event_base< IdEnum > base, IdEnum id, const void *data, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Posts a typed event with a timeout.
result< void > try_listener_remove(listener_handle handle)
Removes a listener by handle.
result< void > try_post(event_base< IdEnum > base, IdEnum id, const void *data, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Posts a typed event with a timeout.
void post(event_type< IdEnum > event, const void *data=nullptr, size_t size=0)
Posts a typed event via event_type, waiting indefinitely.
static void destroy_system()
Destroys the system (default) event loop.
void post(event_type< IdEnum > event, const void *data, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Posts a typed event via event_type with a timeout.
esp_event_loop_handle_t idf_handle() const
Returns the underlying ESP-IDF event loop handle.
static void create_system()
Creates the system (default) event loop.
event_loop & operator=(const event_loop &)=delete
result< void > try_post(event_base< IdEnum > base, IdEnum id, const void *data=nullptr, size_t size=0)
Posts a typed event, waiting indefinitely.
static result< std::unique_ptr< event_loop > > try_make_user(task_config task, size_t queue_size=32)
Creates a user event loop with a dedicated dispatch task.
static event_loop & system()
Returns a reference to the system (default) event loop.
event_loop(esp_event_loop_handle_t handle)
Constructs an event_loop with the given handle.
void post(event_base< IdEnum > base, IdEnum id, const void *data=nullptr, size_t size=0)
Posts a typed event, waiting indefinitely.
result< void > try_post(event_type< IdEnum > event, const void *data, size_t size, const std::chrono::duration< Rep, Period > &timeout)
Posts a typed event via event_type with a timeout.
static result< void > try_destroy_system()
Destroys the system (default) event loop.
static result< void > try_create_system()
Creates the system (default) event loop.
event_loop(const event_loop &)=delete
event_loop & operator=(event_loop &&)=delete
result< void > try_post(event_type< IdEnum > event, const void *data=nullptr, size_t size=0)
Posts a typed event via event_type, waiting indefinitely.
static result< std::unique_ptr< user_event_loop > > try_make_user(size_t queue_size=32)
Creates a user event loop without a dedicated task.
virtual ~event_loop()
Virtual destructor.
Task lifecycle management.
User-created event loop with manual dispatch.
user_event_loop & operator=(user_event_loop &&)=delete
result< void > try_run(const std::chrono::duration< Rep, Period > &duration)
Dispatches pending events.
user_event_loop(user_event_loop &&)=delete
user_event_loop & operator=(const user_event_loop &)=delete
user_event_loop(const user_event_loop &)=delete
void run(const std::chrono::duration< Rep, Period > &duration)
Dispatches pending events.
constexpr TickType_t ticks(const std::chrono::duration< Rep, Period > &d)
Converts a std::chrono duration to TickType_t ticks.
std::move_only_function< void(event_base< IdEnum > base, IdEnum id, void *event_data) const > event_callback
Callback type for event listeners.
void listener_remove(listener_handle handle)
Removes a listener by handle.
listener_handle listener_add(event_base< IdEnum > base, IdEnum id, event_callback< std::type_identity_t< IdEnum > > callback)
Registers a typed listener for a specific event.
static std::unique_ptr< user_event_loop > make_user(size_t queue_size=32)
Creates a user event loop without a dedicated task.
constexpr event_type< IdEnum > operator()(IdEnum id) const
Creates an event_type combining this base with a specific ID.
result< listener_handle > try_listener_add(event_base< IdEnum > base, IdEnum id, event_callback< std::type_identity_t< IdEnum > > callback)
Registers a typed listener for a specific event.
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
@ timeout
Operation timed out.
std::expected< T, std::error_code > result
result type wrapping a value or error code.
result< void > wrap(esp_err_t e)
Wraps an esp_err_t into a result<void>.
Configuration for a dedicated event dispatch task.
unsigned int priority
Priority for the task.
size_t stack_size
Stack size for the task.
std::string_view name
Name of the task.
std::optional< core_id > core_affinity
Core affinity for the task.
Combines an event base with a specific event ID.
constexpr esp_event_base_t idf_base() const
Returns the underlying ESP-IDF event base.
constexpr int32_t idf_id() const
Returns the event ID as an int32_t.
event_base< IdEnum > base
The event base.