mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-10-20 12:25:06 +00:00
Fixes and improvements
This commit is contained in:
parent
f15154392f
commit
c5ae4d1595
@ -84,7 +84,8 @@ struct AppEventSubscription {
|
|||||||
* task_event_group_wait()/task_event_group_wait_any() on this group (OR sub->bit into the mask,
|
* 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().
|
* or use _wait_any() to include every subscription sharing it), then drain with app_event_poll().
|
||||||
* @retval ERROR_NONE on success
|
* @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);
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
#include <app/event.h>
|
#include <app/event.h>
|
||||||
|
#include <app/scheduler.h>
|
||||||
|
|
||||||
#include <tactility/concurrent/mutex.h>
|
#include <tactility/concurrent/mutex.h>
|
||||||
#include <tactility/time.h>
|
#include <tactility/time.h>
|
||||||
@ -28,12 +29,19 @@ error_t app_event_subscribe(AppEventSubscription* sub, TaskEventGroup* event_gro
|
|||||||
return claim_result;
|
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->bit = bit;
|
||||||
sub->internal.event_group = event_group;
|
sub->internal.event_group = event_group;
|
||||||
sub->internal.head = 0;
|
sub->internal.head = 0;
|
||||||
sub->internal.count = 0;
|
sub->internal.count = 0;
|
||||||
|
|
||||||
mutex_lock(&subscriptions_mutex.handle);
|
|
||||||
sub->internal.next = subscriptions;
|
sub->internal.next = subscriptions;
|
||||||
subscriptions = sub;
|
subscriptions = sub;
|
||||||
mutex_unlock(&subscriptions_mutex.handle);
|
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;
|
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"
|
} // extern "C"
|
||||||
|
|||||||
@ -22,14 +22,7 @@ const ModuleSymbol app_module_symbols[] = {
|
|||||||
DEFINE_MODULE_SYMBOL(app_event_unsubscribe),
|
DEFINE_MODULE_SYMBOL(app_event_unsubscribe),
|
||||||
DEFINE_MODULE_SYMBOL(app_event_emit),
|
DEFINE_MODULE_SYMBOL(app_event_emit),
|
||||||
DEFINE_MODULE_SYMBOL(app_event_poll),
|
DEFINE_MODULE_SYMBOL(app_event_poll),
|
||||||
// tactility/concurrent/task_event_group - needed to construct the group app_event_subscribe() takes
|
DEFINE_MODULE_SYMBOL(app_event_loop_run),
|
||||||
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),
|
|
||||||
// app/install
|
// app/install
|
||||||
DEFINE_MODULE_SYMBOL(app_get_install_path),
|
DEFINE_MODULE_SYMBOL(app_get_install_path),
|
||||||
DEFINE_MODULE_SYMBOL(app_install),
|
DEFINE_MODULE_SYMBOL(app_install),
|
||||||
|
|||||||
@ -538,10 +538,18 @@ error_t api_event_subscribe(Device* device, WifiEventSubscription* sub, TaskEven
|
|||||||
if (claim_result != ERROR_NONE) {
|
if (claim_result != ERROR_NONE) {
|
||||||
return claim_result;
|
return claim_result;
|
||||||
}
|
}
|
||||||
sub->internal.event_group = event_group;
|
|
||||||
sub->bit = bit;
|
|
||||||
|
|
||||||
mutex_lock(&ctx->subscriptionsMutex);
|
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;
|
sub->internal.next = ctx->subscriptions;
|
||||||
ctx->subscriptions = sub;
|
ctx->subscriptions = sub;
|
||||||
mutex_unlock(&ctx->subscriptionsMutex);
|
mutex_unlock(&ctx->subscriptionsMutex);
|
||||||
@ -629,6 +637,19 @@ error_t stop_device(Device* device) {
|
|||||||
bring_down_wifi(ctx);
|
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);
|
device_set_driver_data(device, nullptr);
|
||||||
mutex_destruct(&ctx->subscriptionsMutex);
|
mutex_destruct(&ctx->subscriptionsMutex);
|
||||||
mutex_destruct(&ctx->mutex);
|
mutex_destruct(&ctx->mutex);
|
||||||
|
|||||||
@ -55,15 +55,15 @@ struct PosixWifiCtx {
|
|||||||
|
|
||||||
void fireEvent(PosixWifiCtx* ctx, WifiEvent event) {
|
void fireEvent(PosixWifiCtx* ctx, WifiEvent event) {
|
||||||
mutex_lock(&ctx->subscriptionsMutex);
|
mutex_lock(&ctx->subscriptionsMutex);
|
||||||
for (WifiEventSubscription* sub = ctx->subscriptions; sub != nullptr; sub = sub->next) {
|
for (WifiEventSubscription* sub = ctx->subscriptions; sub != nullptr; sub = sub->internal.next) {
|
||||||
mutex_lock(&sub->ring_mutex);
|
mutex_lock(&sub->internal.ring_mutex);
|
||||||
if (sub->count < WIFI_EVENT_QUEUE_CAPACITY) {
|
if (sub->internal.count < WIFI_EVENT_QUEUE_CAPACITY) {
|
||||||
uint8_t tail = (sub->head + sub->count) % WIFI_EVENT_QUEUE_CAPACITY;
|
uint8_t tail = (sub->internal.head + sub->internal.count) % WIFI_EVENT_QUEUE_CAPACITY;
|
||||||
sub->queue[tail] = event;
|
sub->internal.queue[tail] = event;
|
||||||
sub->count++;
|
sub->internal.count++;
|
||||||
}
|
}
|
||||||
mutex_unlock(&sub->ring_mutex);
|
mutex_unlock(&sub->internal.ring_mutex);
|
||||||
task_event_group_signal(sub->event_group, sub->bit);
|
task_event_group_signal(sub->internal.event_group, sub->bit);
|
||||||
}
|
}
|
||||||
mutex_unlock(&ctx->subscriptionsMutex);
|
mutex_unlock(&ctx->subscriptionsMutex);
|
||||||
}
|
}
|
||||||
@ -266,12 +266,20 @@ error_t apiSetRadioOff(Device* device) {
|
|||||||
|
|
||||||
mutex_lock(&ctx->mutex);
|
mutex_lock(&ctx->mutex);
|
||||||
bool already_off = ctx->radioState == WIFI_RADIO_STATE_OFF;
|
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->radioState = WIFI_RADIO_STATE_OFF;
|
||||||
ctx->stationState = WIFI_STATION_STATE_DISCONNECTED;
|
ctx->stationState = WIFI_STATION_STATE_DISCONNECTED;
|
||||||
ctx->scanning = false;
|
ctx->scanning = false;
|
||||||
mutex_unlock(&ctx->mutex);
|
mutex_unlock(&ctx->mutex);
|
||||||
if (already_off) return ERROR_NONE;
|
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 = {};
|
WifiEvent radio_event = {};
|
||||||
radio_event.type = WIFI_EVENT_TYPE_RADIO_STATE_CHANGED;
|
radio_event.type = WIFI_EVENT_TYPE_RADIO_STATE_CHANGED;
|
||||||
radio_event.radio_state = WIFI_RADIO_STATE_OFF;
|
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) {
|
if (claim_result != ERROR_NONE) {
|
||||||
return claim_result;
|
return claim_result;
|
||||||
}
|
}
|
||||||
sub->event_group = event_group;
|
|
||||||
sub->bit = bit;
|
|
||||||
|
|
||||||
mutex_lock(&ctx->subscriptionsMutex);
|
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;
|
ctx->subscriptions = sub;
|
||||||
mutex_unlock(&ctx->subscriptionsMutex);
|
mutex_unlock(&ctx->subscriptionsMutex);
|
||||||
return ERROR_NONE;
|
return ERROR_NONE;
|
||||||
@ -306,9 +322,9 @@ error_t apiEventUnsubscribe(Device* device, WifiEventSubscription* sub) {
|
|||||||
|
|
||||||
error_t result = ERROR_NOT_FOUND;
|
error_t result = ERROR_NOT_FOUND;
|
||||||
mutex_lock(&ctx->subscriptionsMutex);
|
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) {
|
if (*link == sub) {
|
||||||
*link = sub->next;
|
*link = sub->internal.next;
|
||||||
result = ERROR_NONE;
|
result = ERROR_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -316,7 +332,7 @@ error_t apiEventUnsubscribe(Device* device, WifiEventSubscription* sub) {
|
|||||||
mutex_unlock(&ctx->subscriptionsMutex);
|
mutex_unlock(&ctx->subscriptionsMutex);
|
||||||
|
|
||||||
if (result == ERROR_NONE) {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@ -364,6 +380,19 @@ error_t stopDevice(Device* device) {
|
|||||||
apiSetRadioOff(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);
|
device_set_driver_data(device, nullptr);
|
||||||
mutex_destruct(&ctx->subscriptionsMutex);
|
mutex_destruct(&ctx->subscriptionsMutex);
|
||||||
mutex_destruct(&ctx->mutex);
|
mutex_destruct(&ctx->mutex);
|
||||||
|
|||||||
@ -141,7 +141,6 @@ namespace app {
|
|||||||
namespace boot { extern const ::AppManifest manifest; }
|
namespace boot { extern const ::AppManifest manifest; }
|
||||||
namespace development { extern const ::AppManifest manifest; }
|
namespace development { extern const ::AppManifest manifest; }
|
||||||
namespace display { extern const ::AppManifest manifest; }
|
namespace display { extern const ::AppManifest manifest; }
|
||||||
namespace kerneldisplay { extern const ::AppManifest manifest; }
|
|
||||||
namespace files { extern const ::AppManifest manifest; }
|
namespace files { extern const ::AppManifest manifest; }
|
||||||
namespace fileselection { extern const ::AppManifest manifest; }
|
namespace fileselection { extern const ::AppManifest manifest; }
|
||||||
namespace gpssettings { extern const ::AppManifest manifest; }
|
namespace gpssettings { extern const ::AppManifest manifest; }
|
||||||
@ -206,7 +205,7 @@ static void registerInternalApps() {
|
|||||||
app_manager_add(&app::audiosettings::manifest);
|
app_manager_add(&app::audiosettings::manifest);
|
||||||
}
|
}
|
||||||
if (device_exists_of_type(&DISPLAY_TYPE)) {
|
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::files::manifest);
|
||||||
app_manager_add(&app::fileselection::manifest);
|
app_manager_add(&app::fileselection::manifest);
|
||||||
|
|||||||
@ -201,35 +201,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx;
|
Context ctx;
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create_ext(appInstanceId, createWidgets, destroyWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,32 +81,11 @@ void createWidgets(lv_obj_t* parent, void*) {
|
|||||||
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
||||||
appListInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr);
|
||||||
|
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -90,35 +90,11 @@ void createWidgets(lv_obj_t* parent, void*) {
|
|||||||
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
||||||
appSettingsInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -126,31 +126,9 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
ctx.appInstanceId = appInstanceId;
|
ctx.appInstanceId = appInstanceId;
|
||||||
ctx.wsSettings = settings::webserver::loadOrGetDefault();
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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
|
// 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
|
// 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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,31 +215,9 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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) {
|
if (ctx.audioSubscription != nullptr) {
|
||||||
service::audio::getPubsub()->unsubscribe(ctx.audioSubscription);
|
service::audio::getPubsub()->unsubscribe(ctx.audioSubscription);
|
||||||
@ -247,8 +225,6 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -292,13 +292,6 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
isUsbBootSplash = hal::usb::isUsbBootMode();
|
isUsbBootSplash = hal::usb::isUsbBootMode();
|
||||||
sdCardMissing = false;
|
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);
|
bootWindowId = window_manager_create(appInstanceId, createSplashWidgets, nullptr);
|
||||||
|
|
||||||
runBootSequence(start_time);
|
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 -
|
// 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
|
// startNextApp() above is what triggers that, via app-module's "save the previously active
|
||||||
// app" policy, unless sdCardMissing halted before it.
|
// app" policy, unless sdCardMissing halted before it.
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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) {
|
if (bootWindowId != 0) {
|
||||||
window_manager_remove(bootWindowId);
|
window_manager_remove(bootWindowId);
|
||||||
}
|
}
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -220,13 +220,6 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
ctx.state.updateScanResults();
|
ctx.state.updateScanResults();
|
||||||
ctx.state.updatePairedPeers();
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
ctx.btDevice = dev;
|
ctx.btDevice = dev;
|
||||||
@ -244,22 +237,7 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
bluetooth_scan_start(dev);
|
bluetooth_scan_start(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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
|
// 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()).
|
// 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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
service::espnow::unsubscribeReceiver(ctx.receiveSubscription);
|
service::espnow::unsubscribeReceiver(ctx.receiveSubscription);
|
||||||
disableEspNow(&ctx);
|
disableEspNow(&ctx);
|
||||||
|
|||||||
@ -153,37 +153,13 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
if (!ctx.hasFatalError) {
|
if (!ctx.hasFatalError) {
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
bool continuePressed = ctx.continuePressed;
|
bool continuePressed = ctx.continuePressed;
|
||||||
|
|
||||||
|
|||||||
@ -174,13 +174,6 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
return 0;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
ctx.timer = std::make_unique<Timer>(Timer::Type::Periodic, pdMS_TO_TICKS(1000), [&ctx, window] {
|
ctx.timer = std::make_unique<Timer>(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();
|
ctx.timer->start();
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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.
|
// Equivalent of the old model's onHide(): ensure the periodic update isn't already happening.
|
||||||
lvgl_lock();
|
lvgl_lock();
|
||||||
@ -221,8 +199,6 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
lvgl_unlock();
|
lvgl_unlock();
|
||||||
|
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,6 @@
|
|||||||
#include <Tactility/settings/DisplaySettings.h>
|
#include <Tactility/settings/DisplaySettings.h>
|
||||||
|
|
||||||
#include <app/event.h>
|
#include <app/event.h>
|
||||||
#include <app/manager.h>
|
|
||||||
#include <app/manifest.h>
|
#include <app/manifest.h>
|
||||||
|
|
||||||
#include <lvgl_window_manager/window_manager.h>
|
#include <lvgl_window_manager/window_manager.h>
|
||||||
@ -25,11 +24,11 @@
|
|||||||
#include <sdkconfig.h>
|
#include <sdkconfig.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace tt::app::kerneldisplay {
|
namespace tt::app::display {
|
||||||
|
|
||||||
extern const ::AppManifest manifest;
|
extern const ::AppManifest manifest;
|
||||||
|
|
||||||
constexpr auto* TAG = "KernelDisplay";
|
constexpr auto* TAG = "Display";
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -308,36 +307,12 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
while (!shouldClose) {
|
persistIfUpdated(ctx);
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -351,4 +326,4 @@ extern const ::AppManifest manifest = {
|
|||||||
.location = { APP_LOCATION_MEMORY, reinterpret_cast<void*>(appMain) }
|
.location = { APP_LOCATION_MEMORY, reinterpret_cast<void*>(appMain) }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tt::app::kerneldisplay
|
} // namespace tt::app::display
|
||||||
@ -62,32 +62,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
app_event_emit(appInstanceId, &closeEvent);
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return ctx.result;
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -388,36 +388,12 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx;
|
Context ctx;
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
while (!shouldClose) {
|
stopScanningIfRunning(&ctx);
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,35 +89,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
ctx.appInstanceId = appInstanceId;
|
ctx.appInstanceId = appInstanceId;
|
||||||
ctx.filePath = argv[0];
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,32 +111,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
ctx.argc = argc;
|
ctx.argc = argc;
|
||||||
ctx.argv = argv;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return ctx.result;
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,36 +209,12 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
while (!shouldClose) {
|
persistIfUpdated(ctx);
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -234,34 +234,13 @@ void runAutoStart() {
|
|||||||
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
||||||
runAutoStart();
|
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);
|
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
|
// 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).
|
// thread when app-module's scheduler asks it to (e.g. another new-model app is started).
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -145,35 +145,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx;
|
Context ctx;
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -240,37 +240,13 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
updateUi(&ctx);
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
ctx.timer->start();
|
ctx.timer->start();
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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();
|
ctx.timer->stop();
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,35 +136,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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()) {
|
if (ctx.updateTimer->isRunning()) {
|
||||||
ctx.updateTimer->stop();
|
ctx.updateTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,32 +104,11 @@ int32_t appMain(AppInstanceId appInstanceId, int argc, char* argv[]) {
|
|||||||
ctx.argc = argc;
|
ctx.argc = argc;
|
||||||
ctx.argv = argv;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return ctx.result;
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,32 +79,11 @@ void createWidgets(lv_obj_t* parent, void*) {
|
|||||||
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
||||||
settingsInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, nullptr);
|
||||||
|
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -417,39 +417,15 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
lvgl_unlock();
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
ctx.memoryTimer->start(); // Memory: every 10s
|
ctx.memoryTimer->start(); // Memory: every 10s
|
||||||
ctx.tasksTimer->start(); // Tasks/CPU: every 15s
|
ctx.tasksTimer->start(); // Tasks/CPU: every 15s
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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.memoryTimer->stop();
|
||||||
ctx.tasksTimer->stop();
|
ctx.tasksTimer->stop();
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -240,34 +240,13 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
updateList(&ctx);
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
ctx.updateTimer->start();
|
ctx.updateTimer->start();
|
||||||
|
|
||||||
while (true) {
|
app_event_loop_run();
|
||||||
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();
|
ctx.updateTimer->stop();
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return ctx.result;
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -233,35 +233,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
lvgl_unlock();
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
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,
|
// finishCalibration() already applied a new calibration on success. On cancel/failure,
|
||||||
// restore whatever calibration was on disk before the block above cleared it.
|
// restore whatever calibration was on disk before the block above cleared it.
|
||||||
|
|||||||
@ -272,36 +272,12 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
while (!shouldClose) {
|
persistIfUpdated(ctx);
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,35 +85,11 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
Context ctx {};
|
Context ctx {};
|
||||||
ctx.appInstanceId = appInstanceId;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -362,31 +362,9 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
ctx.wsSettings.webServerEnabled = service::webserver::isWebServerEnabled();
|
ctx.wsSettings.webServerEnabled = service::webserver::isWebServerEnabled();
|
||||||
ctx.originalSettings = ctx.wsSettings;
|
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);
|
WindowId window = window_manager_create(appInstanceId, createWidgets, &ctx);
|
||||||
|
|
||||||
bool shouldClose = false;
|
app_event_loop_run();
|
||||||
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().
|
// Equivalent of the old model's onHide().
|
||||||
if (ctx.updated) {
|
if (ctx.updated) {
|
||||||
@ -427,8 +405,6 @@ int32_t appMain(uint32_t appInstanceId, int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window_manager_remove(window);
|
window_manager_remove(window);
|
||||||
app_event_unsubscribe(&sub);
|
|
||||||
task_event_group_destruct(&event_group);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,11 +72,14 @@ static void onConnectToHidden() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateView(Context* ctx) {
|
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();
|
lvgl_lock();
|
||||||
|
ctx->lock();
|
||||||
ctx->view.update();
|
ctx->view.update();
|
||||||
lvgl_unlock();
|
|
||||||
ctx->unlock();
|
ctx->unlock();
|
||||||
|
lvgl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onWifiEvent(Context* ctx, WifiEvent event) {
|
void onWifiEvent(Context* ctx, WifiEvent event) {
|
||||||
|
|||||||
@ -229,18 +229,7 @@ void dispatchConnect() {
|
|||||||
|
|
||||||
LOG_I(TAG, "Connecting to %s", target.ssid.c_str());
|
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);
|
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().
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispatchDisconnect() {
|
void dispatchDisconnect() {
|
||||||
@ -373,10 +362,6 @@ void onWifiDeviceEvent(Device* device, ::WifiEvent event) {
|
|||||||
default:
|
default:
|
||||||
break;
|
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) {
|
void autoScanSetPaused(bool paused) {
|
||||||
|
|||||||
@ -245,7 +245,8 @@ struct WifiApi {
|
|||||||
* mask, or use _wait_any() to include every subscription sharing it), then drain with
|
* mask, or use _wait_any() to include every subscription sharing it), then drain with
|
||||||
* wifi_event_poll().
|
* wifi_event_poll().
|
||||||
* @retval ERROR_NONE on success
|
* @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);
|
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
|
* into the mask, or use _wait_any() to include every subscription sharing it), then drain with
|
||||||
* wifi_event_poll().
|
* wifi_event_poll().
|
||||||
* @retval ERROR_NONE on success
|
* @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);
|
error_t wifi_event_subscribe(struct Device* device, struct WifiEventSubscription* sub, struct TaskEventGroup* event_group);
|
||||||
|
|
||||||
|
|||||||
@ -173,15 +173,11 @@ error_t system_event_subscribe(SystemEventSubscription* sub, TaskEventGroup* eve
|
|||||||
|
|
||||||
mutex_lock(&poll_subscriptions_mutex.handle);
|
mutex_lock(&poll_subscriptions_mutex.handle);
|
||||||
|
|
||||||
// Check-and-insert in one critical section: registering the same `sub` twice would link
|
// Avoid cyclic subscription list that would loop forever
|
||||||
// it into a list that already contains it, creating a cycle that notify_poll_subscribers()
|
if (poll_subscriptions == sub) {
|
||||||
// would then traverse forever while holding this same mutex.
|
mutex_unlock(&poll_subscriptions_mutex.handle);
|
||||||
for (SystemEventSubscription* existing = poll_subscriptions; existing != nullptr; existing = existing->internal.next) {
|
task_event_group_release_bit(event_group, bit);
|
||||||
if (existing == sub) {
|
return ERROR_INVALID_STATE;
|
||||||
mutex_unlock(&poll_subscriptions_mutex.handle);
|
|
||||||
task_event_group_release_bit(event_group, bit);
|
|
||||||
return ERROR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub->internal.event_group = event_group;
|
sub->internal.event_group = event_group;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user