diff --git a/Documentation/ideas.md b/Documentation/ideas.md index f88418540..99dd68e2d 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -11,6 +11,7 @@ ## Higher Priority +- stopAppFromToolbar() in Tactility.cpp stops the top-most app. Change it so the toolbar knows for which app id it is created, so it can rely on that. - Warn if file operations are done from prohibited tasks (e.g. lvgl task) - AppHubApp: Prevent download callbacks from accessing a destroyed view. - Move USB host task stacks to SPIRAM when available: esp32_usbhost*.cpp diff --git a/Modules/app-module/include/app/event.h b/Modules/app-module/include/app/event.h index 69316ce7e..bddc847f7 100644 --- a/Modules/app-module/include/app/event.h +++ b/Modules/app-module/include/app/event.h @@ -116,17 +116,6 @@ error_t app_event_emit(AppInstanceId app_instance_id, const struct AppEvent* eve */ error_t app_event_poll(struct AppEventSubscription* sub, struct AppEvent* out_event); -/** - * Blocks the calling app's task until it receives APP_EVENT_CLOSE, then returns. For apps that - * don't care about APP_EVENT_RESULT or any other app event - just "run until told to close". - * Owns its own subscription/event group for the call's duration (construct/subscribe on entry, - * unsubscribe/destruct before returning); does not interact with any subscription the caller - * manages itself. - * @warning Does not work in ISR context. Must be called from the app's own task (uses - * app_scheduler_current_app_id()). - */ -void app_event_loop_run(void); - #ifdef __cplusplus } #endif diff --git a/Modules/app-module/source/event.cpp b/Modules/app-module/source/event.cpp index 053f5d963..05606f1c8 100644 --- a/Modules/app-module/source/event.cpp +++ b/Modules/app-module/source/event.cpp @@ -1,6 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 #include -#include #include #include @@ -115,28 +114,4 @@ error_t app_event_poll(AppEventSubscription* sub, AppEvent* out_event) { return try_pop(sub, out_event) ? ERROR_NONE : ERROR_TIMEOUT; } -void app_event_loop_run(void) { - TaskEventGroup event_group {}; - task_event_group_construct(&event_group); - - AppEventSubscription sub {}; - sub.app_instance_id = app_scheduler_current_app_id(); - app_event_subscribe(&sub, &event_group); - - bool should_close = false; - while (!should_close) { - task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); - - AppEvent event {}; - while (app_event_poll(&sub, &event) == ERROR_NONE) { - if (event.type == APP_EVENT_CLOSE) { - should_close = true; - } - } - } - - app_event_unsubscribe(&sub); - task_event_group_destruct(&event_group); -} - } // extern "C" diff --git a/Modules/app-module/source/symbols.cpp b/Modules/app-module/source/symbols.cpp index 954ce3881..871f6b0fe 100644 --- a/Modules/app-module/source/symbols.cpp +++ b/Modules/app-module/source/symbols.cpp @@ -22,7 +22,6 @@ const ModuleSymbol app_module_symbols[] = { DEFINE_MODULE_SYMBOL(app_event_unsubscribe), DEFINE_MODULE_SYMBOL(app_event_emit), DEFINE_MODULE_SYMBOL(app_event_poll), - DEFINE_MODULE_SYMBOL(app_event_loop_run), // app/install DEFINE_MODULE_SYMBOL(app_get_install_path), DEFINE_MODULE_SYMBOL(app_install), diff --git a/Tactility/Source/app/apphub/AppHubApp.cpp b/Tactility/Source/app/apphub/AppHubApp.cpp index 17b4808c3..23e3e4095 100644 --- a/Tactility/Source/app/apphub/AppHubApp.cpp +++ b/Tactility/Source/app/apphub/AppHubApp.cpp @@ -201,11 +201,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create_ext(appInstanceId, createWidgets, destroyWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/applist/AppList.cpp b/Tactility/Source/app/applist/AppList.cpp index d6c2268e2..36d07c76e 100644 --- a/Tactility/Source/app/applist/AppList.cpp +++ b/Tactility/Source/app/applist/AppList.cpp @@ -81,11 +81,32 @@ void createWidgets(lv_obj_t* parent, void*) { int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { appListInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr); - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/appsettings/AppSettings.cpp b/Tactility/Source/app/appsettings/AppSettings.cpp index 2f23a20f6..d2395d336 100644 --- a/Tactility/Source/app/appsettings/AppSettings.cpp +++ b/Tactility/Source/app/appsettings/AppSettings.cpp @@ -90,11 +90,35 @@ void createWidgets(lv_obj_t* parent, void*) { int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { appSettingsInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/apwebserver/ApWebServer.cpp b/Tactility/Source/app/apwebserver/ApWebServer.cpp index c352f8bcf..9ece43edc 100644 --- a/Tactility/Source/app/apwebserver/ApWebServer.cpp +++ b/Tactility/Source/app/apwebserver/ApWebServer.cpp @@ -126,9 +126,31 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { ctx.appInstanceId = appInstanceId; ctx.wsSettings = settings::webserver::loadOrGetDefault(); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } // Equivalent of the old model's onHide(): persist the ORIGINAL settings (as loaded at // startup, not the temporary AP-mode config createWidgets() applied above) and revert the @@ -150,6 +172,8 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { }); window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/audiosettings/AudioSettings.cpp b/Tactility/Source/app/audiosettings/AudioSettings.cpp index c5f54b125..dd6219bfb 100644 --- a/Tactility/Source/app/audiosettings/AudioSettings.cpp +++ b/Tactility/Source/app/audiosettings/AudioSettings.cpp @@ -215,9 +215,31 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } if (ctx.audioSubscription != nullptr) { service::audio::getPubsub()->unsubscribe(ctx.audioSubscription); @@ -225,6 +247,8 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index 3a2dd4c7b..eb7c8dc53 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -292,6 +292,13 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { isUsbBootSplash = hal::usb::isUsbBootMode(); sdCardMissing = false; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + bootWindowId = window_manager_create(appInstanceId, createSplashWidgets, nullptr); runBootSequence(start_time); @@ -299,11 +306,25 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { // Waits until app_manager_start(launcher) (or a permanent stop) tells us to give up - // startNextApp() above is what triggers that, via app-module's "save the previously active // app" policy, unless sdCardMissing halted before it. - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } if (bootWindowId != 0) { window_manager_remove(bootWindowId); } + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/btmanage/BtManage.cpp b/Tactility/Source/app/btmanage/BtManage.cpp index f97c0f8db..4b7d7b298 100644 --- a/Tactility/Source/app/btmanage/BtManage.cpp +++ b/Tactility/Source/app/btmanage/BtManage.cpp @@ -220,6 +220,13 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { ctx.state.updateScanResults(); ctx.state.updatePairedPeers(); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); ctx.btDevice = dev; @@ -237,7 +244,22 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { bluetooth_scan_start(dev); } - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } // Invalidate any BT event dispatched-but-not-yet-run for this instance before doing // anything else, so it can't race the teardown below (see onKernelBtEvent()). @@ -253,6 +275,8 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/chat/ChatApp.cpp b/Tactility/Source/app/chat/ChatApp.cpp index 2dcc0d881..170b53f5b 100644 --- a/Tactility/Source/app/chat/ChatApp.cpp +++ b/Tactility/Source/app/chat/ChatApp.cpp @@ -185,11 +185,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { ); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); service::espnow::unsubscribeReceiver(ctx.receiveSubscription); disableEspNow(&ctx); diff --git a/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp b/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp index 30a3252f2..5ef050dbc 100644 --- a/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp +++ b/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp @@ -153,13 +153,37 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); if (!ctx.hasFatalError) { - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); bool continuePressed = ctx.continuePressed; diff --git a/Tactility/Source/app/development/Development.cpp b/Tactility/Source/app/development/Development.cpp index d1463531d..86076fd3d 100644 --- a/Tactility/Source/app/development/Development.cpp +++ b/Tactility/Source/app/development/Development.cpp @@ -174,6 +174,13 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { return 0; } + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); ctx.timer = std::make_unique(Timer::Type::Periodic, pdMS_TO_TICKS(1000), [&ctx, window] { @@ -191,7 +198,22 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { }); ctx.timer->start(); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } // Equivalent of the old model's onHide(): ensure the periodic update isn't already happening. lvgl_lock(); @@ -199,6 +221,8 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { lvgl_unlock(); window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/display/Display.cpp b/Tactility/Source/app/display/Display.cpp index 2f177a7e3..08c768ae0 100644 --- a/Tactility/Source/app/display/Display.cpp +++ b/Tactility/Source/app/display/Display.cpp @@ -307,12 +307,36 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); - persistIfUpdated(ctx); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + persistIfUpdated(ctx); + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/fileselection/FileSelection.cpp b/Tactility/Source/app/fileselection/FileSelection.cpp index 2071b211f..3baba0c46 100644 --- a/Tactility/Source/app/fileselection/FileSelection.cpp +++ b/Tactility/Source/app/fileselection/FileSelection.cpp @@ -62,11 +62,32 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { app_event_emit(appInstanceId, &closeEvent); }); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return ctx.result; } diff --git a/Tactility/Source/app/i2cscanner/I2cScanner.cpp b/Tactility/Source/app/i2cscanner/I2cScanner.cpp index a5a521bb0..c4a18e93f 100644 --- a/Tactility/Source/app/i2cscanner/I2cScanner.cpp +++ b/Tactility/Source/app/i2cscanner/I2cScanner.cpp @@ -388,12 +388,36 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); - stopScanningIfRunning(&ctx); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + stopScanningIfRunning(&ctx); + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/imageviewer/ImageViewer.cpp b/Tactility/Source/app/imageviewer/ImageViewer.cpp index 8f453f97c..175fca478 100644 --- a/Tactility/Source/app/imageviewer/ImageViewer.cpp +++ b/Tactility/Source/app/imageviewer/ImageViewer.cpp @@ -89,11 +89,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { ctx.appInstanceId = appInstanceId; ctx.filePath = argv[0]; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/inputdialog/InputDialog.cpp b/Tactility/Source/app/inputdialog/InputDialog.cpp index a8af63987..877f44027 100644 --- a/Tactility/Source/app/inputdialog/InputDialog.cpp +++ b/Tactility/Source/app/inputdialog/InputDialog.cpp @@ -111,11 +111,32 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { ctx.argc = argc; ctx.argv = argv; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return ctx.result; } diff --git a/Tactility/Source/app/keyboard/KeyboardSettings.cpp b/Tactility/Source/app/keyboard/KeyboardSettings.cpp index 6d60042ac..08ce740cd 100644 --- a/Tactility/Source/app/keyboard/KeyboardSettings.cpp +++ b/Tactility/Source/app/keyboard/KeyboardSettings.cpp @@ -209,12 +209,36 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); - persistIfUpdated(ctx); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + persistIfUpdated(ctx); + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/launcher/Launcher.cpp b/Tactility/Source/app/launcher/Launcher.cpp index a80fb61ba..cb82386c6 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -234,13 +234,34 @@ void runAutoStart() { int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { runAutoStart(); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr); // The launcher is meant to stay resident (it's the home screen) - it only gives up its // thread when app-module's scheduler asks it to (e.g. another new-model app is started). - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/localesettings/LocaleSettings.cpp b/Tactility/Source/app/localesettings/LocaleSettings.cpp index 55b0ee59e..5c7d0c611 100644 --- a/Tactility/Source/app/localesettings/LocaleSettings.cpp +++ b/Tactility/Source/app/localesettings/LocaleSettings.cpp @@ -145,11 +145,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/power/Power.cpp b/Tactility/Source/app/power/Power.cpp index 80cc699e7..34130857e 100644 --- a/Tactility/Source/app/power/Power.cpp +++ b/Tactility/Source/app/power/Power.cpp @@ -240,13 +240,37 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { updateUi(&ctx); }); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); ctx.timer->start(); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } ctx.timer->stop(); window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/poweroff/PowerOff.cpp b/Tactility/Source/app/poweroff/PowerOff.cpp index 8a00075af..5804f7104 100644 --- a/Tactility/Source/app/poweroff/PowerOff.cpp +++ b/Tactility/Source/app/poweroff/PowerOff.cpp @@ -136,11 +136,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/screenshot/Screenshot.cpp b/Tactility/Source/app/screenshot/Screenshot.cpp index a39bce81b..6fbe17783 100644 --- a/Tactility/Source/app/screenshot/Screenshot.cpp +++ b/Tactility/Source/app/screenshot/Screenshot.cpp @@ -250,15 +250,39 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { } }); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } if (ctx.updateTimer->isRunning()) { ctx.updateTimer->stop(); } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/selectiondialog/SelectionDialog.cpp b/Tactility/Source/app/selectiondialog/SelectionDialog.cpp index 107483404..dff75bba1 100644 --- a/Tactility/Source/app/selectiondialog/SelectionDialog.cpp +++ b/Tactility/Source/app/selectiondialog/SelectionDialog.cpp @@ -104,11 +104,32 @@ int32_t appMain(AppInstanceId appInstanceId, int argc, char* argv[]) { ctx.argc = argc; ctx.argv = argv; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return ctx.result; } diff --git a/Tactility/Source/app/settings/Settings.cpp b/Tactility/Source/app/settings/Settings.cpp index 63e8d5f1a..61239aae3 100644 --- a/Tactility/Source/app/settings/Settings.cpp +++ b/Tactility/Source/app/settings/Settings.cpp @@ -79,11 +79,32 @@ void createWidgets(lv_obj_t* parent, void*) { int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { settingsInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr); - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/systeminfo/SystemInfo.cpp b/Tactility/Source/app/systeminfo/SystemInfo.cpp index cbb52b63e..db35843ce 100644 --- a/Tactility/Source/app/systeminfo/SystemInfo.cpp +++ b/Tactility/Source/app/systeminfo/SystemInfo.cpp @@ -417,15 +417,39 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { lvgl_unlock(); }); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); ctx.memoryTimer->start(); // Memory: every 10s ctx.tasksTimer->start(); // Tasks/CPU: every 15s - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } ctx.memoryTimer->stop(); ctx.tasksTimer->stop(); window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/timezone/TimeZone.cpp b/Tactility/Source/app/timezone/TimeZone.cpp index cc52fe6c3..277d7499d 100644 --- a/Tactility/Source/app/timezone/TimeZone.cpp +++ b/Tactility/Source/app/timezone/TimeZone.cpp @@ -240,13 +240,34 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { updateList(&ctx); }); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); ctx.updateTimer->start(); - app_event_loop_run(); + while (true) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + bool shouldClose = false; + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + if (event.type == APP_EVENT_CLOSE) { + shouldClose = true; + break; + } + } + if (shouldClose) break; + } ctx.updateTimer->stop(); window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return ctx.result; } diff --git a/Tactility/Source/app/touchcalibration/TouchCalibration.cpp b/Tactility/Source/app/touchcalibration/TouchCalibration.cpp index 988ce3cdf..56d4f77f4 100644 --- a/Tactility/Source/app/touchcalibration/TouchCalibration.cpp +++ b/Tactility/Source/app/touchcalibration/TouchCalibration.cpp @@ -233,11 +233,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { } lvgl_unlock(); + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); // finishCalibration() already applied a new calibration on success. On cancel/failure, // restore whatever calibration was on disk before the block above cleared it. diff --git a/Tactility/Source/app/trackball/TrackballSettings.cpp b/Tactility/Source/app/trackball/TrackballSettings.cpp index 64e3a7529..4040acb18 100644 --- a/Tactility/Source/app/trackball/TrackballSettings.cpp +++ b/Tactility/Source/app/trackball/TrackballSettings.cpp @@ -272,12 +272,36 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); - persistIfUpdated(ctx); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + persistIfUpdated(ctx); + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/usbsettings/UsbSettings.cpp b/Tactility/Source/app/usbsettings/UsbSettings.cpp index 044e0bb80..e867489c1 100644 --- a/Tactility/Source/app/usbsettings/UsbSettings.cpp +++ b/Tactility/Source/app/usbsettings/UsbSettings.cpp @@ -85,11 +85,35 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { Context ctx {}; ctx.appInstanceId = appInstanceId; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; } diff --git a/Tactility/Source/app/webserversettings/WebServerSettings.cpp b/Tactility/Source/app/webserversettings/WebServerSettings.cpp index 19b37eb2b..563cb76bd 100644 --- a/Tactility/Source/app/webserversettings/WebServerSettings.cpp +++ b/Tactility/Source/app/webserversettings/WebServerSettings.cpp @@ -362,9 +362,31 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { ctx.wsSettings.webServerEnabled = service::webserver::isWebServerEnabled(); ctx.originalSettings = ctx.wsSettings; + TaskEventGroup event_group {}; + task_event_group_construct(&event_group); + + AppEventSubscription sub {}; + sub.app_instance_id = appInstanceId; + app_event_subscribe(&sub, &event_group); + WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx); - app_event_loop_run(); + bool shouldClose = false; + while (!shouldClose) { + task_event_group_wait_any(&event_group, nullptr, portMAX_DELAY); + + AppEvent event {}; + while (app_event_poll(&sub, &event) == ERROR_NONE) { + switch (event.type) { + case APP_EVENT_CLOSE: + shouldClose = true; + break; + default: + break; + } + if (shouldClose) break; + } + } // Equivalent of the old model's onHide(). if (ctx.updated) { @@ -405,6 +427,8 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { } window_manager_remove(window); + app_event_unsubscribe(&sub); + task_event_group_destruct(&event_group); return 0; }