Callbacks and Lifetime

Most PixelUI callbacks use ETL inline storage:

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>;

This avoids std::function and ordinary heap allocation for individual callbacks, but it does not solve the lifetime of captured objects.

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_);
}

This capture is valid only while the Widget callback cannot outlive its App. See App lifecycle and ViewManager for the unified cleanup order before destruction.

Common mistake

1
2
3
4
5
6
void configure() {
int temporary = 42;
button_.setCallback([&temporary]() {
use(temporary); // dangling after configure() returns
});
}

Likewise, do not pass a local character array to a Widget or Popup and then return, queue a reference to a local numeric value, or retain a pointer from getCurrentApp() across a pop.

Inline capacity

A large lambda may fail to fit in etl::inplace_function at compile time. Instead of globally increasing the capacity, it is usually better to capture only this, a pointer, or a small ID. See Resource limits for the configured size.

Member declaration order

C++ destroys members in reverse declaration order. If a Widget holds a non-owning reference to a buffer or state object, declare that object before the Widget. See Widgets and Focus for a Chart example.

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