文章目录

  • X-TRACK阅读笔记
    • 整体架构
    • PageManager
    • 问题
    • 页面的分析
      • StatusBar
      • Startup页面
      • Dilaplate页面
        • 页面的布局
        • 动画的设置
      • LiveMap页面
      • SystemInfos页面

processon框架图

X-TRACK阅读笔记

整体架构

APP-HAL-HARDWARE

USER/APP/Common/HAL下的HAL文件声明HAL的接口,具体实现在App/HAL/下或者Simulator/LVGL.Simulator/HAL/

Main函数

HAL::HAL_Init();
lv_Init();
APP_Init(); // 重点

APP_Init函数

static AppFactory factory;
static PageManager manager(&factory);
DataProc_Init();
manager.Install("LiveMap",     "Pages/LiveMap");

在此函数中,有两个重点:一是定义PageManager,并对页面进行管理;二是初始化DataCenter,实现数据的传递。

理解要点: X-TRACK将App/Common/DataProc下的每个DP_XXX,以及App/Pages/下的每个页面都视为一个Account。(这些Account会在DataProc_Init()中被定义,被DataCenter所管理)

PageManager框架

DataCenter框架

通过manager.Push("Page/StartUp")开始页面的调度

PageManager

需要关心的只有几个方法:

manager.Install("xxx")
manager.Push("xxx") // 将xxx入栈到栈顶,实则会显示xxx页面

APP/Utils/PageManager下实现了PageManager,并提供了几个public接口,包括页面注册:Install(会调用Register), Uninstall;页面调度:Push, Pop,Replace,最终都会调用SwitchTo(PageBase*, bool, PageBase::Stash_t*);

SwitchTo()中会

  1. 调用StateUpdate(_PagePrv), StateUpdate(_PageCurrent)更新页面

PageManager的其它方法不用特别关心,其内部使用了状态机进行页面的切换。我们只需根据App/Pages/下的模板Template定义我们自己的页面。模板的结构是:

自定义页面

初略的页面框架:

详细的页面框架:

实现如下onViewXXX()函数:

virtual void onViewLoad() {}  /* Page load start */
virtual void onViewDidLoad() {}  /* Page load end */virtual void onViewWillAppear() {}/* Page appear animation start */
virtual void onViewDidAppear() {}  /* Page appear animation end  */virtual void onViewWillDisappear() {}/* Page disappear animation start */
virtual void onViewDidDisappear() {} /* Page disappear animation end */virtual void onViewUnload() {}  /* Page unload start */
virtual void onViewDidUnload() {}  /* Page unload end */

问题

  1. App/Pages/Dialate/*中的Dialate.*, DialateModel.*, DialteView.*分别有什么用?特别是ModelView

View应该是创建并管理页面各个wigdet的,由View.Create(lv_ojb_t _root)可知,_root充当该页面的根节点,其它的各个lv组件都是_root的子节点,如btn、label等。

Model是用于获取数据的

  1. 搞懂页面之间的消息传递机制(或者页面的数据怎么从硬件上获取到的?)

每个页面类/对象有一个方法Update(),其会更新页面上的各个数据,它会在onTimerUpdate()中被调用,又会被onViewDidAppear()中被使用(创建一个定时器)

#mermaid-svg-p09A7QnnfJiDNGND {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-p09A7QnnfJiDNGND .error-icon{fill:#552222;}#mermaid-svg-p09A7QnnfJiDNGND .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-p09A7QnnfJiDNGND .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-p09A7QnnfJiDNGND .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-p09A7QnnfJiDNGND .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-p09A7QnnfJiDNGND .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-p09A7QnnfJiDNGND .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-p09A7QnnfJiDNGND .marker{fill:#333333;stroke:#333333;}#mermaid-svg-p09A7QnnfJiDNGND .marker.cross{stroke:#333333;}#mermaid-svg-p09A7QnnfJiDNGND svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-p09A7QnnfJiDNGND .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-p09A7QnnfJiDNGND .cluster-label text{fill:#333;}#mermaid-svg-p09A7QnnfJiDNGND .cluster-label span{color:#333;}#mermaid-svg-p09A7QnnfJiDNGND .label text,#mermaid-svg-p09A7QnnfJiDNGND span{fill:#333;color:#333;}#mermaid-svg-p09A7QnnfJiDNGND .node rect,#mermaid-svg-p09A7QnnfJiDNGND .node circle,#mermaid-svg-p09A7QnnfJiDNGND .node ellipse,#mermaid-svg-p09A7QnnfJiDNGND .node polygon,#mermaid-svg-p09A7QnnfJiDNGND .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-p09A7QnnfJiDNGND .node .label{text-align:center;}#mermaid-svg-p09A7QnnfJiDNGND .node.clickable{cursor:pointer;}#mermaid-svg-p09A7QnnfJiDNGND .arrowheadPath{fill:#333333;}#mermaid-svg-p09A7QnnfJiDNGND .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-p09A7QnnfJiDNGND .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-p09A7QnnfJiDNGND .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-p09A7QnnfJiDNGND .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-p09A7QnnfJiDNGND .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-p09A7QnnfJiDNGND .cluster text{fill:#333;}#mermaid-svg-p09A7QnnfJiDNGND .cluster span{color:#333;}#mermaid-svg-p09A7QnnfJiDNGND div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-p09A7QnnfJiDNGND :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

three
two
one
lv_timer_del()
onViewWillDisappear()
删除定时器
Update()
最终被调用
更新页面数据
onTimerUpdate()
被周期性调用
onViewDidAppear()
创建定时器
StateUpdate()
利用状态机调用onViewXXX函数
SwitchTo()
manager.Push()
manager.Install()
加载并注册页面
  1. DataProc.cppDataProc_Init()函数内的宏

订阅-发布机制的核心:每个人都有一个账户,有一个代理。每个账户要设置一个事件回调函数onEvent(),供Pull(), Notify()调用,但会传入不同的事件类型,比如Account::EVENT_SUB_PULLAccount::EVENT_NOTIFY

数据分发机制有点没懂:相关代码:DataProc.cpp, DataCenter.*, Account.*

#mermaid-svg-J2dhP1ifP9ZoTjBw {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .error-icon{fill:#552222;}#mermaid-svg-J2dhP1ifP9ZoTjBw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-J2dhP1ifP9ZoTjBw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .marker.cross{stroke:#333333;}#mermaid-svg-J2dhP1ifP9ZoTjBw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster-label text{fill:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster-label span{color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .label text,#mermaid-svg-J2dhP1ifP9ZoTjBw span{fill:#333;color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .node rect,#mermaid-svg-J2dhP1ifP9ZoTjBw .node circle,#mermaid-svg-J2dhP1ifP9ZoTjBw .node ellipse,#mermaid-svg-J2dhP1ifP9ZoTjBw .node polygon,#mermaid-svg-J2dhP1ifP9ZoTjBw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .node .label{text-align:center;}#mermaid-svg-J2dhP1ifP9ZoTjBw .node.clickable{cursor:pointer;}#mermaid-svg-J2dhP1ifP9ZoTjBw .arrowheadPath{fill:#333333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster text{fill:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster span{color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-J2dhP1ifP9ZoTjBw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

成员变量
注册许多accounts到center
center
AccountMain
DataProc_Init()
accounts
AddAccount()
RemoveAccount()
SearchAccount()
Subscirbe()
Commit()
Publish()
Pull()
Notify()
Center
UserData
publishers
subscribers

Account对象的Pull(pub,data,size),Notify(pub,data,size)函数都会调用pub->priv.eventCallback(pub,para)

而在App/Common/DataProc/下的每个DP_XXX.cpp都包含一个account对象,其会在DATA_PROC_INIT_DEF(Clock)中调用account->SetEventCallback(onEvent)设置事件回调函数。而在回调函数中,就可以通过判断传入的参数,返回订阅者需要的数据(通过调用HAL层提供的接口)。

此外,DialplateModel::Init()中也会创建account,并像上面一样,设置回调函数。

页面的分析

以Diplate页面为例

StatusBar

在任何页面都显示,不会被遮挡,因为位于lv_layer_top()

Startup页面

Dilaplate页面

void DialplateView::Create(lv_obj_t* root)设计页面的布局,及动画设置

页面的布局

BottomInfo_Create(root);
TopInfo_Create(root);
BtnCont_Create(root);

动画的设置

核心:成员lv_anim_timeline_t* anim_timeline;

通过宏定义ANIM_DEF定义多个动画:lv_anim_timeline_wrapper_t类型

调用

LiveMap页面

SystemInfos页面

【开源项目】X-TRACK源码分析相关推荐

  1. IEC61499开源项目FORTE部分源码分析

    一.IEC 61499简介 IEC 61499 作为工业自动化领域分布式控制系统级建模语言的标准,其第一(体系结构).二(软件工具要求).四(兼容文件的规则)部分的第一版于 2005 年正式发布,并在 ...

  2. 基于STC51:四轴飞控开源项目原理图与源码(入门级DIY)

    目录 前言(作者:宏晶科技) 一.飞控配件 二.接线 三.原理图 四.调试 五.程序 六.完整工程.原理图文件获取 前言(作者:宏晶科技) 本飞控仅仅是姿态飞行控制,没有GPS.电子罗盘.气压高度计. ...

  3. 开源僵尸网络平台LiteHttp源码分析

    一. 简介 如今,黑客越来越多的通过修改开源的病毒源码来实现快速的病毒开发,如Mirai.qbot等公开了源码的病毒,常被黑客用于二次开发,用以攻击.前不久,一起针对巴基斯坦的APT攻击中,发现黑客所 ...

  4. DDPush开源推送框架源码分析之APPServer到DDPush

    DDPush 任意门推送 DDPush是什么 DDPush (Dimension Door Push),任意门推送,是一款开源免费的单机千万级实时信息推送服务器,使用Java语言开发,具有简单.稳定. ...

  5. 企业级低代码平台,接私活必备的Java开源项目(附源码)

    项目介绍 Jeecg-Boot 是一款基于代码生成器的智能开发平台!采用前后端分离架构:SpringBoot,Mybatis,Shiro,JWT,Vue&Ant Design.强大的代码生成器 ...

  6. 谷歌开源项目Chromium的源码获取与项目构建(Win7+vs10/vs13)

    从12年那会儿开始获取源码和构建chromium项目都是按照那时候的官方要求用win7+vs2010,相对来说也比较简单,按照步骤来也很快能编译出来. 1.官网的编译配置介绍:http://www.c ...

  7. 【开源项目学习】源码剖析,学习仿网易云音乐app代码

    [前言] 这篇文字不全是讲app代码,而是博主怎么根据代码系统学习梳理的过程,非专业,如有不对,欢迎指出 仿网易云音乐app源码地址:https://github.com/aa112901/remus ...

  8. android移动日记代码,Android开源项目-小熊日记源码

    前言 一直是接着别人的代码来做App的,所以没有完整的开发App体验,总感觉有所缺少.于是,就利用业余时间亲自操刀开始了我的第一次开源项目.本文将讲述开源项目的整个开发过程. 项目初衷 开始这个项目的 ...

  9. NeteaseCloudMusicApi 开源 网易云nodeapi 源码分析

    这篇文章,分享下网易云开源的一个api,通过伪造请求来获取网易云的歌曲,评论和电台等信息. 首先,大致描述项目里用到的一些知识点 涉及到的知识点 apicache 缓存中间件,可以用于redis,项目 ...

最新文章

  1. 关于python语言、下列说法不正确的是-关于 Python字符串,下列说法错误的是_学小易找答案...
  2. Android Linux自带iptables配置IP访问规则
  3. python隐藏windows磁盘
  4. 内部类(闭包与回调)
  5. Android Studio 多渠道打包、自动版本号及 gradlew 命令的基本使用
  6. [蓝桥杯][2013年第四届真题]带分数
  7. P4062 [Code+#1]Yazid 的新生舞会 树状数组维护三阶差分
  8. day15 Ui自动化元素的定位
  9. Android自定义Lint实践
  10. Java中文件的创建
  11. Matlab滤波器的verilog实现,FIR滤波器的Verilog实现
  12. ES6-改变对象的原型对象
  13. oracle服务端导出/导入方式expdp/impdp
  14. springmvc并发调用controller方法时对局部变量的影响
  15. UCF101数据集处理
  16. 快嘴企业名录搜索 2007 是什么
  17. PDF文件怎样修改,怎么修改PDF文件内容
  18. android降低屏幕分辨率,让游戏更尽兴 手动调低Android手机屏幕分辨率
  19. oracle character set mismatch,EntityFramework查询oracle数据库时报ora-12704: character set mismatch...
  20. 直播的用户体验体系与质量监控方案

热门文章

  1. 杰理之AC695_3.0.4_SDK做发射器连接接收器无声问题解决方法【篇】
  2. Spring Cloud Finchley OpenFeign的重试配置相关的坑
  3. ElementUI的el-tree实现懒加载查询和直接全部查询出来
  4. 自学本科计算机课程要多久,22岁完全0基础自考计算机本科是否现实?
  5. Python爬虫之——爬取妹子图片
  6. C#用于生成meileg网站的图片下载地址
  7. C语言中对结构体赋初值
  8. 基于均值调整的自适应局部伽玛校正 Cython
  9. HDU2080 夹角有多大II
  10. 编写“木马生成器”软件总结