diff --git a/Modules/app-module/include/app/event.h b/Modules/app-module/include/app/event.h index 2edd857e4..69316ce7e 100644 --- a/Modules/app-module/include/app/event.h +++ b/Modules/app-module/include/app/event.h @@ -84,7 +84,8 @@ struct AppEventSubscription { * task_event_group_wait()/task_event_group_wait_any() on this group (OR sub->bit into the mask, * or use _wait_any() to include every subscription sharing it), then drain with app_event_poll(). * @retval ERROR_NONE on success - * @retval ERROR_RESOURCE @a event_group has no free bits left to claim + * @retval ERROR_RESOURCE @a event_group has no free bits left to claim; @a sub was not registered + * @retval ERROR_INVALID_STATE @a sub is already registered */ error_t app_event_subscribe(struct AppEventSubscription* sub, struct TaskEventGroup* event_group); @@ -115,6 +116,17 @@ 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 e5c963c4f..053f5d963 100644 --- a/Modules/app-module/source/event.cpp +++ b/Modules/app-module/source/event.cpp @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 #include +#include #include #include @@ -28,12 +29,19 @@ error_t app_event_subscribe(AppEventSubscription* sub, TaskEventGroup* event_gro return claim_result; } + mutex_lock(&subscriptions_mutex.handle); + + // Avoid cyclic subscription list that would loop forever + if (subscriptions == sub) { + mutex_unlock(&subscriptions_mutex.handle); + task_event_group_release_bit(event_group, bit); + return ERROR_INVALID_STATE; + } + sub->bit = bit; sub->internal.event_group = event_group; sub->internal.head = 0; sub->internal.count = 0; - - mutex_lock(&subscriptions_mutex.handle); sub->internal.next = subscriptions; subscriptions = sub; mutex_unlock(&subscriptions_mutex.handle); @@ -107,4 +115,28 @@ 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 9c79b5cb4..954ce3881 100644 --- a/Modules/app-module/source/symbols.cpp +++ b/Modules/app-module/source/symbols.cpp @@ -22,14 +22,7 @@ const ModuleSymbol app_module_symbols[] = { DEFINE_MODULE_SYMBOL(app_event_unsubscribe), DEFINE_MODULE_SYMBOL(app_event_emit), DEFINE_MODULE_SYMBOL(app_event_poll), - // tactility/concurrent/task_event_group - needed to construct the group app_event_subscribe() takes - DEFINE_MODULE_SYMBOL(task_event_group_construct), - DEFINE_MODULE_SYMBOL(task_event_group_destruct), - DEFINE_MODULE_SYMBOL(task_event_group_claim_bit), - DEFINE_MODULE_SYMBOL(task_event_group_release_bit), - DEFINE_MODULE_SYMBOL(task_event_group_signal), - DEFINE_MODULE_SYMBOL(task_event_group_wait), - DEFINE_MODULE_SYMBOL(task_event_group_wait_any), + DEFINE_MODULE_SYMBOL(app_event_loop_run), // app/install DEFINE_MODULE_SYMBOL(app_get_install_path), DEFINE_MODULE_SYMBOL(app_install), diff --git a/Platforms/platform-esp32/source/drivers/esp32_wifi.cpp b/Platforms/platform-esp32/source/drivers/esp32_wifi.cpp index 805cfff65..afae6d75a 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_wifi.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_wifi.cpp @@ -538,10 +538,18 @@ error_t api_event_subscribe(Device* device, WifiEventSubscription* sub, TaskEven if (claim_result != ERROR_NONE) { return claim_result; } - sub->internal.event_group = event_group; - sub->bit = bit; mutex_lock(&ctx->subscriptionsMutex); + + // Avoid cyclic subscription list that would loop forever + if (ctx->subscriptions == sub) { + mutex_unlock(&ctx->subscriptionsMutex); + task_event_group_release_bit(event_group, bit); + return ERROR_INVALID_STATE; + } + + sub->internal.event_group = event_group; + sub->bit = bit; sub->internal.next = ctx->subscriptions; ctx->subscriptions = sub; mutex_unlock(&ctx->subscriptionsMutex); @@ -629,6 +637,19 @@ error_t stop_device(Device* device) { bring_down_wifi(ctx); } + // Release any subscribers that never unsubscribed: device_stop() doesn't wait for apps still + // using this device, so a later wifi_event_unsubscribe() would find no ctx and skip releasing + // the bit and destructing sub->internal.ring_mutex. + mutex_lock(&ctx->subscriptionsMutex); + for (WifiEventSubscription* sub = ctx->subscriptions; sub != nullptr;) { + WifiEventSubscription* next = sub->internal.next; + task_event_group_release_bit(sub->internal.event_group, sub->bit); + mutex_destruct(&sub->internal.ring_mutex); + sub = next; + } + ctx->subscriptions = nullptr; + mutex_unlock(&ctx->subscriptionsMutex); + device_set_driver_data(device, nullptr); mutex_destruct(&ctx->subscriptionsMutex); mutex_destruct(&ctx->mutex); diff --git a/Platforms/platform-posix/source/drivers/mock_wifi.cpp b/Platforms/platform-posix/source/drivers/mock_wifi.cpp index 321bc7ac3..42c85e4dc 100644 --- a/Platforms/platform-posix/source/drivers/mock_wifi.cpp +++ b/Platforms/platform-posix/source/drivers/mock_wifi.cpp @@ -55,15 +55,15 @@ struct PosixWifiCtx { void fireEvent(PosixWifiCtx* ctx, WifiEvent event) { mutex_lock(&ctx->subscriptionsMutex); - for (WifiEventSubscription* sub = ctx->subscriptions; sub != nullptr; sub = sub->next) { - mutex_lock(&sub->ring_mutex); - if (sub->count < WIFI_EVENT_QUEUE_CAPACITY) { - uint8_t tail = (sub->head + sub->count) % WIFI_EVENT_QUEUE_CAPACITY; - sub->queue[tail] = event; - sub->count++; + for (WifiEventSubscription* sub = ctx->subscriptions; sub != nullptr; sub = sub->internal.next) { + mutex_lock(&sub->internal.ring_mutex); + if (sub->internal.count < WIFI_EVENT_QUEUE_CAPACITY) { + uint8_t tail = (sub->internal.head + sub->internal.count) % WIFI_EVENT_QUEUE_CAPACITY; + sub->internal.queue[tail] = event; + sub->internal.count++; } - mutex_unlock(&sub->ring_mutex); - task_event_group_signal(sub->event_group, sub->bit); + mutex_unlock(&sub->internal.ring_mutex); + task_event_group_signal(sub->internal.event_group, sub->bit); } mutex_unlock(&ctx->subscriptionsMutex); } @@ -266,12 +266,20 @@ error_t apiSetRadioOff(Device* device) { mutex_lock(&ctx->mutex); bool already_off = ctx->radioState == WIFI_RADIO_STATE_OFF; + bool was_connected = ctx->stationState != WIFI_STATION_STATE_DISCONNECTED; ctx->radioState = WIFI_RADIO_STATE_OFF; ctx->stationState = WIFI_STATION_STATE_DISCONNECTED; ctx->scanning = false; mutex_unlock(&ctx->mutex); if (already_off) return ERROR_NONE; + if (was_connected) { + WifiEvent station_event = {}; + station_event.type = WIFI_EVENT_TYPE_STATION_STATE_CHANGED; + station_event.station_state = WIFI_STATION_STATE_DISCONNECTED; + fireEvent(ctx, station_event); + } + WifiEvent radio_event = {}; radio_event.type = WIFI_EVENT_TYPE_RADIO_STATE_CHANGED; radio_event.radio_state = WIFI_RADIO_STATE_OFF; @@ -290,11 +298,19 @@ error_t apiEventSubscribe(Device* device, WifiEventSubscription* sub, TaskEventG if (claim_result != ERROR_NONE) { return claim_result; } - sub->event_group = event_group; - sub->bit = bit; mutex_lock(&ctx->subscriptionsMutex); - sub->next = ctx->subscriptions; + + // Avoid cyclic subscription list that would loop forever + if (ctx->subscriptions == sub) { + mutex_unlock(&ctx->subscriptionsMutex); + task_event_group_release_bit(event_group, bit); + return ERROR_INVALID_STATE; + } + + sub->internal.event_group = event_group; + sub->bit = bit; + sub->internal.next = ctx->subscriptions; ctx->subscriptions = sub; mutex_unlock(&ctx->subscriptionsMutex); return ERROR_NONE; @@ -306,9 +322,9 @@ error_t apiEventUnsubscribe(Device* device, WifiEventSubscription* sub) { error_t result = ERROR_NOT_FOUND; mutex_lock(&ctx->subscriptionsMutex); - for (WifiEventSubscription** link = &ctx->subscriptions; *link != nullptr; link = &(*link)->next) { + for (WifiEventSubscription** link = &ctx->subscriptions; *link != nullptr; link = &(*link)->internal.next) { if (*link == sub) { - *link = sub->next; + *link = sub->internal.next; result = ERROR_NONE; break; } @@ -316,7 +332,7 @@ error_t apiEventUnsubscribe(Device* device, WifiEventSubscription* sub) { mutex_unlock(&ctx->subscriptionsMutex); if (result == ERROR_NONE) { - task_event_group_release_bit(sub->event_group, sub->bit); + task_event_group_release_bit(sub->internal.event_group, sub->bit); } return result; } @@ -364,6 +380,19 @@ error_t stopDevice(Device* device) { apiSetRadioOff(device); } + // Release any subscribers that never unsubscribed: device_stop() doesn't wait for apps still + // using this device, so a later wifi_event_unsubscribe() would find no ctx and skip releasing + // the bit and destructing sub->internal.ring_mutex. + mutex_lock(&ctx->subscriptionsMutex); + for (WifiEventSubscription* sub = ctx->subscriptions; sub != nullptr;) { + WifiEventSubscription* next = sub->internal.next; + task_event_group_release_bit(sub->internal.event_group, sub->bit); + mutex_destruct(&sub->internal.ring_mutex); + sub = next; + } + ctx->subscriptions = nullptr; + mutex_unlock(&ctx->subscriptionsMutex); + device_set_driver_data(device, nullptr); mutex_destruct(&ctx->subscriptionsMutex); mutex_destruct(&ctx->mutex); diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index 3fcb52a0f..74f151409 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -141,7 +141,6 @@ namespace app { namespace boot { extern const ::AppManifest manifest; } namespace development { extern const ::AppManifest manifest; } namespace display { extern const ::AppManifest manifest; } - namespace kerneldisplay { extern const ::AppManifest manifest; } namespace files { extern const ::AppManifest manifest; } namespace fileselection { extern const ::AppManifest manifest; } namespace gpssettings { extern const ::AppManifest manifest; } @@ -206,7 +205,7 @@ static void registerInternalApps() { app_manager_add(&app::audiosettings::manifest); } if (device_exists_of_type(&DISPLAY_TYPE)) { - app_manager_add(&app::kerneldisplay::manifest); + app_manager_add(&app::display::manifest); } app_manager_add(&app::files::manifest); app_manager_add(&app::fileselection::manifest); diff --git a/Tactility/Source/app/apphub/AppHubApp.cpp b/Tactility/Source/app/apphub/AppHubApp.cpp index 23e3e4095..17b4808c3 100644 --- a/Tactility/Source/app/apphub/AppHubApp.cpp +++ b/Tactility/Source/app/apphub/AppHubApp.cpp @@ -201,35 +201,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 36d07c76e..d6c2268e2 100644 --- a/Tactility/Source/app/applist/AppList.cpp +++ b/Tactility/Source/app/applist/AppList.cpp @@ -81,32 +81,11 @@ 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); - 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; - } + app_event_loop_run(); 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 d2395d336..2f23a20f6 100644 --- a/Tactility/Source/app/appsettings/AppSettings.cpp +++ b/Tactility/Source/app/appsettings/AppSettings.cpp @@ -90,35 +90,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 9ece43edc..c352f8bcf 100644 --- a/Tactility/Source/app/apwebserver/ApWebServer.cpp +++ b/Tactility/Source/app/apwebserver/ApWebServer.cpp @@ -126,31 +126,9 @@ 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); - 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; - } - } + app_event_loop_run(); // 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 @@ -172,8 +150,6 @@ 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 dd6219bfb..c5f54b125 100644 --- a/Tactility/Source/app/audiosettings/AudioSettings.cpp +++ b/Tactility/Source/app/audiosettings/AudioSettings.cpp @@ -215,31 +215,9 @@ 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); - 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; - } - } + app_event_loop_run(); if (ctx.audioSubscription != nullptr) { service::audio::getPubsub()->unsubscribe(ctx.audioSubscription); @@ -247,8 +225,6 @@ 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 eb7c8dc53..3a2dd4c7b 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -292,13 +292,6 @@ 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); @@ -306,25 +299,11 @@ 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. - 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; - } + app_event_loop_run(); 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 4b7d7b298..f97c0f8db 100644 --- a/Tactility/Source/app/btmanage/BtManage.cpp +++ b/Tactility/Source/app/btmanage/BtManage.cpp @@ -220,13 +220,6 @@ 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; @@ -244,22 +237,7 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { bluetooth_scan_start(dev); } - 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; - } - } + app_event_loop_run(); // 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()). @@ -275,8 +253,6 @@ 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 170b53f5b..2dcc0d881 100644 --- a/Tactility/Source/app/chat/ChatApp.cpp +++ b/Tactility/Source/app/chat/ChatApp.cpp @@ -185,35 +185,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 5ef050dbc..30a3252f2 100644 --- a/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp +++ b/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp @@ -153,37 +153,13 @@ 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) { - 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; - } - } + app_event_loop_run(); } 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 86076fd3d..d1463531d 100644 --- a/Tactility/Source/app/development/Development.cpp +++ b/Tactility/Source/app/development/Development.cpp @@ -174,13 +174,6 @@ 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] { @@ -198,22 +191,7 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) { }); ctx.timer->start(); - 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; - } - } + app_event_loop_run(); // Equivalent of the old model's onHide(): ensure the periodic update isn't already happening. lvgl_lock(); @@ -221,8 +199,6 @@ 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/kerneldisplay/KernelDisplay.cpp b/Tactility/Source/app/display/Display.cpp similarity index 93% rename from Tactility/Source/app/kerneldisplay/KernelDisplay.cpp rename to Tactility/Source/app/display/Display.cpp index 24a56c701..2f177a7e3 100644 --- a/Tactility/Source/app/kerneldisplay/KernelDisplay.cpp +++ b/Tactility/Source/app/display/Display.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -25,11 +24,11 @@ #include #endif -namespace tt::app::kerneldisplay { +namespace tt::app::display { extern const ::AppManifest manifest; -constexpr auto* TAG = "KernelDisplay"; +constexpr auto* TAG = "Display"; namespace { @@ -308,36 +307,12 @@ 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); - 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; - } - } + app_event_loop_run(); + persistIfUpdated(ctx); window_manager_remove(window); - app_event_unsubscribe(&sub); - task_event_group_destruct(&event_group); return 0; } @@ -351,4 +326,4 @@ extern const ::AppManifest manifest = { .location = { APP_LOCATION_MEMORY, reinterpret_cast(appMain) } }; -} // namespace tt::app::kerneldisplay +} // namespace tt::app::display diff --git a/Tactility/Source/app/fileselection/FileSelection.cpp b/Tactility/Source/app/fileselection/FileSelection.cpp index 3baba0c46..2071b211f 100644 --- a/Tactility/Source/app/fileselection/FileSelection.cpp +++ b/Tactility/Source/app/fileselection/FileSelection.cpp @@ -62,32 +62,11 @@ 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); - 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; - } + app_event_loop_run(); 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 c4a18e93f..a5a521bb0 100644 --- a/Tactility/Source/app/i2cscanner/I2cScanner.cpp +++ b/Tactility/Source/app/i2cscanner/I2cScanner.cpp @@ -388,36 +388,12 @@ 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); - 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; - } - } + app_event_loop_run(); + stopScanningIfRunning(&ctx); 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 175fca478..8f453f97c 100644 --- a/Tactility/Source/app/imageviewer/ImageViewer.cpp +++ b/Tactility/Source/app/imageviewer/ImageViewer.cpp @@ -89,35 +89,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 877f44027..a8af63987 100644 --- a/Tactility/Source/app/inputdialog/InputDialog.cpp +++ b/Tactility/Source/app/inputdialog/InputDialog.cpp @@ -111,32 +111,11 @@ 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); - 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; - } + app_event_loop_run(); 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 08ce740cd..6d60042ac 100644 --- a/Tactility/Source/app/keyboard/KeyboardSettings.cpp +++ b/Tactility/Source/app/keyboard/KeyboardSettings.cpp @@ -209,36 +209,12 @@ 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); - 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; - } - } + app_event_loop_run(); + persistIfUpdated(ctx); 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 cb82386c6..a80fb61ba 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -234,34 +234,13 @@ 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). - 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; - } + app_event_loop_run(); 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 5c7d0c611..55b0ee59e 100644 --- a/Tactility/Source/app/localesettings/LocaleSettings.cpp +++ b/Tactility/Source/app/localesettings/LocaleSettings.cpp @@ -145,35 +145,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 34130857e..80cc699e7 100644 --- a/Tactility/Source/app/power/Power.cpp +++ b/Tactility/Source/app/power/Power.cpp @@ -240,37 +240,13 @@ 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(); - 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; - } - } + app_event_loop_run(); 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 5804f7104..8a00075af 100644 --- a/Tactility/Source/app/poweroff/PowerOff.cpp +++ b/Tactility/Source/app/poweroff/PowerOff.cpp @@ -136,35 +136,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 6fbe17783..a39bce81b 100644 --- a/Tactility/Source/app/screenshot/Screenshot.cpp +++ b/Tactility/Source/app/screenshot/Screenshot.cpp @@ -250,39 +250,15 @@ 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); - 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; - } - } + app_event_loop_run(); 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 dff75bba1..107483404 100644 --- a/Tactility/Source/app/selectiondialog/SelectionDialog.cpp +++ b/Tactility/Source/app/selectiondialog/SelectionDialog.cpp @@ -104,32 +104,11 @@ 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); - 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; - } + app_event_loop_run(); 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 61239aae3..63e8d5f1a 100644 --- a/Tactility/Source/app/settings/Settings.cpp +++ b/Tactility/Source/app/settings/Settings.cpp @@ -79,32 +79,11 @@ 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); - 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; - } + app_event_loop_run(); 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 db35843ce..cbb52b63e 100644 --- a/Tactility/Source/app/systeminfo/SystemInfo.cpp +++ b/Tactility/Source/app/systeminfo/SystemInfo.cpp @@ -417,39 +417,15 @@ 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 - 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; - } - } + app_event_loop_run(); 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 277d7499d..cc52fe6c3 100644 --- a/Tactility/Source/app/timezone/TimeZone.cpp +++ b/Tactility/Source/app/timezone/TimeZone.cpp @@ -240,34 +240,13 @@ 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(); - 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; - } + app_event_loop_run(); 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 56d4f77f4..988ce3cdf 100644 --- a/Tactility/Source/app/touchcalibration/TouchCalibration.cpp +++ b/Tactility/Source/app/touchcalibration/TouchCalibration.cpp @@ -233,35 +233,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 4040acb18..64e3a7529 100644 --- a/Tactility/Source/app/trackball/TrackballSettings.cpp +++ b/Tactility/Source/app/trackball/TrackballSettings.cpp @@ -272,36 +272,12 @@ 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); - 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; - } - } + app_event_loop_run(); + persistIfUpdated(ctx); 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 e867489c1..044e0bb80 100644 --- a/Tactility/Source/app/usbsettings/UsbSettings.cpp +++ b/Tactility/Source/app/usbsettings/UsbSettings.cpp @@ -85,35 +85,11 @@ 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); - 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; - } - } + app_event_loop_run(); 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 563cb76bd..19b37eb2b 100644 --- a/Tactility/Source/app/webserversettings/WebServerSettings.cpp +++ b/Tactility/Source/app/webserversettings/WebServerSettings.cpp @@ -362,31 +362,9 @@ 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); - 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; - } - } + app_event_loop_run(); // Equivalent of the old model's onHide(). if (ctx.updated) { @@ -427,8 +405,6 @@ 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/wifimanage/WifiManage.cpp b/Tactility/Source/app/wifimanage/WifiManage.cpp index cbb5502cc..6cb12f184 100644 --- a/Tactility/Source/app/wifimanage/WifiManage.cpp +++ b/Tactility/Source/app/wifimanage/WifiManage.cpp @@ -72,11 +72,14 @@ static void onConnectToHidden() { } void updateView(Context* ctx) { - ctx->lock(); + // Same lock order as createWidgets() (called with the LVGL lock already held, per the + // window-manager's WindowCreateWidgetsFn contract, then acquiring ctx->mutex) - acquiring + // these in the opposite order here would deadlock against a concurrent createWidgets() call. lvgl_lock(); + ctx->lock(); ctx->view.update(); - lvgl_unlock(); ctx->unlock(); + lvgl_unlock(); } void onWifiEvent(Context* ctx, WifiEvent event) { diff --git a/Tactility/Source/service/wifi/Wifi.cpp b/Tactility/Source/service/wifi/Wifi.cpp index 3ca2e6f95..ac8989c26 100644 --- a/Tactility/Source/service/wifi/Wifi.cpp +++ b/Tactility/Source/service/wifi/Wifi.cpp @@ -229,18 +229,7 @@ void dispatchConnect() { LOG_I(TAG, "Connecting to %s", target.ssid.c_str()); - error_t result = wifi_station_connect(state.device, target.ssid.c_str(), target.password.c_str(), target.channel); - if (result != ERROR_NONE) { - LOG_E(TAG, "Failed to connect to %s (%s)", target.ssid.c_str(), error_to_string(result)); - WifiEvent event = {}; - event.type = WIFI_EVENT_TYPE_STATION_CONNECTION_RESULT; - // The driver couldn't even initiate the connection attempt; there's no - // more specific WifiStationConnectionError for that. - event.connection_error = WIFI_STATION_CONNECTION_ERROR_TIMEOUT; - publish(event); - } - // On success, WIFI_EVENT_TYPE_STATION_STATE_CHANGED / _CONNECTION_RESULT arrive - // asynchronously via onWifiDeviceEvent(). + wifi_station_connect(state.device, target.ssid.c_str(), target.password.c_str(), target.channel); } void dispatchDisconnect() { @@ -373,10 +362,6 @@ void onWifiDeviceEvent(Device* device, ::WifiEvent event) { default: break; } - - // Forward the event as-is: subscribers inspect event.type and the - // relevant union field directly, same as this function does. - publish(event); } void autoScanSetPaused(bool paused) { diff --git a/TactilityKernel/include/tactility/drivers/wifi.h b/TactilityKernel/include/tactility/drivers/wifi.h index 0caad93d9..78c7cff6a 100644 --- a/TactilityKernel/include/tactility/drivers/wifi.h +++ b/TactilityKernel/include/tactility/drivers/wifi.h @@ -245,7 +245,8 @@ struct WifiApi { * mask, or use _wait_any() to include every subscription sharing it), then drain with * wifi_event_poll(). * @retval ERROR_NONE on success - * @retval ERROR_RESOURCE @a event_group has no free bits left to claim + * @retval ERROR_RESOURCE @a event_group has no free bits left to claim; @a sub was not registered + * @retval ERROR_INVALID_STATE @a sub is already registered */ error_t (*event_subscribe)(struct Device* device, struct WifiEventSubscription* sub, struct TaskEventGroup* event_group); @@ -298,7 +299,8 @@ error_t wifi_station_get_rssi(struct Device* device, int32_t* rssi); * into the mask, or use _wait_any() to include every subscription sharing it), then drain with * wifi_event_poll(). * @retval ERROR_NONE on success - * @retval ERROR_RESOURCE @a event_group has no free bits left to claim + * @retval ERROR_RESOURCE @a event_group has no free bits left to claim; @a sub was not registered + * @retval ERROR_INVALID_STATE @a sub is already registered */ error_t wifi_event_subscribe(struct Device* device, struct WifiEventSubscription* sub, struct TaskEventGroup* event_group); diff --git a/TactilityKernel/source/system_event.cpp b/TactilityKernel/source/system_event.cpp index 66beffbe0..d77602a6f 100644 --- a/TactilityKernel/source/system_event.cpp +++ b/TactilityKernel/source/system_event.cpp @@ -173,15 +173,11 @@ error_t system_event_subscribe(SystemEventSubscription* sub, TaskEventGroup* eve mutex_lock(&poll_subscriptions_mutex.handle); - // Check-and-insert in one critical section: registering the same `sub` twice would link - // it into a list that already contains it, creating a cycle that notify_poll_subscribers() - // would then traverse forever while holding this same mutex. - for (SystemEventSubscription* existing = poll_subscriptions; existing != nullptr; existing = existing->internal.next) { - if (existing == sub) { - mutex_unlock(&poll_subscriptions_mutex.handle); - task_event_group_release_bit(event_group, bit); - return ERROR_INVALID_STATE; - } + // Avoid cyclic subscription list that would loop forever + if (poll_subscriptions == sub) { + mutex_unlock(&poll_subscriptions_mutex.handle); + task_event_group_release_bit(event_group, bit); + return ERROR_INVALID_STATE; } sub->internal.event_group = event_group;