Callbacks and Lifetime / 回调与生命周期

PixelUI 的大部分回调用 ETL 内联存储:

1
2
3
using InputCallback = etl::inplace_function<bool(InputEvent), CALLBACK_STORAGE_SIZE>;
using VoidCallback = etl::inplace_function<void(), CALLBACK_STORAGE_SIZE>;
using ValueCallback = etl::inplace_function<void(int32_t), CALLBACK_STORAGE_SIZE>;

避免了 std::function 和单次回调的普通堆分配,但不会自动解决捕获对象的寿命。

推荐的 App 成员捕获

1
2
3
4
5
6
7
8
void onEnter(ExitCallback cb) override {
IApplication::onEnter(cb);
button_.setCallback([this]() {
value_++;
ui_.markDirty();
});
ui_.addWidgetToFocusManager(&button_);
}

这个捕获的前提是 Widget 回调不能比 App 活得更久。App 销毁前的统一清理顺序见App 生命周期与 ViewManager

常见错误

1
2
3
4
5
6
void configure() {
int temporary = 42;
button_.setCallback([&temporary]() {
use(temporary); // configure() 返回后已悬空
});
}

同样,不要把局部字符数组传给 Widget/Popup 后返回,不要把局部数值引用排入 Popup 队列,也不要让 getCurrentApp() 得到的指针跨过 pop。

内联容量

大 lambda 可能在编译时无法放入 etl::inplace_function。与其把容量全局调大,更常见的做法是只捕获 this、指针或小型 ID;具体容量见资源上限

成员声明顺序

C++ 按成员声明的反向顺序析构。如果 Widget 持有某个 buffer 或状态的非拥有引用,把被引用对象声明在 Widget 之前。Chart 的具体写法见组件与焦点光标

最新文章
网站信息
文章数目 :
1
本站访客数 :
本站总浏览量 :
最后更新时间 :