C

Telltales: Rendering Safety-Critical UI

// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial

// This file is part of the Qt Safe Renderer module
/*
Purpose of this example is to enable development of Qt Safe Renderer
in desktop environment (Windows and Linux).

Note that this example is NOT implemented according Misra C++ 2008 nor ISO26262
functional safety standards and it depends on Qt classes.

You should not use this example in production environment.
*/
#include <QtSafeRenderer/qsafelayout.h>
#include <QtSafeRenderer/qsafelayoutresourcereader.h>
#include <QtSafeRenderer/statemanager.h>
#include <QtSafeRenderer/qsafechecksum.h>
#include "safewindow.h"
#include "eventhandler.h"

using namespace SafeRenderer;
//Global pointer to access the EventHandler from the filterFunction.
EventHandler *g_msgHandler = NULL;

static bool handleHeartbeatEvent(const QSafeEvent &event)
{
    bool eventHandled = false;
    //Handle EventHeartbeatTimeout event
    if ((g_msgHandler != NULL) &&
        (EventHeartbeatTimeout == event.getEventId())) {
        eventHandled = true;
        QSafeEventHeartbeatTimeout timeout(event);
        bool showNotif = timeout.getValue();
        //Show or hide the error notification.
        QSafeEventVisibility notification;
        notification.setItemId(qsafe_hash_string("safeText"));
        notification.setValue(showNotif);
        g_msgHandler->processEvent(notification);
    }
    return eventHandled;
}

static void hideIcons(StateManager &stateManager, QSafeLayout &layout)
{
    for (quint32 i=0; i<layout.count(); i++) {
        if (layout.item(i).id() == qsafe_hash_string("speedText") ) {
            continue;
        } else if (layout.item(i).id() == qsafe_hash_string("turnleft") ||
                   layout.item(i).id() == qsafe_hash_string("turnright") ) {
            QSafeEventChangeState changeState;
            changeState.setItemId(layout.item(i).id());
            changeState.setStateId(qsafe_hash_string("hidden"));
            stateManager.handleEvent(changeState);
        } else {
            QSafeEventVisibility hideItem;
            hideItem.setItemId(layout.item(i).id());
            hideItem.setValue(0U);
            stateManager.handleEvent(hideItem);
        }
    }
}

int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;

    static QSafeLayoutResourceReader hybrid("/layoutData/DashboardForm/DashboardForm.ui.srl");
    static QSafeLayoutResourceReader sport("/layoutData/DashboardSportForm/DashboardSportForm.ui.srl");

    hybrid.setLayoutId(qsafe_hash_string("hybrid"));
    sport.setLayoutId(qsafe_hash_string("sport"));

    SafeWindow telltaleWindow(hybrid.size(), QSafePoint(0U, 0U));
    static SafeRenderer::StateManager stateManager(telltaleWindow, hybrid);
    stateManager.addLayout(&sport);
    hideIcons(stateManager, hybrid);
    telltaleWindow.requestUpdate();
    static EventHandler msgHandler(stateManager, telltaleWindow);
    g_msgHandler = &msgHandler;
    msgHandler.installEventFilter(&handleHeartbeatEvent);
    msgHandler.handleEvents();
    return 0;
}