Project restructuring: add tactility-headless (#55)
- Created `tactility-headless` to support ESP32 firmwares that don't require graphics - `tactility` subproject now contains both PC and ESP32 code (to avoid having to split up `tactility` and `tactility-headless` into separate projects, which would result in a very complex dependency tree) - `tactility` subproject is now defined as component for ESP32 and as regular module for PC - Improvements for dispatcher - Added `project-structure.puml` to docs - `Gui` service now depends on `Loader` service instead of the reverse - Added `statusbar_updater` service for updating Wi-Fi and SD card icons
This commit is contained in:
committed by
GitHub
parent
b659d5b940
commit
27730260e0
@@ -8,6 +8,7 @@ file(GLOB SOURCES "src/*.c")
|
||||
file(GLOB HEADERS "src/*.h")
|
||||
|
||||
add_library(tactility-core OBJECT)
|
||||
|
||||
target_sources(tactility-core
|
||||
PRIVATE ${SOURCES}
|
||||
PUBLIC ${HEADERS}
|
||||
|
||||
@@ -2,9 +2,20 @@
|
||||
|
||||
#include "tactility_core.h"
|
||||
|
||||
typedef struct {
|
||||
Callback callback;
|
||||
void* context;
|
||||
} DispatcherMessage;
|
||||
|
||||
typedef struct {
|
||||
MessageQueue* queue;
|
||||
Mutex* mutex;
|
||||
DispatcherMessage buffer; // Buffer for consuming a message
|
||||
} DispatcherData;
|
||||
|
||||
Dispatcher* tt_dispatcher_alloc(uint32_t message_count) {
|
||||
Dispatcher* dispatcher = malloc(sizeof(Dispatcher));
|
||||
*dispatcher = (Dispatcher) {
|
||||
DispatcherData* data = malloc(sizeof(DispatcherData));
|
||||
*data = (DispatcherData) {
|
||||
.queue = tt_message_queue_alloc(message_count, sizeof(DispatcherMessage)),
|
||||
.mutex = tt_mutex_alloc(MutexTypeNormal),
|
||||
.buffer = {
|
||||
@@ -12,37 +23,40 @@ Dispatcher* tt_dispatcher_alloc(uint32_t message_count) {
|
||||
.context = NULL
|
||||
}
|
||||
};
|
||||
return dispatcher;
|
||||
return data;
|
||||
}
|
||||
|
||||
void tt_dispatcher_free(Dispatcher* dispatcher) {
|
||||
tt_mutex_acquire(dispatcher->mutex, TtWaitForever);
|
||||
tt_message_queue_reset(dispatcher->queue);
|
||||
tt_message_queue_free(dispatcher->queue);
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
tt_mutex_free(dispatcher->mutex);
|
||||
free(dispatcher);
|
||||
DispatcherData* data = (DispatcherData*)dispatcher;
|
||||
tt_mutex_acquire(data->mutex, TtWaitForever);
|
||||
tt_message_queue_reset(data->queue);
|
||||
tt_message_queue_free(data->queue);
|
||||
tt_mutex_release(data->mutex);
|
||||
tt_mutex_free(data->mutex);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void tt_dispatcher_dispatch(Dispatcher* dispatcher, Callback callback, void* context) {
|
||||
DispatcherData* data = (DispatcherData*)dispatcher;
|
||||
DispatcherMessage message = {
|
||||
.callback = callback,
|
||||
.context = context
|
||||
};
|
||||
tt_mutex_acquire(dispatcher->mutex, TtWaitForever);
|
||||
tt_message_queue_put(dispatcher->queue, &message, TtWaitForever);
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
tt_mutex_acquire(data->mutex, TtWaitForever);
|
||||
tt_message_queue_put(data->queue, &message, TtWaitForever);
|
||||
tt_mutex_release(data->mutex);
|
||||
}
|
||||
|
||||
bool tt_dispatcher_consume(Dispatcher* dispatcher, uint32_t timeout_ticks) {
|
||||
tt_mutex_acquire(dispatcher->mutex, TtWaitForever);
|
||||
if (tt_message_queue_get(dispatcher->queue, &(dispatcher->buffer), timeout_ticks) == TtStatusOk) {
|
||||
DispatcherMessage* message = &(dispatcher->buffer);
|
||||
DispatcherData* data = (DispatcherData*)dispatcher;
|
||||
tt_mutex_acquire(data->mutex, TtWaitForever);
|
||||
if (tt_message_queue_get(data->queue, &(data->buffer), timeout_ticks) == TtStatusOk) {
|
||||
DispatcherMessage* message = &(data->buffer);
|
||||
message->callback(message->context);
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
tt_mutex_release(data->mutex);
|
||||
return true;
|
||||
} else {
|
||||
tt_mutex_release(dispatcher->mutex);
|
||||
tt_mutex_release(data->mutex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file message_queue.h
|
||||
* @file dispatcher.h
|
||||
*
|
||||
* Dispatcher is a thread-safe message queue implementation for callbacks.
|
||||
* Dispatcher is a thread-safe code execution queue.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@@ -15,21 +15,12 @@ extern "C" {
|
||||
|
||||
typedef void (*Callback)(void* data);
|
||||
|
||||
typedef struct {
|
||||
Callback callback;
|
||||
void* context;
|
||||
} DispatcherMessage;
|
||||
|
||||
typedef struct {
|
||||
MessageQueue* queue;
|
||||
Mutex* mutex;
|
||||
DispatcherMessage buffer; // Buffer for consuming a message
|
||||
} Dispatcher;
|
||||
typedef void Dispatcher;
|
||||
|
||||
Dispatcher* tt_dispatcher_alloc(uint32_t message_count);
|
||||
void tt_dispatcher_free(Dispatcher* dispatcher);
|
||||
void tt_dispatcher_dispatch(Dispatcher* dispatcher, Callback callback, void* context);
|
||||
bool tt_dispatcher_consume(Dispatcher* dispatcher, uint32_t timeout_ticks);
|
||||
void tt_dispatcher_dispatch(Dispatcher* data, Callback callback, void* context);
|
||||
bool tt_dispatcher_consume(Dispatcher* data, uint32_t timeout_ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#ifdef ESP_TARGET
|
||||
#include "esp_log.h"
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
@@ -11,7 +11,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#ifdef ESP_TARGET
|
||||
|
||||
#define TT_LOG_E(tag, format, ...) \
|
||||
ESP_LOGE(tag, format, ##__VA_ARGS__)
|
||||
@@ -47,7 +47,7 @@ void tt_log(LogLevel level, const char* tag, const char* format, ...);
|
||||
#define TT_LOG_T(tag, format, ...) \
|
||||
tt_log(LOG_LEVEL_TRACE, tag, format, ##__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
#endif // ESP_TARGET
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user