cancel
Showing results for 
Search instead for 
Did you mean: 

What is the best way to update a custom component across multiple Screens?

GBert.2
Senior

I'm building a complex application with multiple screens in TouchGFX 4.16.

All those screens have the same menu bar with indications like battery energy level, time, etc.

All screens include the MenuBar custom component.

When the battery level changes, I want the model to be able to update MenuBar.

Currently, I'm doing this to update the battery:

In Model.cpp

    bool bShouldNotify = pollBatteryState();
    if (bShouldNotify)
    {
        modelListener->notifyBatteryStateChanged(m_oDeviceState.oBattery);
    }

In SomeScreen1Presenter.cpp

void SomeScreenPresenter::notifyBatteryStateChanged(oBatteryState_t const oBatteryState)
{
    view.updateBatteryState(oBatteryState);
}

In SomeScreen1View.cpp

void SomeScreenView::updateBatteryState(oBatteryState_t const oBatteryState)
{
    // Update widgets
    MenuBar.updateBattery(oBatteryState);
}

If you need to do this for all screens, this will create a lot of code.

Is there a better way to update views that all use the same component?

An event-based system maybe?

Regards,

GB

7 REPLIES 7
GBert.2
Senior

Maybe we could define a general function to pass event

 In model.cpp

modelListener->notify(MY_EVENT);

In view.cpp

void MonitoringView::update(Event const event)
{
    switch (event)
    {
    case MY_EVENT: 
        data = pollTheNeededData();
        menuBar.update(data)
        break;
    }
}

But now the pollTheDataFromModel() function needs to be implemented for all presenters...

I'm not sure if it's worth it or if it respects the View-Model-Presenter architecture.

MM..1
Chief II

Maybe you can create self updated component and register to tick handler

Application::getInstance()->registerTimerWidget(this);

And create

void Component::handleTickEvent()
{
if (externalstruct.update)
    {
            // showed
            externalstruct.update = false;
            xxxx.show(externalstruct.baterylevel);
    }
}

That's an interesting idea.

In your example, how would your component access the`externalstruct` in the mode?

To my knowledge, inside a component, we don't have access to the Presenter Object.

void Container::handleTickEvent()
{
    externalstruct = presenter->getExternalStruct(); //< [!] not possibe
    if (externalstruct.update)
    {
        // showed
        externalstruct.update = false;
    }
}

 Also, where do you register your tick? In the constructor?

external struct is normal C variable included as extern C

You can share it over memory access in any thread on single core and skip MVP .

Ah ok.

I would prefer not to bypass the MVP model, if possible.

Thanks for your suggestion, though.

I then dont understand your question. MVP have on every view too one presenter and only model is based as main for touchgfx process.

But real thread main is in

#include <gui/common/FrontendApplication.hpp>
 
FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
    : FrontendApplicationBase(m, heap)
{
 
}

then maybe you can manage common code here ... But skip MVP is ok too

Thanks for your answer.

In my opinion, respecting the MVP model is key to making TouchGFX codebases readable.

Basically, I would like TouchGFX to provide a way to have shared container objects, accessible from the model (or the FrontendApplication).

But I agree with you, currently, I think creating a handleTickEvent function that directly talks to my firmware seems like the best way to do it.