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

[FL-3841] FuriEventLoop Pt.2 #3703

Merged
merged 60 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
869dad8
Remove all primitive specialisation from FuriEventLoop
gsurkov Jun 11, 2024
82fafd9
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
gsurkov Jun 11, 2024
d9363d3
Implement FuriEventLoop interoperation via inheritance for FuriMessag…
gsurkov Jun 12, 2024
97ed11e
Merge remote-tracking branch 'origin' into gsurkov/3841_event_loop_pt2
gsurkov Jun 12, 2024
ca838d9
Revert "Implement FuriEventLoop interoperation via inheritance for Fu…
gsurkov Jul 4, 2024
e82b5d8
Revert "Remove all primitive specialisation from FuriEventLoop"
gsurkov Jul 4, 2024
7885881
Merge remote-tracking branch 'origin/dev' into gsurkov/3841_event_loo…
gsurkov Jul 4, 2024
0a4d907
Merge remote-tracking branch 'origin/dev' into gsurkov/3841_event_loo…
gsurkov Jul 15, 2024
dbbeef1
Merge remote-tracking branch 'origin/dev' into gsurkov/3841_event_loo…
gsurkov Jul 17, 2024
470eeaa
Abstract primitive type from main logic in FuriEventLoop
gsurkov Jul 17, 2024
18c8c1e
Remove message_queue_i.h
gsurkov Jul 17, 2024
120ccb8
Add stream buffer support for event loop
gsurkov Jul 17, 2024
b1a900f
Add semaphore support for event loop
gsurkov Jul 17, 2024
42ae47c
Add temporary unit test workaround
gsurkov Jul 18, 2024
eb9d385
Make the linter happy
gsurkov Jul 18, 2024
ec3e1c1
Add mutex support for event loop
gsurkov Jul 19, 2024
e29009c
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
gsurkov Jul 19, 2024
648b389
Implement event subscription and unsubscription while the event loop …
gsurkov Jul 23, 2024
eba1575
Fix PVS warnings
gsurkov Jul 23, 2024
ec59dbf
Implement edge events
gsurkov Jul 24, 2024
d1b6825
Fix leftover logical errors
gsurkov Jul 24, 2024
c612771
Add event loop timer example application
gsurkov Jul 24, 2024
4c87f36
Implement flag-based edge trigger and one-shot mode
gsurkov Jul 24, 2024
b5d4174
Add event loop mutex example application
gsurkov Jul 24, 2024
8a3a2f8
Fix a typo
gsurkov Jul 24, 2024
23b5c0d
Fix a copy/paste typo
gsurkov Jul 25, 2024
9cd5aed
Only notify the event loop if stream buffer is at or above its trigge…
gsurkov Jul 25, 2024
82a6f58
Reformat comments
gsurkov Jul 25, 2024
711f3b7
Add event loop stream buffer example application
gsurkov Jul 25, 2024
6c11a31
Add event loop multiple elements example application
gsurkov Jul 26, 2024
0b4f111
Improve event loop flag names
gsurkov Jul 26, 2024
cfe6edb
Remove redundant signal handler as it is already handled by the event…
gsurkov Jul 26, 2024
6872de1
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
gsurkov Jul 29, 2024
dd3ffaf
Refactor Power service, improve ViewHolder
gsurkov Jul 29, 2024
8316854
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
gsurkov Jul 29, 2024
ea730bb
Use ViewHolder instead of ViewDispatcher in About app
gsurkov Jul 30, 2024
a9b437a
Enable ViewDispatcher queue on construction, deprecate view_dispatche…
gsurkov Jul 30, 2024
3e7e7c4
Fix a typo
gsurkov Jul 30, 2024
60b4cd9
Remove all invocations of view_dispatcher_enable_queue()
gsurkov Jul 30, 2024
6a27727
Remove app-scened-template
gsurkov Jul 30, 2024
3f45f5b
Remove missing library from target.json
gsurkov Jul 30, 2024
541a8b8
Merge remote-tracking branch 'origin/dev' into gsurkov/3841_event_loo…
gsurkov Jul 30, 2024
2632fef
Port Accessor app to ViewHolder
gsurkov Jul 30, 2024
045c915
Make the linter happy
gsurkov Jul 30, 2024
b5c25c8
Add example_view_holder application, update ViewHolder docs
gsurkov Jul 30, 2024
0c07e36
Add example_view_dispatcher application, update ViewDispatcher docs
gsurkov Jul 31, 2024
c13c49e
Replace FuriSemaphore with FuriApiLock, remove workaround delay
gsurkov Jul 31, 2024
32fd0eb
Fix logical error
gsurkov Jul 31, 2024
1ed1933
Fix another logical error
gsurkov Jul 31, 2024
d05d6da
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
gsurkov Jul 31, 2024
577d4b5
Use the sources directive to speed up compilation
gsurkov Jul 31, 2024
cbdebd3
Use constant define macro
gsurkov Jul 31, 2024
8ee6cb3
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
hedger Aug 2, 2024
8f6b93c
Merge remote-tracking branch 'origin/dev' into gsurkov/3841_event_loo…
gsurkov Aug 4, 2024
5df5a37
Improve FuriEventLoop documentation
gsurkov Aug 5, 2024
3424ce2
Improve FuriEventLoop documentation once more
gsurkov Aug 5, 2024
9be39e5
Merge branch 'dev' into gsurkov/3841_event_loop_pt2
skotopes Aug 7, 2024
4df93f7
Bump API Version
skotopes Aug 7, 2024
bfe38d0
Gui: remove redundant checks from ViewDispatcher
skotopes Aug 7, 2024
4d5627d
Gui: remove dead ifs from ViewDispatcher
skotopes Aug 7, 2024
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
54 changes: 26 additions & 28 deletions applications/debug/accessor/accessor_view_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,49 @@
AccessorAppViewManager::AccessorAppViewManager() {
event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent));

view_dispatcher = view_dispatcher_alloc();
auto callback = cbc::obtain_connector(this, &AccessorAppViewManager::previous_view_callback);
view_holder = view_holder_alloc();
auto callback =
cbc::obtain_connector(this, &AccessorAppViewManager::view_holder_back_callback);

// allocate views
submenu = submenu_alloc();
add_view(ViewType::Submenu, submenu_get_view(submenu));

popup = popup_alloc();
add_view(ViewType::Popup, popup_get_view(popup));

gui = static_cast<Gui*>(furi_record_open(RECORD_GUI));
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
// set back callback
view_holder_set_back_callback(view_holder, callback, NULL);

// set previous view callback for all views
view_set_previous_callback(submenu_get_view(submenu), callback);
view_set_previous_callback(popup_get_view(popup), callback);
gui = static_cast<Gui*>(furi_record_open(RECORD_GUI));
view_holder_attach_to_gui(view_holder, gui);
}

AccessorAppViewManager::~AccessorAppViewManager() {
// remove views
view_dispatcher_remove_view(
view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Submenu));
view_dispatcher_remove_view(
view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Popup));

// remove current view
view_holder_set_view(view_holder, NULL);
// free view modules
furi_record_close(RECORD_GUI);
submenu_free(submenu);
popup_free(popup);

// free dispatcher
view_dispatcher_free(view_dispatcher);

// free view holder
view_holder_free(view_holder);
// free event queue
furi_message_queue_free(event_queue);
}

void AccessorAppViewManager::switch_to(ViewType type) {
view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type));
View* view;

switch(type) {
case ViewType::Submenu:
view = submenu_get_view(submenu);
break;
case ViewType::Popup:
view = popup_get_view(popup);
break;
default:
furi_crash();
}

view_holder_set_view(view_holder, view);
}

Submenu* AccessorAppViewManager::get_submenu() {
Expand All @@ -65,16 +69,10 @@ void AccessorAppViewManager::send_event(AccessorEvent* event) {
furi_check(result == FuriStatusOk);
}

uint32_t AccessorAppViewManager::previous_view_callback(void*) {
void AccessorAppViewManager::view_holder_back_callback(void*) {
if(event_queue != NULL) {
AccessorEvent event;
event.type = AccessorEvent::Type::Back;
send_event(&event);
}

return VIEW_IGNORE;
}

void AccessorAppViewManager::add_view(ViewType view_type, View* view) {
view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view);
}
8 changes: 3 additions & 5 deletions applications/debug/accessor/accessor_view_manager.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
#include <furi.h>
#include <gui/view_dispatcher.h>
#include <gui/view_holder.h>
#include <gui/modules/submenu.h>
#include <gui/modules/popup.h>
#include "accessor_event.h"
Expand All @@ -10,7 +10,6 @@ class AccessorAppViewManager {
enum class ViewType : uint8_t {
Submenu,
Popup,
Tune,
};

FuriMessageQueue* event_queue;
Expand All @@ -27,11 +26,10 @@ class AccessorAppViewManager {
Popup* get_popup(void);

private:
ViewDispatcher* view_dispatcher;
Gui* gui;
ViewHolder* view_holder;

uint32_t previous_view_callback(void* context);
void add_view(ViewType view_type, View* view);
void view_holder_back_callback(void* context);

// view elements
Submenu* submenu;
Expand Down
1 change: 0 additions & 1 deletion applications/debug/battery_test_app/battery_test_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ BatteryTestApp* battery_test_alloc(void) {

// View dispatcher
app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, battery_test_battery_info_update_model, 500);
Expand Down
1 change: 0 additions & 1 deletion applications/debug/bt_debug_app/bt_debug_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ BtDebugApp* bt_debug_app_alloc(void) {

// View dispatcher
app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);

// Views
Expand Down
1 change: 0 additions & 1 deletion applications/debug/crash_test/crash_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ CrashTest* crash_test_alloc(void) {

instance->gui = furi_record_open(RECORD_GUI);
instance->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(instance->view_dispatcher);
view_dispatcher_attach_to_gui(
instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);

Expand Down
1 change: 0 additions & 1 deletion applications/debug/display_test/display_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ DisplayTest* display_test_alloc(void) {

instance->gui = furi_record_open(RECORD_GUI);
instance->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(instance->view_dispatcher);
view_dispatcher_attach_to_gui(
instance->view_dispatcher, instance->gui, ViewDispatcherTypeFullscreen);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ static void view_port_input_callback(InputEvent* input_event, void* context) {
furi_message_queue_put(app->input_queue, input_event, 0);
}

static bool input_queue_callback(FuriMessageQueue* queue, void* context) {
static bool input_queue_callback(FuriEventLoopObject* object, void* context) {
FuriMessageQueue* queue = object;
EventLoopBlinkTestApp* app = context;

InputEvent event;
Expand Down Expand Up @@ -144,7 +145,7 @@ int32_t event_loop_blink_test_app(void* arg) {
gui_add_view_port(gui, view_port, GuiLayerFullscreen);

furi_event_loop_tick_set(app.event_loop, 500, event_loop_tick_callback, &app);
furi_event_loop_message_queue_subscribe(
furi_event_loop_subscribe_message_queue(
app.event_loop, app.input_queue, FuriEventLoopEventIn, input_queue_callback, &app);

furi_event_loop_run(app.event_loop);
Expand All @@ -154,7 +155,7 @@ int32_t event_loop_blink_test_app(void* arg) {

furi_record_close(RECORD_GUI);

furi_event_loop_message_queue_unsubscribe(app.event_loop, app.input_queue);
furi_event_loop_unsubscribe(app.event_loop, app.input_queue);
furi_message_queue_free(app.input_queue);

for(size_t i = 0; i < TIMER_COUNT; ++i) {
Expand Down
2 changes: 0 additions & 2 deletions applications/debug/file_browser_test/file_browser_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ FileBrowserApp* file_browser_app_alloc(char* arg) {
app->dialogs = furi_record_open(RECORD_DIALOGS);

app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(app->view_dispatcher);

app->scene_manager = scene_manager_alloc(&file_browser_scene_handlers, app);

view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
Expand Down
1 change: 0 additions & 1 deletion applications/debug/lfrfid_debug/lfrfid_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ static LfRfidDebug* lfrfid_debug_alloc(void) {

app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&lfrfid_debug_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
app->view_dispatcher, lfrfid_debug_custom_event_callback);
Expand Down
1 change: 0 additions & 1 deletion applications/debug/locale_test/locale_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ static LocaleTestApp* locale_test_alloc(void) {

// View dispatcher
app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);

// Views
Expand Down
1 change: 0 additions & 1 deletion applications/debug/rpc_debug_app/rpc_debug_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ static RpcDebugApp* rpc_debug_app_alloc(void) {
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, rpc_debug_app_tick_event_callback, 100);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_enable_queue(app->view_dispatcher);

app->widget = widget_alloc();
view_dispatcher_add_view(
Expand Down
1 change: 0 additions & 1 deletion applications/debug/subghz_test/subghz_test_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ SubGhzTestApp* subghz_test_app_alloc(void) {
// View Dispatcher
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&subghz_test_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);

view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ int32_t text_box_view_test_app(void* p) {
Gui* gui = furi_record_open(RECORD_GUI);
ViewDispatcher* view_dispatcher = view_dispatcher_alloc();
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
view_dispatcher_enable_queue(view_dispatcher);

TextBoxViewTest instance = {
.text_box = text_box_alloc(),
Expand Down
1 change: 0 additions & 1 deletion applications/debug/uart_echo/uart_echo.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ static UartEchoApp* uart_echo_app_alloc(uint32_t baudrate) {

// View dispatcher
app->view_dispatcher = view_dispatcher_alloc();
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);

// Views
Expand Down
62 changes: 30 additions & 32 deletions applications/debug/unit_tests/tests/furi/furi_event_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,24 @@ typedef struct {
uint32_t consumer_counter;
} TestFuriData;

bool test_furi_event_loop_producer_mq_callback(FuriMessageQueue* queue, void* context) {
bool test_furi_event_loop_producer_mq_callback(FuriEventLoopObject* object, void* context) {
furi_check(context);

TestFuriData* data = context;
furi_check(data->mq == queue, "Invalid queue");
furi_check(data->mq == object, "Invalid queue");

FURI_LOG_I(
TAG, "producer_mq_callback: %lu %lu", data->producer_counter, data->consumer_counter);

// Remove and add should not cause crash
// if(data->producer_counter == EVENT_LOOP_EVENT_COUNT/2) {
// furi_event_loop_message_queue_remove(data->producer_event_loop, data->mq);
// furi_event_loop_message_queue_add(
// data->producer_event_loop,
// data->mq,
// FuriEventLoopEventOut,
// test_furi_event_loop_producer_mq_callback,
// data);
// }
if(data->producer_counter == EVENT_LOOP_EVENT_COUNT / 2) {
furi_event_loop_unsubscribe(data->producer_event_loop, data->mq);
furi_event_loop_subscribe_message_queue(
data->producer_event_loop,
data->mq,
FuriEventLoopEventOut,
test_furi_event_loop_producer_mq_callback,
data);
}

if(data->producer_counter == EVENT_LOOP_EVENT_COUNT) {
furi_event_loop_stop(data->producer_event_loop);
Expand All @@ -61,7 +60,7 @@ int32_t test_furi_event_loop_producer(void* p) {
FURI_LOG_I(TAG, "producer start 1st run");

data->producer_event_loop = furi_event_loop_alloc();
furi_event_loop_message_queue_subscribe(
furi_event_loop_subscribe_message_queue(
data->producer_event_loop,
data->mq,
FuriEventLoopEventOut,
Expand All @@ -73,15 +72,15 @@ int32_t test_furi_event_loop_producer(void* p) {
// 2 EventLoop index, 0xFFFFFFFF - all possible flags, emulate uncleared flags
xTaskNotifyIndexed(xTaskGetCurrentTaskHandle(), 2, 0xFFFFFFFF, eSetBits);

furi_event_loop_message_queue_unsubscribe(data->producer_event_loop, data->mq);
furi_event_loop_unsubscribe(data->producer_event_loop, data->mq);
furi_event_loop_free(data->producer_event_loop);

FURI_LOG_I(TAG, "producer start 2nd run");

data->producer_counter = 0;
data->producer_event_loop = furi_event_loop_alloc();

furi_event_loop_message_queue_subscribe(
furi_event_loop_subscribe_message_queue(
data->producer_event_loop,
data->mq,
FuriEventLoopEventOut,
Expand All @@ -90,36 +89,35 @@ int32_t test_furi_event_loop_producer(void* p) {

furi_event_loop_run(data->producer_event_loop);

furi_event_loop_message_queue_unsubscribe(data->producer_event_loop, data->mq);
furi_event_loop_unsubscribe(data->producer_event_loop, data->mq);
furi_event_loop_free(data->producer_event_loop);

FURI_LOG_I(TAG, "producer end");

return 0;
}

bool test_furi_event_loop_consumer_mq_callback(FuriMessageQueue* queue, void* context) {
bool test_furi_event_loop_consumer_mq_callback(FuriEventLoopObject* object, void* context) {
furi_check(context);

TestFuriData* data = context;
furi_check(data->mq == queue);
furi_check(data->mq == object);

furi_delay_us(furi_hal_random_get() % 1000);
furi_check(furi_message_queue_get(data->mq, &data->consumer_counter, 0) == FuriStatusOk);

FURI_LOG_I(
TAG, "consumer_mq_callback: %lu %lu", data->producer_counter, data->consumer_counter);

// Remove and add should not cause crash
// if(data->producer_counter == EVENT_LOOP_EVENT_COUNT/2) {
// furi_event_loop_message_queue_remove(data->consumer_event_loop, data->mq);
// furi_event_loop_message_queue_add(
// data->consumer_event_loop,
// data->mq,
// FuriEventLoopEventIn,
// test_furi_event_loop_producer_mq_callback,
// data);
// }
if(data->consumer_counter == EVENT_LOOP_EVENT_COUNT / 2) {
furi_event_loop_unsubscribe(data->consumer_event_loop, data->mq);
furi_event_loop_subscribe_message_queue(
data->consumer_event_loop,
data->mq,
FuriEventLoopEventIn,
test_furi_event_loop_consumer_mq_callback,
data);
}

if(data->consumer_counter == EVENT_LOOP_EVENT_COUNT) {
furi_event_loop_stop(data->consumer_event_loop);
Expand All @@ -137,7 +135,7 @@ int32_t test_furi_event_loop_consumer(void* p) {
FURI_LOG_I(TAG, "consumer start 1st run");

data->consumer_event_loop = furi_event_loop_alloc();
furi_event_loop_message_queue_subscribe(
furi_event_loop_subscribe_message_queue(
data->consumer_event_loop,
data->mq,
FuriEventLoopEventIn,
Expand All @@ -149,14 +147,14 @@ int32_t test_furi_event_loop_consumer(void* p) {
// 2 EventLoop index, 0xFFFFFFFF - all possible flags, emulate uncleared flags
xTaskNotifyIndexed(xTaskGetCurrentTaskHandle(), 2, 0xFFFFFFFF, eSetBits);

furi_event_loop_message_queue_unsubscribe(data->consumer_event_loop, data->mq);
furi_event_loop_unsubscribe(data->consumer_event_loop, data->mq);
furi_event_loop_free(data->consumer_event_loop);

FURI_LOG_I(TAG, "consumer start 2nd run");

data->consumer_counter = 0;
data->consumer_event_loop = furi_event_loop_alloc();
furi_event_loop_message_queue_subscribe(
furi_event_loop_subscribe_message_queue(
data->consumer_event_loop,
data->mq,
FuriEventLoopEventIn,
Expand All @@ -165,7 +163,7 @@ int32_t test_furi_event_loop_consumer(void* p) {

furi_event_loop_run(data->consumer_event_loop);

furi_event_loop_message_queue_unsubscribe(data->consumer_event_loop, data->mq);
furi_event_loop_unsubscribe(data->consumer_event_loop, data->mq);
furi_event_loop_free(data->consumer_event_loop);

FURI_LOG_I(TAG, "consumer end");
Expand Down
Loading
Loading