Various improvements (#547)
- Fixed crash when returning to Setup app (from any of the steps) - Fixed crash when returning to TimeDateSettings app (after locale selection) - Fixed GuiService inconsistent behaviour: now always perform operations async (e.g. to show/hide apps). This fixes crashes in some onHide() calls where onHide() might be called before onShow() was called. - Fix for incorrect WebServService path - Remove CYD-4848S040C SD card functionality, but added a GPIO fix for releasing 3-wire SPI pin sharing. - Fix for saving/loading settings for various apps
This commit is contained in:
committed by
GitHub
parent
a323f8e148
commit
ecad2248d9
@@ -27,14 +27,49 @@ void warnIfRunningOnGuiTask(const char* context) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
enum class GuiDispatchType { Show, Hide, Exit };
|
||||
|
||||
struct GuiDispatchItem {
|
||||
GuiService* service;
|
||||
GuiDispatchType type;
|
||||
std::shared_ptr<app::AppInstance> appInstance; // only used for Show
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// region AppManifest
|
||||
|
||||
void GuiService::onGuiDispatch(void* context) {
|
||||
std::unique_ptr<GuiDispatchItem> item(static_cast<GuiDispatchItem*>(context));
|
||||
switch (item->type) {
|
||||
case GuiDispatchType::Show:
|
||||
item->service->showApp(item->appInstance);
|
||||
break;
|
||||
case GuiDispatchType::Hide:
|
||||
item->service->hideApp();
|
||||
break;
|
||||
case GuiDispatchType::Exit:
|
||||
item->service->exitRequested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GuiService::onLoaderEvent(LoaderService::Event event) {
|
||||
GuiDispatchItem* item;
|
||||
if (event == LoaderService::Event::ApplicationShowing) {
|
||||
auto app_instance = std::static_pointer_cast<app::AppInstance>(app::getCurrentAppContext());
|
||||
showApp(app_instance);
|
||||
item = new GuiDispatchItem{this, GuiDispatchType::Show, app_instance};
|
||||
} else if (event == LoaderService::Event::ApplicationHiding) {
|
||||
hideApp();
|
||||
item = new GuiDispatchItem{this, GuiDispatchType::Hide, nullptr};
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dispatcher_dispatch(dispatcher, item, onGuiDispatch) != ERROR_NONE) {
|
||||
LOGGER.error("Failed to dispatch gui event");
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,26 +117,8 @@ int32_t GuiService::guiMain() {
|
||||
|
||||
lvgl::unlock();
|
||||
|
||||
while (true) {
|
||||
uint32_t flags = 0;
|
||||
if (service->threadFlags.wait(GUI_THREAD_FLAG_ALL, false, true, &flags, portMAX_DELAY)) {
|
||||
// When service not started or starting -> exit
|
||||
State service_state = getState(manifest.id);
|
||||
if (service_state != State::Started && service_state != State::Starting) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Process and dispatch draw call
|
||||
if (flags & GUI_THREAD_FLAG_DRAW) {
|
||||
service->threadFlags.clear(GUI_THREAD_FLAG_DRAW);
|
||||
service->redraw();
|
||||
}
|
||||
|
||||
if (flags & GUI_THREAD_FLAG_EXIT) {
|
||||
service->threadFlags.clear(GUI_THREAD_FLAG_EXIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (!service->exitRequested) {
|
||||
dispatcher_consume(service->dispatcher);
|
||||
}
|
||||
|
||||
service->appRootWidget = nullptr;
|
||||
@@ -177,6 +194,9 @@ void GuiService::redraw() {
|
||||
}
|
||||
|
||||
bool GuiService::onStart(ServiceContext& service) {
|
||||
exitRequested = false;
|
||||
dispatcher = dispatcher_alloc();
|
||||
|
||||
thread = new Thread(
|
||||
GUI_TASK_NAME,
|
||||
4096, // Last known minimum was 2800 for launching desktop
|
||||
@@ -211,8 +231,14 @@ void GuiService::onStop(ServiceContext& service) {
|
||||
appToRender = nullptr;
|
||||
isStarted = false;
|
||||
|
||||
threadFlags.set(GUI_THREAD_FLAG_EXIT);
|
||||
unlock();
|
||||
|
||||
auto* exit_item = new GuiDispatchItem{this, GuiDispatchType::Exit, nullptr};
|
||||
if (dispatcher_dispatch(dispatcher, exit_item, onGuiDispatch) != ERROR_NONE) {
|
||||
LOGGER.error("Failed to dispatch gui exit event");
|
||||
check(false, "Failed to dispatch exit signal to thread.");
|
||||
delete exit_item;
|
||||
}
|
||||
thread->join();
|
||||
|
||||
if (lvgl::lock()) {
|
||||
@@ -226,10 +252,8 @@ void GuiService::onStop(ServiceContext& service) {
|
||||
}
|
||||
|
||||
delete thread;
|
||||
}
|
||||
|
||||
void GuiService::requestDraw() {
|
||||
threadFlags.set(GUI_THREAD_FLAG_DRAW);
|
||||
dispatcher_free(dispatcher);
|
||||
dispatcher = nullptr;
|
||||
}
|
||||
|
||||
void GuiService::showApp(std::shared_ptr<app::AppInstance> app) {
|
||||
@@ -253,7 +277,7 @@ void GuiService::showApp(std::shared_ptr<app::AppInstance> app) {
|
||||
}
|
||||
|
||||
appToRender = std::move(app);
|
||||
requestDraw();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void GuiService::hideApp() {
|
||||
|
||||
Reference in New Issue
Block a user