The latest development version of this page may be more current than this released 0.4.3 version.

Event

Overview

The Event component is a module used for event distribution. Various modules send events to the event component, which then distributes them to applications through registered callbacks, allowing users to centrally subscribe to and handle events from different modules.

The Event component provides grouped management, allowing for registration of event callbacks by group, removal of registered callbacks, and sending events to groups.

Event involve two roles: the publisher and the subscriber. The module that generates the event is the publisher, and the module that registers event callbacks to receive and process the events is the subscriber.

Publishers use the WM_EVENT_DECLARE_GROUP macro in the module’s header file to declare event groups and use enums to define event types within the group. They use structures to define the specific data types of events. In the module’s C file, they use WM_EVENT_DEFINE_GROUP to define event groups and wm_event_send to send events at the point of generation.

Subscribers need to use wm_event_add_callback to register which group’s events they want to receive. If the group is WM_EVENT_ANY_GROUP, they will receive events from all groups.

Example Functions

Initializing the Event Component

After enabling the Event component in the configuration, users do not need to call wm_event_init() for initialization.

Event Groups

The GROUP definition is as follows:

#define WM_EVENT_DECLARE_GROUP(group) extern wm_event_group_t const group
#define WM_EVENT_DEFINE_GROUP(group) wm_event_group_t const group = #group

The above two macros are used to declare and define event groups. They are used in the module that generates the events, with the group declared in the header file and defined in the C file. The subscriber module can directly use the group.

WM_EVENT_DECLARE_GROUP : Used to declare the event group in the publisher’s header file. The subscriber can directly use the group name after including the header file. WM_EVENT_DEFINE_GROUP : Used to define the event group in the publisher’s C file, only defined once.

Warning

The group name can only be defined using the above macros, and can only be used as declared in the module’s header file. Direct usage of strings is not allowed, as the module internally compares addresses, not the strings themselves.

Register Callback Function

wm_event_add_callback is defined as follows:

int wm_event_add_callback(wm_event_group_t group, int event, wm_event_callback callback, void *priv);

This function registers a callback function for a specific event group with the event module. When an event in that group occurs, the registered callback function will be called. If the group is WM_EVENT_ANY_GROUP, all group events will be received.

wm_event_group_t group : Specifies the event group to filter.

event : Specifies the event type to filter.

wm_event_callback callback: The callback function to add, which completes the necessary tasks when the event is triggered. The function prototype is:

void *priv : Private data of the callback function can be added during registration, usually as a semaphore for synchronization.

typedef void (*wm_event_callback)(wm_event_group_t group, int event,void *data, void *priv);

Remove Callback Function

wm_event_remove_callback is defined as follows:

int wm_event_remove_callback(wm_event_group_t group, int event, wm_event_callback callback,void *priv);

wm_event_group_t group: Event group.

event: Event type to filter.

wm_event_callback callback: The callback function to remove. The function prototype is:

void *priv : Private data of the callback function can be added during registration, usually as a semaphore for synchronization.

To remove a callback, the group, event, callback, and priv must all match the registered values. After removal, the event will no longer be received.

Send Event

wm_event_send is defined as follows:

int wm_event_send(wm_event_group_t group,int event, void *data,size_t size);

wm_event_group_t group : Event group.

int event : Event subtype within the group, generally defined in the publisher’s module header file using an enum.

void* data : Event group data. The specific structure is generally defined as a struct in the subscriber’s header file. If the event subtype sufficiently describes the event, this can be NULL indicating no data.

size_t size : Size of the data.

This function sends an event to the specified group. The event can carry specific *data, which the callback can handle by converting it to the publisher’s struct.

Deinitialize the Event Component

wm_event_deinit is defined as follows:

int wm_event_deinit(void);

Calling this function stops the event processing task and releases related resources.

Application Example

1 The header file of the event-generating module (example_event.h) defines as follows:

// Declare the event group, equivalent to extern const char* EXAMPLE_USER_EV_GROUP;
WM_EVENT_DECLARE_GROUP(EXAMPLE_USER_EV_GROUP);

enum{
   EXAMPLE_EVENT_TYPE1 = 1,  // Event types within the group, multiple can be defined
};

// Data type carried by the event
struct exampe_user_event_t
{
   int param1;
   int param2;
};

// Function that generates the event in the module
void start_example_event(void);

2 The C file of the event-generating module (example_event.c) implements as follows:

#include "example_event.h"

//// Define the event, equivalent to: const char *  EXAMPLE_USER_EV_GROUP="EXAMPLE_USER_EV_GROUP"
WM_EVENT_DEFINE_GROUP(EXAMPLE_USER_EV_GROUP);

void start_example_event(void)
{
   // Specific data carried by the event
   struct exampe_user_event_t user_event = {1,2};

   // Send the event to the group
   wm_event_send(EXAMPLE_USER_EV_GROUP, EXAMPLE_EVENT_TYPE1, &user_event, sizeof(user_event));
}

3 Subscribe to and handle the event:

#include <stdio.h>
#include <stdint.h>

#include "wm_types.h"
#include "wm_event.h"
#include "example_event.h"

static void example_event_user_callback(wm_event_group_t group, int event,void *data, void *priv)
{
   if (event == EXAMPLE_EVENT_TYPE1)  // Handle the specified event
   {
      struct exampe_user_event_t* p = (struct exampe_user_event_t*)(data);
      printf("user event %d %d\n",p->param1,p->param2);
   }
}

int main(void)
{
   // Subscribe to the event
   wm_event_add_callback(EXAMPLE_USER_EV_GROUP,WM_EVENT_ANY_TYPE,example_event_user_callback,NULL);

   // Start the module that generates the event
   start_example_event();

   return 0;
}