Flipper Zero Firmware
Loading...
Searching...
No Matches
event_loop.h File Reference

Furi Event Loop. More...

#include "base.h"

Go to the source code of this file.

Typedefs

typedef struct FuriEventLoop FuriEventLoop
 Anonymous message queue type.
 
typedef void(* FuriEventLoopTickCallback) (void *context)
 Tick callback type.
 
typedef void(* FuriEventLoopPendingCallback) (void *context)
 Timer callback type for functions to be called in a deferred manner.
 
typedef void FuriEventLoopObject
 
typedef bool(* FuriEventLoopEventCallback) (FuriEventLoopObject *object, void *context)
 Callback type for event loop events.
 
typedef struct FuriMessageQueue FuriMessageQueue
 Opaque message queue type.
 
typedef struct FuriStreamBuffer FuriStreamBuffer
 Opaque stream buffer type.
 
typedef struct FuriSemaphore FuriSemaphore
 Opaque semaphore type.
 
typedef struct FuriMutex FuriMutex
 Opaque mutex type.
 

Enumerations

enum  FuriEventLoopEvent {
  FuriEventLoopEventIn = 0x00000001U , FuriEventLoopEventOut = 0x00000002U , FuriEventLoopEventMask = 0x00000003U , FuriEventLoopEventFlagEdge = 0x00000004U ,
  FuriEventLoopEventFlagOnce = 0x00000008U , FuriEventLoopEventFlagMask = 0xFFFFFFFCU , FuriEventLoopEventReserved = UINT32_MAX
}
 Enumeration of event types, flags and masks. More...
 

Functions

FuriEventLoopfuri_event_loop_alloc (void)
 Allocate Event Loop instance.
 
void furi_event_loop_free (FuriEventLoop *instance)
 Free Event Loop instance.
 
void furi_event_loop_run (FuriEventLoop *instance)
 Continuously poll for events.
 
void furi_event_loop_stop (FuriEventLoop *instance)
 Stop Event Loop instance.
 
void furi_event_loop_tick_set (FuriEventLoop *instance, uint32_t interval, FuriEventLoopTickCallback callback, void *context)
 Set Event Loop tick callback.
 
void furi_event_loop_pend_callback (FuriEventLoop *instance, FuriEventLoopPendingCallback callback, void *context)
 Call a function when all preceding timer commands are processed.
 
void furi_event_loop_subscribe_message_queue (FuriEventLoop *instance, FuriMessageQueue *message_queue, FuriEventLoopEvent event, FuriEventLoopEventCallback callback, void *context)
 Subscribe to message queue events.
 
void furi_event_loop_subscribe_stream_buffer (FuriEventLoop *instance, FuriStreamBuffer *stream_buffer, FuriEventLoopEvent event, FuriEventLoopEventCallback callback, void *context)
 Subscribe to stream buffer events.
 
void furi_event_loop_subscribe_semaphore (FuriEventLoop *instance, FuriSemaphore *semaphore, FuriEventLoopEvent event, FuriEventLoopEventCallback callback, void *context)
 Subscribe to semaphore events.
 
void furi_event_loop_subscribe_mutex (FuriEventLoop *instance, FuriMutex *mutex, FuriEventLoopEvent event, FuriEventLoopEventCallback callback, void *context)
 Subscribe to mutex events.
 
void furi_event_loop_unsubscribe (FuriEventLoop *instance, FuriEventLoopObject *object)
 Unsubscribe from events (common)
 

Detailed Description

Furi Event Loop.

        This module is designed to handle application event loop in fully
        asynchronous, reactive nature. On the low level this modules is
        inspired by epoll/kqueue concept, on the high level by asyncio
        event loop.

        This module is trying to best fit into Furi OS, so we don't
        provide any compatibility with other event driven APIs. But
        programming concepts are the same, except some runtime
        limitations from our side.

Typedef Documentation

◆ FuriEventLoopEventCallback

typedef bool(* FuriEventLoopEventCallback) (FuriEventLoopObject *object, void *context)

Callback type for event loop events.

Parameters
objectThe object that triggered the event
contextThe context that was provided upon subscription
Returns
true if event was processed, false if we need to delay processing

◆ FuriEventLoopPendingCallback

typedef void(* FuriEventLoopPendingCallback) (void *context)

Timer callback type for functions to be called in a deferred manner.

Parameters
[in,out]contextpointer to a user-specific object that was provided during furi_event_loop_pend_callback() call

◆ FuriEventLoopTickCallback

typedef void(* FuriEventLoopTickCallback) (void *context)

Tick callback type.

Parameters
contextThe context for callback

Enumeration Type Documentation

◆ FuriEventLoopEvent

Enumeration of event types, flags and masks.

Only one event direction (In or Out) can be used per subscription. An object can have no more than one subscription for each direction.

Additional flags that modify the behaviour can be set using the bitwise OR operation (see flag description).

Enumerator
FuriEventLoopEventIn 

Subscribe to In events.

In events occur on the following conditions:

  • One or more items were inserted into a FuriMessageQueue,
  • Enough data has been written to a FuriStreamBuffer,
  • A FuriSemaphore has been released at least once,
  • A FuriMutex has been released.
FuriEventLoopEventOut 

Subscribe to Out events.

Out events occur on the following conditions:

  • One or more items were removed from a FuriMessageQueue,
  • Any amount of data has been read out of a FuriStreamBuffer,
  • A FuriSemaphore has been acquired at least once,
  • A FuriMutex has been acquired.
FuriEventLoopEventMask 

Special value containing the event direction bits, used internally.

FuriEventLoopEventFlagEdge 

Use edge triggered events.

By default, level triggered events are used. A level above zero is reported based on the following conditions:

In events:

  • a FuriMessageQueue contains one or more items,
  • a FuriStreamBuffer contains one or more bytes,
  • a FuriSemaphore can be acquired at least once,
  • a FuriMutex can be acquired.

Out events:

  • a FuriMessageQueue has at least one item of free space,
  • a FuriStreamBuffer has at least one byte of free space,
  • a FuriSemaphore has been acquired at least once,
  • a FuriMutex has been acquired.

If this flag is NOT set, the event will be generated repeatedly until the level becomes zero (e.g. all items have been removed from a FuriMessageQueue in case of the "In" event, etc.)

If this flag IS set, then the above check is skipped and the event is generated ONLY when a change occurs, with the event direction (In or Out) taken into account.

FuriEventLoopEventFlagOnce 

Automatically unsubscribe from events after one time.

By default, events will be generated each time the specified conditions have been met. If this flag IS set, the event subscription will be cancelled upon the first occurred event and no further events will be generated.

FuriEventLoopEventFlagMask 

Special value containing the event flag bits, used internally.

FuriEventLoopEventReserved 

Special value to force the enum to 32-bit values.

Function Documentation

◆ furi_event_loop_alloc()

FuriEventLoop * furi_event_loop_alloc ( void )

Allocate Event Loop instance.

Couple things to keep in mind:

  • You can have 1 event_loop per 1 thread
  • You can not use event_loop instance in the other thread
  • Do not use blocking API to query object delegated to Event Loop
Returns
The Event Loop instance

◆ furi_event_loop_free()

void furi_event_loop_free ( FuriEventLoop * instance)

Free Event Loop instance.

Parameters
instanceThe Event Loop instance

◆ furi_event_loop_pend_callback()

void furi_event_loop_pend_callback ( FuriEventLoop * instance,
FuriEventLoopPendingCallback callback,
void * context )

Call a function when all preceding timer commands are processed.

This function may be useful to call another function when the event loop has been started.

Parameters
[in,out]instancepointer to the current FuriEventLoop instance
[in]callbackpointer to the callback to be executed when previous commands have been processed
[in,out]contextpointer to a user-specific object (will be passed to the callback)

◆ furi_event_loop_run()

void furi_event_loop_run ( FuriEventLoop * instance)

Continuously poll for events.

Can be stopped with furi_event_loop_stop

Parameters
instanceThe Event Loop instance

◆ furi_event_loop_stop()

void furi_event_loop_stop ( FuriEventLoop * instance)

Stop Event Loop instance.

Parameters
instanceThe Event Loop instance

◆ furi_event_loop_subscribe_message_queue()

void furi_event_loop_subscribe_message_queue ( FuriEventLoop * instance,
FuriMessageQueue * message_queue,
FuriEventLoopEvent event,
FuriEventLoopEventCallback callback,
void * context )

Subscribe to message queue events.

Warning
you can only have one subscription for one event type.
Parameters
instanceThe Event Loop instance
message_queueThe message queue to add
[in]eventThe Event Loop event to trigger on
[in]callbackThe callback to call on event
contextThe context for callback

Subscribe to message queue events.

◆ furi_event_loop_subscribe_mutex()

void furi_event_loop_subscribe_mutex ( FuriEventLoop * instance,
FuriMutex * mutex,
FuriEventLoopEvent event,
FuriEventLoopEventCallback callback,
void * context )

Subscribe to mutex events.

Warning
you can only have one subscription for one event type.
Parameters
instanceThe Event Loop instance
mutexThe mutex to add
[in]eventThe Event Loop event to trigger on
[in]callbackThe callback to call on event
contextThe context for callback

◆ furi_event_loop_subscribe_semaphore()

void furi_event_loop_subscribe_semaphore ( FuriEventLoop * instance,
FuriSemaphore * semaphore,
FuriEventLoopEvent event,
FuriEventLoopEventCallback callback,
void * context )

Subscribe to semaphore events.

Warning
you can only have one subscription for one event type.
Parameters
instanceThe Event Loop instance
semaphoreThe semaphore to add
[in]eventThe Event Loop event to trigger on
[in]callbackThe callback to call on event
contextThe context for callback

◆ furi_event_loop_subscribe_stream_buffer()

void furi_event_loop_subscribe_stream_buffer ( FuriEventLoop * instance,
FuriStreamBuffer * stream_buffer,
FuriEventLoopEvent event,
FuriEventLoopEventCallback callback,
void * context )

Subscribe to stream buffer events.

Warning
you can only have one subscription for one event type.
Parameters
instanceThe Event Loop instance
stream_bufferThe stream buffer to add
[in]eventThe Event Loop event to trigger on
[in]callbackThe callback to call on event
contextThe context for callback

◆ furi_event_loop_tick_set()

void furi_event_loop_tick_set ( FuriEventLoop * instance,
uint32_t interval,
FuriEventLoopTickCallback callback,
void * context )

Set Event Loop tick callback.

Tick callback is called periodically after specified inactivity time. It acts like a low-priority timer: it will only fire if there is time left after processing the synchronization primitives and the regular timers. Therefore, it is not monotonic: ticks will be skipped if the event loop is busy.

Parameters
instanceThe Event Loop instance
[in]intervalThe tick interval
[in]callbackThe callback to call
contextThe context for callback

◆ furi_event_loop_unsubscribe()

void furi_event_loop_unsubscribe ( FuriEventLoop * instance,
FuriEventLoopObject * object )

Unsubscribe from events (common)

Parameters
instanceThe Event Loop instance
objectThe object to unsubscribe from

Unsubscribe from events (common)