The event loop library allows components to declare events to which other components can register handlers -- code which will execute when those events occur. This allows loosely coupled components to attach desired behavior to state changes of other components without application involvement. This also simplifies event processing by serializing and deferring code execution to another context.
..only:: SOC_WIFI_SUPPORTED
One common use case is if a high level library is using the WiFi library: it may subscribe to :ref:`events produced by the Wi-Fi subsystem <wifi-programming-model>` directly and act on those events.
..only:: SOC_BT_SUPPORTED
..note::
Various modules of the Bluetooth stack deliver events to applications via dedicated callback functions instead of via the Event Loop Library.
1. A user defines a function that should run when an event is posted to a loop. This function is referred to as the event handler. It should have the same signature as :cpp:type:`esp_event_handler_t`.
2. An event loop is created using :cpp:func:`esp_event_loop_create`, which outputs a handle to the loop of type :cpp:type:`esp_event_loop_handle_t`. Event loops created using this API are referred to as user event loops. There is, however, a special type of event loop called the default event loop which are discussed :ref:`here <esp-event-default-loops>`.
3. Components register event handlers to the loop using :cpp:func:`esp_event_handler_register_with`. Handlers can be registered with multiple loops, more on that :ref:`here <esp-event-handler-registration>`.
4. Event sources post an event to the loop using :cpp:func:`esp_event_post_to`.
5. Components wanting to remove their handlers from being called can do so by unregistering from the loop using :cpp:func:`esp_event_handler_unregister_with`.
6. Event loops which are no longer needed can be deleted using :cpp:func:`esp_event_loop_delete`.
In IDF, the base identifiers for system events are uppercase and are postfixed with ``_EVENT``. For example, the base for Wi-Fi events is declared and defined
In general, an event handler run by an event loop is *not allowed to do any (un)registering activity on that event loop*. There is one exception, though: un-registering itself is allowed for the handler. E.g., it is possible to do the following:
The general rule is that for handlers that match a certain posted event during dispatch, those which are registered first also gets executed first. The user can then control which handlers get executed first by
registering them before other handlers, provided that all registrations are performed using a single task.
If the user plans to take advantage of this behavior, caution must be exercised if there are multiple tasks registering handlers. While the 'first registered, first executed'
behavior still holds true, the task which gets executed first will also get their handlers registered first. Handlers registered one after the other by a single task
will still be dispatched in the order relative to each other, but if that task gets pre-empted in between registration by another task which also registers handlers; then during dispatch those
The function :cpp:func:`esp_event_dump` can be used to output the collected statistics to a file stream. More details on the information included in the dump
can be found in the :cpp:func:`esp_event_dump` API Reference.
Examples on using the ``esp_event`` library can be found in :example:`system/esp_event`. The examples cover event declaration, loop creation, handler registration and unregistration and event posting.
Other examples which also adopt esp_event library:
*:example:`NMEA Parser <peripherals/uart/nmea0183_parser>`, which will decode the statements received from GPS.