~aleteoryx/muditaos

684ecb7a786f128036b88fc7c2e4484ee7c044bb — Lukasz Mastalerz 2 years ago 13217cc
[BH-1767] Fix the pre-revert issue inside ServiceGUI

Introducing states to ServiceGUI instead of using bool variables as
flagss.
M module-services/service-gui/CMakeLists.txt => module-services/service-gui/CMakeLists.txt +2 -0
@@ 6,12 6,14 @@ target_sources(service-gui
        DrawCommandsQueue.cpp
        RenderCache.cpp
        ServiceGUI.cpp
        ServiceGUIStateManager.cpp
        SynchronizationMechanism.cpp
        WorkerGUI.cpp
        messages/DrawMessage.cpp
    INTERFACE
        service-gui/ServiceGUIName.hpp
        service-gui/ServiceGUI.hpp
        service-gui/ServiceGUIStateManager.hpp
        service-gui/messages/ChangeColorScheme.hpp
        service-gui/messages/DrawMessage.hpp
        service-gui/messages/GUIMessage.hpp

M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +11 -9
@@ 87,6 87,7 @@ namespace service::gui
        worker = std::make_unique<WorkerGUI>(this);
        worker->init(queueInfo);
        worker->run();
        stateManager.setState(ServiceGUIState::Running);
        return sys::ReturnCodes::Success;
    }



@@ 98,12 99,13 @@ namespace service::gui

    void ServiceGUI::ProcessCloseReason(sys::CloseReason closeReason)
    {
        if (not isDisplaying and not isRendering) {
        if (stateManager.isInState(RenderingState::Idle) and stateManager.isInState(DisplayingState::Idle)) {
            sendCloseReadyMessage(this);
            stateManager.setState(ServiceGUIState::Closed);
            return;
        }
        else {
            isClosing = true;
            stateManager.setState(ServiceGUIState::Closing);
        }
    }



@@ 145,7 147,7 @@ namespace service::gui
    void ServiceGUI::notifyRenderer(std::list<std::unique_ptr<::gui::DrawCommand>> &&commands,
                                    ::gui::RefreshModes refreshMode)
    {
        isRendering = true;
        stateManager.setState(RenderingState::Rendering);
        enqueueDrawCommands(DrawCommandsQueue::QueueItem{std::move(commands), refreshMode});
        worker->notify(WorkerGUI::Signal::Render);
    }


@@ 172,12 174,12 @@ namespace service::gui

    sys::MessagePointer ServiceGUI::handleGUIRenderingFinished(sys::Message *message)
    {
        isRendering          = false;
        stateManager.setState(RenderingState::Idle);
        auto finishedMsg     = static_cast<service::gui::RenderingFinished *>(message);
        const auto contextId = finishedMsg->getContextId();
        auto refreshMode     = finishedMsg->getRefreshMode();

        if (not isDisplaying) {
        if (stateManager.isInState(DisplayingState::Idle)) {
            if (cache.isRenderCached()) {
                refreshMode = getMaxRefreshMode(cache.getCachedRender()->refreshMode, refreshMode);
                cache.invalidate();


@@ 201,8 203,7 @@ namespace service::gui

    void ServiceGUI::sendOnDisplay(::gui::Context *context, int contextId, ::gui::RefreshModes refreshMode)
    {
        isDisplaying = true;

        stateManager.setState(DisplayingState::Displaying);
        auto msg = std::make_shared<service::eink::ImageMessage>(contextId, context, refreshMode);
        bus.sendUnicast(std::move(msg), service::name::eink);
        scheduleContextRelease(contextId);


@@ 229,7 230,7 @@ namespace service::gui

    sys::MessagePointer ServiceGUI::handleImageDisplayedNotification(sys::Message *message)
    {
        isDisplaying         = false;
        stateManager.setState(DisplayingState::Idle);
        const auto msg       = static_cast<eink::ImageDisplayedNotification *>(message);
        const auto contextId = msg->getContextId();
        contextPool->returnContext(contextId);


@@ 240,8 241,9 @@ namespace service::gui
        if (isNextFrameReady() and not isAnyFrameBeingRenderedOrDisplayed()) {
            trySendNextFrame();
        }
        else if (isClosing) {
        else if (stateManager.isInState(ServiceGUIState::Closing)) {
            sendCloseReadyMessage(this);
            stateManager.setState(ServiceGUIState::Closed);
        }
        return sys::MessageNone{};
    }

A module-services/service-gui/ServiceGUIStateManager.cpp => module-services/service-gui/ServiceGUIStateManager.cpp +36 -0
@@ 0,0 1,36 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ServiceGUIStateManager.hpp"

namespace service::gui
{
    bool ServiceGUIStateManager::isInState(DisplayingState state)
    {
        return displayingState == state;
    }
    bool ServiceGUIStateManager::isInState(RenderingState state)
    {
        return renderingState == state;
    }
    bool ServiceGUIStateManager::isInState(ServiceGUIState state)
    {
        return serviceState == state;
    }

    void ServiceGUIStateManager::setState(DisplayingState state)
    {
        displayingState = state;
    }
    void ServiceGUIStateManager::setState(RenderingState state)
    {
        renderingState = state;
    }
    void ServiceGUIStateManager::setState(ServiceGUIState state)
    {
        if (serviceState == ServiceGUIState::Closed) {
            return;
        }
        serviceState = state;
    }
} // namespace service::gui

M module-services/service-gui/service-gui/ServiceGUI.hpp => module-services/service-gui/service-gui/ServiceGUI.hpp +3 -5
@@ 8,7 8,7 @@
#include "RenderCache.hpp"
#include "messages/RenderingFinished.hpp"
#include "ServiceGUIDependencies.hpp"

#include "ServiceGUIStateManager.hpp"
#include <system/Common.hpp>
#include <Service/Message.hpp>
#include <Service/Service.hpp>


@@ 22,6 22,7 @@ namespace gui
{
    class Context;
    class DrawCommand;

} // namespace gui

namespace service::gui


@@ 46,10 47,6 @@ namespace service::gui
        sys::ReturnCodes SwitchPowerModeHandler(const sys::ServicePowerMode mode) override;

      private:
        bool isRendering{};
        bool isDisplaying{};
        bool isClosing{};

        static void initAssetManagers();
        void registerMessageHandlers();



@@ 76,6 73,7 @@ namespace service::gui
        std::unique_ptr<::gui::ColorScheme> colorSchemeUpdate;
        RenderCache cache;
        sys::TimerHandle contextReleaseTimer;
        ServiceGUIStateManager stateManager{};
    };
} // namespace service::gui


A module-services/service-gui/service-gui/ServiceGUIStateManager.hpp => module-services/service-gui/service-gui/ServiceGUIStateManager.hpp +45 -0
@@ 0,0 1,45 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once
namespace service::gui
{
    enum class RenderingState
    {
        Idle,
        Rendering
    };

    enum class DisplayingState
    {
        Idle,
        Displaying
    };

    enum class ServiceGUIState
    {
        Initializing,
        Running,
        Closing,
        Closed
    };

    class ServiceGUIStateManager
    {
      public:
        ServiceGUIStateManager()  = default;
        ~ServiceGUIStateManager() = default;
        bool isInState(DisplayingState state);
        bool isInState(RenderingState state);
        bool isInState(ServiceGUIState state);

        void setState(DisplayingState state);
        void setState(RenderingState state);
        void setState(ServiceGUIState state);

      private:
        DisplayingState displayingState{DisplayingState::Idle};
        RenderingState renderingState{RenderingState::Idle};
        ServiceGUIState serviceState{ServiceGUIState::Initializing};
    };
} // namespace service::gui