From 884105a4e2f7d163646f67466226fdcd8f4ba58b Mon Sep 17 00:00:00 2001 From: Alessandro Mauri Date: Tue, 7 Oct 2025 17:47:24 +0200 Subject: [PATCH] faster sort of command queue --- lib/ugui.c3l/src/cmd.c3 | 29 +++++++++++++++++++++++++++++ lib/ugui.c3l/src/core.c3 | 13 +++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/lib/ugui.c3l/src/cmd.c3 b/lib/ugui.c3l/src/cmd.c3 index 7f3f549..6e47715 100644 --- a/lib/ugui.c3l/src/cmd.c3 +++ b/lib/ugui.c3l/src/cmd.c3 @@ -59,6 +59,35 @@ fn int Cmd.compare_to(Cmd a, Cmd b) return a.z_index > b.z_index ? 1 : -1; } + +// FIXME: This sorting method does not fully respect layer ordering for popups. +// Popups that start on the same layer but are enqueued at different times +// may still be rendered on top of each other, even if the first popup +// has elements in higher layers than the second. The current approach +// does not truly sort by layer; it only moves elements from higher layers +// to the end of the queue as they are encountered. +fn void? CmdQueue.sort(&queue) +{ + CmdQueue stack; + stack.init(allocator::tmem); + + for (isz i = queue.len()-1; i > 0; i--) { + Cmd cur = (*queue)[i]; + Cmd next = (*queue)[i - 1]; + // cur < next + if (cur.compare_to(next) < 0) { + stack.push(next); + queue.remove_at(i-1); + } + } + + usz l = stack.len(); + for (usz i; i < l; i++) { + queue.push(stack.pop())!; + } + +} + // implement the Printable interface fn usz? Cmd.to_format(Cmd* cmd, Formatter *f) @dynamic { diff --git a/lib/ugui.c3l/src/core.c3 b/lib/ugui.c3l/src/core.c3 index ef89ea0..0771a70 100644 --- a/lib/ugui.c3l/src/core.c3 +++ b/lib/ugui.c3l/src/core.c3 @@ -294,7 +294,13 @@ fn void? Ctx.frame_end(&ctx) ctx.sprite_atlas.should_update = false; } -// debug + // sort the command buffer by the z-index + // FIXME: sorting the buffer fucks with scissor commands that have to be kept in place + // TODO: instead of sorting at the end perform ordered inserts into the command buffer + //sort::countingsort(ctx.cmd_queue, fn uint(Cmd c) => c.z_index+1); + ctx.cmd_queue.sort()!; + + // debug $if $feature(DEBUG_POINTER): // draw mouse position Cmd cmd = { @@ -311,11 +317,6 @@ $if $feature(DEBUG_POINTER): ctx.cmd_queue.push(cmd); $endif - // sort the command buffer by the z-index - // FIXME: sorting the buffer fucks with scissor commands that have to be kept in place - // TODO: instead of sorting at the end perform ordered inserts into the command buffer - sort::countingsort(ctx.cmd_queue, fn uint(Cmd c) => c.z_index+1); - // foreach (i, c: ctx.cmd_queue) { // io::printf("[%d]: ", i); // io::printn(c);