Free memory from unused GUI elements, and make colorpicker not glitch on first appearance

This commit is contained in:
Yousef Khadadeh 2025-10-14 12:51:24 +03:00
parent 1ec7c717b2
commit 9ceb4e1b8a
4 changed files with 15 additions and 3 deletions

View file

@ -13,7 +13,7 @@ void CheckBox::update(UpdateInputData& io, bool newIsTicked, const std::function
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
if(isTicked != newIsTicked) {
hoverAnimation2 = CHECKBOX_ANIMATION_TIME;
hoverAnimation2 = selection.hovered ? CHECKBOX_ANIMATION_TIME : 0.0f;
isTicked = newIsTicked;
}
if(elemUpdate)

View file

@ -22,8 +22,9 @@ template <typename T> class ColorPicker : public Element {
CLAY({
.layout = {
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(bb.width()) }
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) }
},
.aspectRatio = 1.0f,
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);

View file

@ -36,6 +36,9 @@ Clay_Dimensions GUIManager::clay_skia_measure_text(Clay_StringSlice str, Clay_Te
}
void GUIManager::begin() {
for(auto& [id, e] : elements)
e.isUsedThisFrame = false;
io->mouse.pos = io->mouse.globalPos - windowPos;
io->strArena = &strArena;
Clay_SetLayoutDimensions(Clay_Dimensions(windowSize.x(), windowSize.y()));
@ -52,6 +55,9 @@ void GUIManager::end() {
renderCommands = Clay_EndLayout();
if(!idStack.empty())
throw std::runtime_error("[GUIManager::end] ID Stack is not empty on end (push_id and pop_id calls not equal)");
std::erase_if(elements, [](auto& p) {
return !p.second.isUsedThisFrame;
});
}
void GUIManager::draw(SkCanvas* canvas) {

View file

@ -23,6 +23,7 @@ class GUIManager {
struct ElementContainer {
std::unique_ptr<Element> elem;
std::any extra;
bool isUsedThisFrame;
};
GUIManager();
@ -90,15 +91,19 @@ class GUIManager {
template <typename NewElement> NewElement* insert_element() {
auto [it, inserted] = elements.emplace(idStack, ElementContainer());
auto& container = it->second;
if(inserted)
it->second = {std::make_unique<NewElement>()};
container = {std::make_unique<NewElement>()};
container.isUsedThisFrame = true;
return static_cast<NewElement*>(it->second.elem.get());
}
template <typename T> T& insert_any(const T& def) {
auto [it, inserted] = elements.emplace(idStack, ElementContainer());
auto& container = it->second;
if(inserted)
it->second.extra = def;
container.isUsedThisFrame = true;
return std::any_cast<T&>(it->second.extra);
}