Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add event handler context #29

Merged
merged 6 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions .github/workflows/pull-request-acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,11 @@ jobs:
uses: actions/checkout@v3
- name: Install Ninja
uses: seanmiddleditch/gha-setup-ninja@master
- name: Build Tests And Examples
- name: Build And Test
working-directory: extra
run: |
cmake -B build -S . -G Ninja
cmake --build build
- name: Baremetal Tests
working-directory: extra
run: ./build/test/baremetal_eventrouter_test
- name: FreeRTOS Tests
working-directory: extra
run: ./build/test/freertos_eventrouter_test
- name: POSIX Tests
working-directory: extra
run: ./build/test/posix_eventrouter_test
for implementation in baremetal freertos posix; do
cmake -B build -S . -G Ninja -DIMPLEMENTATION=$implementation
cmake --build build
cmake --build build --target test
done
3 changes: 2 additions & 1 deletion eventrouter/internal/event_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ extern "C"

/// A function which accepts events and returns qualitative information
/// about how that event was received.
typedef ErEventHandlerRet_t (*ErEventHandler_t)(struct ErEvent_t *a_event);
typedef ErEventHandlerRet_t (*ErEventHandler_t)(struct ErEvent_t* a_event,
void* a_context);

#ifdef __cplusplus
}
Expand Down
10 changes: 6 additions & 4 deletions eventrouter/internal/eventrouter_baremetal.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ void ErCallHandlers(ErEvent_t *a_event)
if (module_is_subscribed)
{
// Deliver the event to the subscribed module.
const ErEventHandlerRet_t ret = module->m_handler(a_event);
const ErEventHandlerRet_t ret =
module->m_handler(a_event, module->m_context);

if (ret == ER_EVENT_HANDLER_RET__KEPT)
{
Expand Down Expand Up @@ -175,7 +176,8 @@ void ErReturnToSender(ErEvent_t *a_event)
ErListRemove(&s_context.m_events.m_kept, &a_event->m_next);

// All subscribed modules have received the event; return to its sender.
a_event->m_sending_module->m_handler(a_event);
ErModule_t *sender = a_event->m_sending_module;
sender->m_handler(a_event, sender->m_context);
}
}

Expand Down Expand Up @@ -226,8 +228,8 @@ ErEvent_t *ErGetEventToDeliver(void)
ErList_t *node = &s_context.m_events.m_deliver_now;
if (node->m_next != NULL)
{
ret = er_container_of(node->m_next, ErEvent_t, m_next);
node->m_next = node->m_next->m_next;
ret = er_container_of(node->m_next, ErEvent_t, m_next);
node->m_next = node->m_next->m_next;
ret->m_next.m_next = NULL;
}

Expand Down
10 changes: 8 additions & 2 deletions eventrouter/internal/eventrouter_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ static pthread_cond_t s_init_gate_cond = PTHREAD_COND_INITIALIZER;
//==============================================================================

#if ER_IMPLEMENTATION == ER_IMPL_FREERTOS

#include "FreeRTOS.h"
#include "queue.h"

static bool IsInIsr(void); // Forward declaration.

static void DefaultSendEvent(ErQueueHandle_t a_queue, void *a_event)
Expand Down Expand Up @@ -543,7 +547,8 @@ void ErCallHandlers(ErEvent_t *a_event)
if (module_is_subscribed)
{
// Deliver the event to the subscribed module.
const ErEventHandlerRet_t ret = module->m_handler(a_event);
const ErEventHandlerRet_t ret =
module->m_handler(a_event, module->m_context);

if (ret == ER_EVENT_HANDLER_RET__KEPT)
{
Expand Down Expand Up @@ -628,7 +633,8 @@ void ErReturnToSender(ErEvent_t *a_event)
// support the optimization mentioned a few lines up.
if (atomic_load(&a_event->m_reference_count) == 0)
{
a_event->m_sending_module->m_handler(a_event);
ErModule_t *sender = a_event->m_sending_module;
sender->m_handler(a_event, sender->m_context);
}
}

Expand Down
9 changes: 5 additions & 4 deletions eventrouter/internal/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern "C"
typedef struct
{
ErEventHandler_t m_handler; /// Where events are delivered/returned.
void *m_context; /// Passed to `m_handler` when an event is delivered.

// Implementation details.
size_t m_task_idx;
Expand All @@ -30,10 +31,10 @@ extern "C"

/// Used to initialize `ErModule_t` definitions while avoiding
/// missing-field-initializers warnings.
#define ER_CREATE_MODULE(a_handler) \
{ \
.m_handler = a_handler, .m_task_idx = 0, .m_module_idx = 0, \
.m_subscriptions = {0}, \
#define ER_CREATE_MODULE(a_handler, a_context) \
{ \
.m_handler = a_handler, .m_context = a_context, .m_task_idx = 0, \
.m_module_idx = 0, .m_subscriptions = {0}, \
}

#ifdef __cplusplus
Expand Down
36 changes: 23 additions & 13 deletions extra/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,35 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS true)
project(cmake-extras)

include(cmake/repository_root.cmake)
include(cmake/freertos.cmake)
include(cmake/googletest.cmake)

#===============================================================================
# Build implementation-specific eventrouter libs; used by examples and tests.
# ===============================================================================
# Select implementation.
#===============================================================================

add_library(baremetal_eventrouter STATIC ${REPOSITORY_ROOT}/eventrouter.c)
target_include_directories(baremetal_eventrouter PUBLIC ${REPOSITORY_ROOT} .)
target_compile_definitions(baremetal_eventrouter PUBLIC -DER_BAREMETAL)
set(IMPLEMENTATION "baremetal" CACHE STRING "Select the implementation to build")
set(ALLOWED_IMPLEMENTATIONS "baremetal;freertos;posix")
set_property(CACHE IMPLEMENTATION PROPERTY STRINGS ${ALLOWED_IMPLEMENTATIONS})
if(NOT IMPLEMENTATION IN_LIST ALLOWED_IMPLEMENTATIONS)
message(FATAL_ERROR "IMPLEMENTATION must be one of: ${ALLOWED_IMPLEMENTATIONS}")
endif()

add_library(freertos_eventrouter STATIC ${REPOSITORY_ROOT}/eventrouter.c)
target_include_directories(freertos_eventrouter PUBLIC ${REPOSITORY_ROOT} .)
target_link_libraries(freertos_eventrouter PUBLIC freertos_kernel)
target_compile_definitions(freertos_eventrouter PUBLIC -DER_FREERTOS)
#===============================================================================
# Build the eventrouter library; used by examples and tests.
# ===============================================================================

add_library(posix_eventrouter STATIC ${REPOSITORY_ROOT}/eventrouter.c)
target_include_directories(posix_eventrouter PUBLIC ${REPOSITORY_ROOT} .)
target_compile_definitions(posix_eventrouter PUBLIC -DER_POSIX)
add_library(eventrouter STATIC ${REPOSITORY_ROOT}/eventrouter.c)
target_include_directories(eventrouter PUBLIC ${REPOSITORY_ROOT} .)

if(IMPLEMENTATION STREQUAL "baremetal")
target_compile_definitions(eventrouter PUBLIC -DER_BAREMETAL)
elseif(IMPLEMENTATION STREQUAL "freertos")
include(cmake/freertos.cmake)
target_link_libraries(eventrouter PUBLIC freertos_kernel)
target_compile_definitions(eventrouter PUBLIC -DER_FREERTOS)
elseif(IMPLEMENTATION STREQUAL "posix")
target_compile_definitions(eventrouter PUBLIC -DER_POSIX)
endif()

#===============================================================================
# Build tests and example applications
Expand Down
6 changes: 5 additions & 1 deletion extra/cmake/freertos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/FreeRTOSConfig.h
#ifndef FREERTOSCONFIG_H
#define FREERTOSCONFIG_H

#include <pthread.h>
#include <stdbool.h>

/// These values come from starting with an empty file and silencing compiler
/// errors by providing reasonable (?) values. These specific values are not
/// necessary for the Event Router to function.

#define configMAX_PRIORITIES 10
#define configMINIMAL_STACK_SIZE 1024
#define configMINIMAL_STACK_SIZE PTHREAD_STACK_MIN
#define configTICK_RATE_HZ 1000
#define configTOTAL_HEAP_SIZE (1024 * 1024)
#define configUSE_16_BIT_TICKS false
Expand All @@ -42,3 +43,6 @@ FetchContent_MakeAvailable(freertos)
target_link_options(freertos_kernel PUBLIC
$<$<PLATFORM_ID:Linux>:-pthread>
)
target_include_directories(freertos_kernel PUBLIC
${CMAKE_CURRENT_BINARY_DIR}
)
52 changes: 5 additions & 47 deletions extra/example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,53 +1,11 @@
#===============================================================================
# Common Modules
#
# These modules are common to all example applications to demonstrate the
# reusability of event-based code across eventrouter implementations.
# ===============================================================================

set(COMMON_MODULE_SOURCES # Related header files are directory-local.
add_executable(eventrouter_example
module_data_logger.c
module_data_uploader.c
module_sensor_data_publisher.c
${IMPLEMENTATION}_eventrouter_example.c
$<$<IN_LIST:${IMPLEMENTATION},freertos;posix>:task_generic.c>
)

#===============================================================================
# Baremetal: The simplest example application.
# ===============================================================================

add_executable(baremetal_eventrouter_example
${COMMON_MODULE_SOURCES}
baremetal_eventrouter_example.c
)
target_link_libraries(baremetal_eventrouter_example
PRIVATE
baremetal_eventrouter
)

#===============================================================================
# FreeRTOS
# ===============================================================================

add_executable(freertos_eventrouter_example
${COMMON_MODULE_SOURCES}
freertos_eventrouter_example.c
task_generic.c
)
target_link_libraries(freertos_eventrouter_example
PRIVATE
freertos_eventrouter
)

#===============================================================================
# POSIX
# ===============================================================================

add_executable(posix_eventrouter_example
${COMMON_MODULE_SOURCES}
posix_eventrouter_example.c
task_generic.c
)
target_link_libraries(posix_eventrouter_example
target_link_libraries(eventrouter_example
PRIVATE
posix_eventrouter
eventrouter
)
9 changes: 6 additions & 3 deletions extra/example/module_data_logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@
#include "eventrouter.h"
#include "module_sensor_data_publisher.h"

static ErEventHandlerRet_t DataLogger_EventHandler(ErEvent_t* a_event);
static ErEventHandlerRet_t DataLogger_EventHandler(ErEvent_t* a_event,
void* a_context);

ErModule_t g_data_logger_module = ER_CREATE_MODULE(DataLogger_EventHandler);
ErModule_t g_data_logger_module =
ER_CREATE_MODULE(DataLogger_EventHandler, NULL);

void DataLogger_Init(void)
{
ErSubscribe(&g_data_logger_module, ER_EVENT_TYPE__SENSOR_DATA);
}

ErEventHandlerRet_t DataLogger_EventHandler(ErEvent_t *a_event)
ErEventHandlerRet_t DataLogger_EventHandler(ErEvent_t* a_event, void* a_context)
{
ER_UNUSED(a_context);
ErEventHandlerRet_t result = ER_EVENT_HANDLER_RET__HANDLED;

switch (a_event->m_type)
Expand Down
10 changes: 7 additions & 3 deletions extra/example/module_data_uploader.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@
#include "eventrouter.h"
#include "module_sensor_data_publisher.h"

static ErEventHandlerRet_t DataUploader_EventHandler(ErEvent_t* a_event);
static ErEventHandlerRet_t DataUploader_EventHandler(ErEvent_t* a_event,
void* a_context);

ErModule_t g_data_uploader_module = ER_CREATE_MODULE(DataUploader_EventHandler);
ErModule_t g_data_uploader_module =
ER_CREATE_MODULE(DataUploader_EventHandler, NULL);

void DataUploader_Init(void)
{
ErSubscribe(&g_data_uploader_module, ER_EVENT_TYPE__SENSOR_DATA);
}

ErEventHandlerRet_t DataUploader_EventHandler(ErEvent_t* a_event)
ErEventHandlerRet_t DataUploader_EventHandler(ErEvent_t* a_event,
void* a_context)
{
ER_UNUSED(a_context);
ErEventHandlerRet_t result = ER_EVENT_HANDLER_RET__HANDLED;

switch (a_event->m_type)
Expand Down
9 changes: 6 additions & 3 deletions extra/example/module_sensor_data_publisher.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@

#include "eventrouter.h"

static ErEventHandlerRet_t SensorDataPublisher_EventHandler(ErEvent_t *a_event);
static ErEventHandlerRet_t SensorDataPublisher_EventHandler(ErEvent_t *a_event,
void *a_context);

ErModule_t g_sensor_data_publisher_module =
ER_CREATE_MODULE(SensorDataPublisher_EventHandler);
ER_CREATE_MODULE(SensorDataPublisher_EventHandler, NULL);

static SensorDataEvent_t s_event = {
INIT_ER_EVENT(ER_EVENT_TYPE__SENSOR_DATA, &g_sensor_data_publisher_module),
Expand All @@ -32,8 +33,10 @@ void SensorDataPublisher_Init(void)
srand(time(NULL));
}

ErEventHandlerRet_t SensorDataPublisher_EventHandler(ErEvent_t *a_event)
ErEventHandlerRet_t SensorDataPublisher_EventHandler(ErEvent_t *a_event,
void *a_context)
{
ER_UNUSED(a_context);
ErEventHandlerRet_t result = ER_EVENT_HANDLER_RET__HANDLED;

switch (a_event->m_type)
Expand Down
46 changes: 7 additions & 39 deletions extra/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,43 +1,11 @@
#===============================================================================
# Baremetal
# ===============================================================================

add_executable(baremetal_eventrouter_test
baremetal_eventrouter_test.cc
add_executable(eventrouter_test
common_eventrouter_test.cc
$<$<IN_LIST:${IMPLEMENTATION},baremetal>:baremetal_eventrouter_test.cc>
$<$<IN_LIST:${IMPLEMENTATION},freertos;posix>:os_eventrouter_test.cc>
$<$<IN_LIST:${IMPLEMENTATION},freertos;posix>:mock_os.cc>
)
target_link_libraries(baremetal_eventrouter_test PRIVATE
baremetal_eventrouter
target_link_libraries(eventrouter_test PUBLIC
eventrouter
gtest_main
)
gtest_discover_tests(baremetal_eventrouter_test)

#===============================================================================
# FreeRTOS
# ===============================================================================

add_executable(freertos_eventrouter_test
common_eventrouter_test.cc
os_eventrouter_test.cc
mock_os.cc
)
target_link_libraries(freertos_eventrouter_test PRIVATE
freertos_eventrouter
gtest_main
)
gtest_discover_tests(freertos_eventrouter_test)

#===============================================================================
# POSIX
# ===============================================================================

add_executable(posix_eventrouter_test
common_eventrouter_test.cc
os_eventrouter_test.cc
mock_os.cc
)
target_link_libraries(posix_eventrouter_test PRIVATE
posix_eventrouter
gtest_main
)
gtest_discover_tests(posix_eventrouter_test)
gtest_discover_tests(eventrouter_test)
5 changes: 3 additions & 2 deletions extra/test/mock_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ struct MockModule
m_module.m_handler = EventHandler;
}

static ErEventHandlerRet_t EventHandler(ErEvent_t *a_event)
static ErEventHandlerRet_t EventHandler(ErEvent_t *a_event, void *a_context)
{
ER_UNUSED(a_context);
m_last_event_handled = a_event;
return m_event_handler_ret;
}
Expand All @@ -56,7 +57,7 @@ ErEvent_t *MockModule<N>::m_last_event_handled = nullptr;

template <int N>
ErModule_t MockModule<N>::m_module =
ER_CREATE_MODULE(MockModule<N>::EventHandler);
ER_CREATE_MODULE(MockModule<N>::EventHandler, NULL);

template <int N>
ErEventHandlerRet_t MockModule<N>::m_event_handler_ret =
Expand Down
Loading