我最近启动了一个项目:实现一个应用于嵌入式的声明式UI框架: https://gitee.com/ufbycd/zdec
用Zig语言编写,底层基于LVGL进行绘图。我用过emWin、AWTK、QT(widget/qml/pyqt)、 wxWidgets,但我之前对LVGL只是耳闻并在PC上跑了下Demo,实际项目从来没用过。
在实现命令绑定时发现LVGL的事件处理函数的添加和删除的API好丑呀。
lv_obj_add_event_cb的返回值在V8版本已经标记为遗弃。而在V9版本则没有返回值了,API调用到底是成功还是失败,用户不知道!太不严谨了。
并且不能通过lv_obj_add_event_cb返回的东西来删除处理函数了。这对于实现一个声明式UI框架很不友好!
AWTK相应的API是这样的:
uint32_t widget_on(widget_t* widget, uint32_t type, event_func_t on_event, void* ctx);
ret_t widget_off(widget_t* widget, uint32_t id);
用法是这样的:
// 添加
uint32_t event_id = widget_on(widget, EVT_CLICK, callback, ctx);
if(event_id == TK_INVALID_ID) {
// 失败处理
}
// 删除
widget_off(widget, event_id);
LVGL的版本号都这么大了,大家都没有意见吗?我打算到github上提下意见。
另外,将来空闲时也会写点这个Zig项目的心得。
最近编辑记录 海石生风 (2024-01-17 15:13:23)
离线
lvgl的意思是lv_obj_add_event_cb就是列表里加个函数指针 根本不会 fail 不过列表如果静态的会不会占好大地方 如果动态满了怎么办
lv_obj_add_event_cb内部会有动态内存分配,只有一个fail原因,那就是内存分配失败。
后面看了不少C代码,lvgl对于内存分配失败都是只用LV_ASSERT_MALLOC触发断言而没有在返回值上体现来处理的,跟我之前所用的UI库处理习惯上有点不同。
而zig这边因为有完善的错误处理机制,一个函数返回OOM(Out Of Memory)错误是很常见的。zig提倡由调用者决定什么时候处理错误,这就可以让软件更健壮,不会一触发OOM就因ASSERT断言而死掉。
最近编辑记录 海石生风 (2024-01-27 19:03:58)
离线
机理肯定是不一样的 不过 你也可以把断言改成弹出个消息框或者标记全局错误状态 不用一条一条检查函数返回值 嵌入式的内存不够了 程序和用户能做的事情不多 也就是获得错误消息转给开发人员处理
消息框弹出来了,然后呢,你原本的流程怎么办?标记了全局错误状态也要每层都去判断是否出错呀,不然你的流程怎么办,出错了也照常走?
zig的错误处理不需要像go那样每返回一个错误就检查一次,zig在调用函数时加try关键字就可以在出错时直接返回错误,而没有出错时就照常走。
在可靠性要求高的场合,即使出现OOM错误也不能让程序直接死掉的。
最近编辑记录 海石生风 (2024-01-29 22:29:26)
离线