touchgfx的工作机制

touchgfx的工作机制

一.MVP软件架构

MVP的全称为Model-View-Presenter

Model: 就是数据部分,在整个touchgfx应用中,只有一个Model类实例对象,它为所有的Screen屏幕界面服务,可以理解成是一个全局变量区,同时它还负责和后端系统通信

View: 就是UI界面部分,对应于View类,在整个touchgfx应用中,可以存在多个View实例对象,一个View实例对象其实就是一个Screen屏幕界面

Presenter: 就是项目的业务逻辑部分,相当于是一个主持人,负责在Model和View之间进行数据中转

注: 每一个Screen屏幕界面,都会有一个专有的View类和专有的Presenter类与之对应,但是Model类是所有屏幕界面共有的

二.View类

1.构造函数: 主要是做一些成员变量的初始化

2.setupScreen : 主要是做一些UI控件的属性初始化

3.tearDownScreen: 做一些资源释放

4.虚构函数: 做一些资源释放

上面四个函数也可以说是一个Screen屏幕界面的生命周期,由从上到下的顺序被系统调用,而且都只会被调用一次

三.Model类

1.构造函数: 主要是做一些成员变量的初始化

2.Tick函数: 每隔一个tick周期就会被调用一次,而一个tick周期其实就是一个屏幕刷新周期,取决于你的LCD像素时钟,一般在20ms左右,在这里主要负责轮询后端系统的事件

四.Presenter类

1.构造函数

2.activate

3.deactivate

五.内存管理机制

这里的内存指的是微处理器内部的ram

touchgfx中的控件对象的内存分配全部都是在内部ram中的,而且都是分配在几个私有的大数组中

cpp 复制代码
Block stBlocks[NUMBER_OF_ELEMENTS];

因此touchgfx的内存分配是在程序编译时就完成了的,而不是在程序运行时动态分配的,

因此内存消耗的大小是确定可控的,不会出现运行时的内存泄露问题

内存管理的细节由FontendHeap单例类(在TouchGFX\gui\include\gui\common目录下)来描述,总内存消耗由以下几部分构成:

touchgfx::Partition< CombinedPresenterTypes, 1 > presenters;

touchgfx::Partition< CombinedViewTypes, 1 > views;

touchgfx::Partition< CombinedTransitionTypes, 1 > transitions;//屏幕切换动画

Model model;

FrontendApplication app;

举例:

1.presenters所分配的内存空间大小等于界面中内存消耗最大的那一个Presenter,而不是所有的Presenter内存消耗的总和,然后所有的Presenter共享同一个presenters内存区域,即分时复用

2.views所分配的内存空间大小等于界面中内存消耗最大的那一个View,而不是所有的View内存消耗的总和,然后所有的View共享同一个views内存区域,即分时复用

(五)启动流程

(1)void touchgfx_init()

cpp 复制代码
void touchgfx_init()
{
    //挂载图片数据库
    Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
    //挂载文本服务类
    TypedText::registerTexts(&texts);
    //设置语言
    Texts::setLanguage(0);
    //设置字体提供器
    FontManager::setFontProvider(&fontProvider);
    //创建内存管理
    FrontendHeap& heap = FrontendHeap::getInstance();
    /*
     * we need to obtain the reference above to initialize the frontend heap.
     */
    //避免警告
    (void)heap;

    /*
     * Initialize TouchGFX
     */
    hal.initialize();
}

(2)

cpp 复制代码
static FrontendHeap& getInstance()
{
    static FrontendHeap instance;
    return instance;
}

(3)跳转到启动界面

cpp 复制代码
FrontendHeap() : FrontendHeapBase(presenters, views, transitions, app),
                     app(model, *this)
    {
        gotoStartScreen(app);
    }

(4)

cpp 复制代码
virtual void gotoStartScreen(FrontendApplication& app)
{
    app.gotostartScreenScreenNoTransition();
}

(5)设置回调函数,此时是没有进行界面跳转的

cpp 复制代码
void FrontendApplicationBase::gotostartScreenScreenNoTransition()
{
    transitionCallback = touchgfx::Callback<FrontendApplicationBase>(this, &FrontendApplicationBase::gotostartScreenScreenNoTransitionImpl);
    pendingScreenTransitionCallback = &transitionCallback;
}

(6)这个地方才是真正的界面跳转

cpp 复制代码
void FrontendApplicationBase::gotostartScreenScreenNoTransitionImpl()
{
    touchgfx::makeTransition<startScreenView, startScreenPresenter, touchgfx::NoTransition, Model >(&currentScreen, &currentPresenter, frontendHeap, &currentTransition, &model);
}

(7)预跳转

cpp 复制代码
template <class ScreenType, class PresenterType, class TransType, class ModelType>
PresenterType* makeTransition(Screen** currentScreen, Presenter** currentPresenter, MVPHeap& heap, Transition** currentTrans, ModelType* model)
{
    assert(sizeof(ScreenType) <= heap.screenStorage.element_size() && "View allocation error: Check that all views are added to FrontendHeap::ViewTypes");
    assert(sizeof(PresenterType) <= heap.presenterStorage.element_size() && "Presenter allocation error: Check that all presenters are added to FrontendHeap::PresenterTypes");
    assert(sizeof(TransType) <= heap.transitionStorage.element_size() && "Transition allocation error: Check that all transitions are added to FrontendHeap::TransitionTypes");
//跳转之前的操作,主要把当前界面的资源进行释放(View类,Presenter类,Transition类)
    prepareTransition(currentScreen, currentPresenter, currentTrans);
//placement 在一个地址上分配内存,不会重新分配内存空间
    TransType* newTransition = new (&heap.transitionStorage.at<TransType>(0)) TransType;
    ScreenType* newScreen = new (&heap.screenStorage.at<ScreenType>(0)) ScreenType;
    PresenterType* newPresenter = new (&heap.presenterStorage.at<PresenterType>(0)) PresenterType(*newScreen);
   //绑定
    *currentTrans = newTransition;
    *currentPresenter = newPresenter;
    *currentScreen = newScreen;
    model->bind(newPresenter);
    newPresenter->bind(model);
    newScreen->bind(*newPresenter);

    finalizeTransition((Screen*)newScreen, (Presenter*)newPresenter, (Transition*)newTransition);

    return newPresenter;
}

(8)跳转

cpp 复制代码
FORCE_INLINE_FUNCTION static void finalizeTransition(Screen* newScreen, Presenter* newPresenter, Transition* newTransition)
{
    newScreen->setupScreen();
    newPresenter->activate();
    newScreen->bindTransition(*newTransition);
    newTransition->init();
    newTransition->invalidate();
}
相关推荐
蒋楼丶3 小时前
stm32和Zynq的中断抢占机制
stm32·单片机·嵌入式硬件
xyx-3v4 小时前
已知三极管的类型(NPN/PNP)和基极引脚,如何区分集电极(c)和发射极(e)
单片机·嵌入式硬件·学习
随机惯性粒子群5 小时前
STM32控制开发学习笔记【基于STM32 HAL库】
笔记·stm32·嵌入式硬件·学习
会编程的果子君7 小时前
面向对象实现LED灯
单片机·嵌入式硬件
阿华学长单片机设计9 小时前
【开源】基于STM32的新疆地区棉花智能种植系统
stm32·嵌入式硬件·开源
无垠的广袤10 小时前
【LattePanda Mu 开发套件】AI 图像识别网页服务器
服务器·人工智能·python·单片机·嵌入式硬件·物联网
充哥单片机设计13 小时前
【STM32项目开源】基于STM32的智能养殖场环境监测系统
stm32·单片机·嵌入式硬件
New农民工14 小时前
STM32ADC模式和DMA设置
stm32·单片机·嵌入式硬件
清风66666615 小时前
基于51单片机的空气质量检测PM2.5粉尘检测设计
数据库·单片机·嵌入式硬件·毕业设计·51单片机·课程设计
何处归途.15 小时前
stm32内部flash
stm32·单片机·嵌入式硬件