diff --git a/lib/ugui.c3l/src/cmd.c3 b/lib/ugui.c3l/src/cmd.c3 index 7f37757..7f3f549 100644 --- a/lib/ugui.c3l/src/cmd.c3 +++ b/lib/ugui.c3l/src/cmd.c3 @@ -1,7 +1,7 @@ module ugui; -import std::ascii; import std::io; +import std::collections::list; // command type enum CmdType { @@ -49,6 +49,10 @@ struct Cmd (Printable) { } } +// command queue +alias CmdQueue = list::List{Cmd}; + + fn int Cmd.compare_to(Cmd a, Cmd b) { if (a.z_index == b.z_index) return 0; @@ -87,21 +91,21 @@ macro bool cull_rect(Rect rect, Rect clip = {0,0,short.max,short.max}) } // FIXME: this whole thing could be done at compile time, maybe -macro Ctx.push_cmd(&ctx, Cmd *cmd, int z_index) +macro Ctx.push_cmd(&ctx, Cmd cmd, int z_index) { cmd.z_index = z_index; Rect rect; switch (cmd.type) { case CMD_RECT: rect = cmd.rect.rect; case CMD_SPRITE: rect = cmd.sprite.rect; - default: return ctx.cmd_queue.enqueue(cmd); + default: return ctx.cmd_queue.push(cmd); } if (cull_rect(rect, ctx.div_scissor)) { // println("NOPE: ", cmd.rect.rect, cmd.z_index); // unreachable(); return; } - return ctx.cmd_queue.enqueue(cmd); + return ctx.cmd_queue.push(cmd); } fn void? Ctx.push_scissor(&ctx, Rect rect, int z_index) @@ -110,10 +114,10 @@ fn void? Ctx.push_scissor(&ctx, Rect rect, int z_index) .type = CMD_SCISSOR, .scissor.rect = rect.intersection(ctx.div_scissor), }; - ctx.push_cmd(&sc, z_index)!; + ctx.push_cmd(sc, z_index); } -fn void? Ctx.reset_scissor(&ctx, int z_index) => ctx.push_cmd(&&(Cmd){.type=CMD_SCISSOR,.scissor.rect=ctx.div_scissor}, z_index)!; +fn void? Ctx.reset_scissor(&ctx, int z_index) => ctx.push_cmd({.type=CMD_SCISSOR,.scissor.rect=ctx.div_scissor}, z_index); fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style) { @@ -130,7 +134,7 @@ fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style) .rect.color = border_color, .rect.radius = radius + border.x, }; - ctx.push_cmd(&cmd, z_index)!; + ctx.push_cmd(cmd, z_index); } Cmd cmd = { @@ -144,7 +148,7 @@ fn void? Ctx.push_rect(&ctx, Rect rect, int z_index, Style* style) .rect.color = bg, .rect.radius = radius, }; - ctx.push_cmd(&cmd, z_index)!; + ctx.push_cmd(cmd, z_index); } // TODO: accept a Sprite* instead of all this shit @@ -158,7 +162,7 @@ fn void? Ctx.push_sprite(&ctx, Rect bounds, Rect texture, Id texture_id, int z_i .sprite.texture_id = texture_id, .sprite.hue = hue, }; - ctx.push_cmd(&cmd, z_index)!; + ctx.push_cmd(cmd, z_index); } fn void? Ctx.push_update_atlas(&ctx, Atlas* atlas) @@ -174,7 +178,7 @@ fn void? Ctx.push_update_atlas(&ctx, Atlas* atlas) }, }; // update the atlases before everything else - ctx.push_cmd(&up, -1)!; + ctx.push_cmd(up, -1); } macro Ctx.dbg_rect(&ctx, Rect r, uint c = 0xff000042u) => ctx.push_rect(r, int.max, &&(Style){.bg=c.to_rgba()})!!; diff --git a/lib/ugui.c3l/src/core.c3 b/lib/ugui.c3l/src/core.c3 index f21af75..b6eb5ec 100644 --- a/lib/ugui.c3l/src/core.c3 +++ b/lib/ugui.c3l/src/core.c3 @@ -69,29 +69,25 @@ struct Elem { } } + +const uint MAX_ELEMENTS = 256; +const uint MAX_COMMANDS = 2048; +const uint STACK_STEP = 10; +const uint ROOT_ID = 1; +const uint TEXT_MAX = 64; + + // Tuple of Element pointers, used when it is useful to get both parent and child alias PElemTuple = pair::Pair{Elem*, Elem*}; - // relationships between elements are stored in a tree, it stores just the ids alias IdTree = mtree::MTree{Id}; // elements themselves are kept in a cache -const uint MAX_ELEMENTS = 256; alias ElemCache = cache::Cache{Id, Elem, MAX_ELEMENTS}; -alias CmdQueue = fifo::Fifo{Cmd}; - faultdef INVALID_SIZE, EVENT_UNSUPPORTED, WRONG_ELEMENT_TYPE, WRONG_ID; -const Rect DIV_FILL = { .x = 0, .y = 0, .w = 0, .h = 0 }; - -const uint STACK_STEP = 10; -const uint MAX_ELEMS = 128; -const uint MAX_CMDS = 2048; -const uint ROOT_ID = 1; -const uint TEXT_MAX = 64; - struct Ctx { IdTree tree; ElemCache cache; @@ -216,7 +212,7 @@ fn void? Ctx.init(&ctx, Allocator allocator) ctx.cache.init(allocator)!; defer catch { (void)ctx.cache.free(); } - ctx.cmd_queue.init(MAX_CMDS, allocator)!; + ctx.cmd_queue.init(allocator::mem, MAX_COMMANDS); defer catch { (void)ctx.cmd_queue.free(); } ctx.styles.init(allocator); @@ -311,13 +307,13 @@ $if $feature(DEBUG_POINTER): }, .rect.color = 0xff00ffffu.to_rgba() }; - ctx.cmd_queue.enqueue(&cmd)!; + 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 - ctx.cmd_queue.sort()!; + //ctx.cmd_queue.sort()!; // foreach (i, c: ctx.cmd_queue) { // io::printf("[%d]: ", i); diff --git a/lib/ugui.c3l/src/fifo.c3 b/lib/ugui.c3l/src/fifo.c3 deleted file mode 100644 index c7dff8f..0000000 --- a/lib/ugui.c3l/src/fifo.c3 +++ /dev/null @@ -1,93 +0,0 @@ -module fifo::faults; -faultdef FULL, EMPTY; - -module fifo{Type}; - -import std::core::mem; -import std::sort; - -// TODO: specify the allocator - -struct Fifo { - Allocator allocator; - Type[] arr; - usz out; - usz count; -} - -fn void? Fifo.init(&fifo, usz size, Allocator allocator) -{ - fifo.allocator = allocator; - fifo.arr = allocator::new_array(fifo.allocator, Type, size); - fifo.out = 0; - fifo.count = 0; -} - -fn void Fifo.free(&fifo) -{ - (void)allocator::free(fifo.allocator, fifo.arr); -} - -fn void? Fifo.enqueue(&fifo, Type *elem) -{ - if (fifo.count >= fifo.arr.len) { - return fifo::faults::FULL?; - } - usz in = (fifo.out + fifo.count) % fifo.arr.len; - fifo.arr[in] = *elem; - fifo.count++; -} - -fn Type*? Fifo.dequeue(&fifo) -{ - if (fifo.count == 0) { - return fifo::faults::EMPTY?; - } - Type *ret = &fifo.arr[fifo.out]; - fifo.count--; - fifo.out = (fifo.out + 1) % fifo.arr.len; - return ret; -} - -macro Type Fifo.get(&fifo, usz i) @operator([]) -{ - return fifo.arr[(fifo.out + i) % fifo.arr.len]; -} - -fn void Fifo.set(&fifo, usz i, Type val) @operator([]=) -{ - fifo.arr[(fifo.out + i) % fifo.arr.len] = val; -} - -macro Type* Fifo.get_ref(&fifo, usz i) @operator(&[]) -{ - return &fifo.arr[(fifo.out + i) % fifo.arr.len]; -} - -macro usz Fifo.len(&fifo) @operator(len) -{ - return fifo.count; -} - -fn void? Fifo.sort(&fifo) -{ - Type[] arr = allocator::new_array(fifo.allocator, Type, fifo.count); - defer allocator::free(fifo.allocator, arr); - - foreach(i, c: fifo) { - arr[i] = c; - } - - // doesn't keep ordering - //sort::quicksort(arr); - - // seems to keep the right order but we will never know... - // also since most things are already ordered the time is closer to O(n) than to O(n^2) - sort::insertionsort(arr); - - fifo.count = 0; - fifo.out = 0; - foreach (&c: arr) { - fifo.enqueue(c)!; - } -} \ No newline at end of file diff --git a/src/renderer.c3 b/src/renderer.c3 index 189517c..6110220 100644 --- a/src/renderer.c3 +++ b/src/renderer.c3 @@ -990,7 +990,12 @@ fn void Renderer.render_ugui(&self, CmdQueue* queue) uint calls = 0; uint off; - for (Cmd* cmd; (cmd = queue.dequeue() ?? null) != null;) { + while (true) { + Cmd? cmd = queue.pop_first(); + if (catch e = cmd) { + if (e != NO_MORE_ELEMENT) unreachable(); + break; + } switch (cmd.type) { case CMD_UPDATE_ATLAS: // TODO: verify the correct type @@ -1011,7 +1016,7 @@ fn void Renderer.render_ugui(&self, CmdQueue* queue) uint count = 1; while (queue.len() != 0 && (queue.get(0).type == CMD_RECT || queue.get(0).type == CMD_SPRITE)) { count++; - (void)queue.dequeue(); + (void)queue.pop_first(); } self.draw_quads(off, count); off += count;