diff --git a/lib/ugui.c3l/src/fifo.c3 b/lib/ugui.c3l/src/fifo.c3 index 59802e5..d9fc52e 100644 --- a/lib/ugui.c3l/src/fifo.c3 +++ b/lib/ugui.c3l/src/fifo.c3 @@ -1,8 +1,10 @@ +module fifo::faults; +faultdef FULL, EMPTY; + module fifo{Type}; import std::core::mem; - -faultdef FULL, EMPTY; +import std::sort; // TODO: specify the allocator @@ -27,7 +29,7 @@ fn void Fifo.free(&fifo) fn void? Fifo.enqueue(&fifo, Type *elem) { if (fifo.count >= fifo.arr.len) { - return FULL?; + return fifo::faults::FULL?; } usz in = (fifo.out + fifo.count) % fifo.arr.len; fifo.arr[in] = *elem; @@ -37,7 +39,7 @@ fn void? Fifo.enqueue(&fifo, Type *elem) fn Type*? Fifo.dequeue(&fifo) { if (fifo.count == 0) { - return EMPTY?; + return fifo::faults::EMPTY?; } Type *ret = &fifo.arr[fifo.out]; fifo.count--; @@ -63,4 +65,27 @@ macro Type* Fifo.get_ref(&fifo, usz i) @operator(&[]) macro usz Fifo.len(&fifo) @operator(len) { return fifo.count; +} + +fn void? Fifo.sort(&fifo) +{ + Type[] arr = mem::new_array(Type, fifo.count); + defer mem::free(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/lib/ugui.c3l/src/ugui_cmd.c3 b/lib/ugui.c3l/src/ugui_cmd.c3 index 51120bb..77468cb 100644 --- a/lib/ugui.c3l/src/ugui_cmd.c3 +++ b/lib/ugui.c3l/src/ugui_cmd.c3 @@ -49,6 +49,12 @@ struct Cmd (Printable) { } } +fn int Cmd.compare_to(Cmd a, Cmd b) +{ + if (a.z_index == b.z_index) return 0; + return a.z_index > b.z_index ? 1 : -1; +} + // implement the Printable interface fn usz? Cmd.to_format(Cmd* cmd, Formatter *f) @dynamic { diff --git a/lib/ugui.c3l/src/ugui_core.c3 b/lib/ugui.c3l/src/ugui_core.c3 index 8078218..a1c7e2b 100644 --- a/lib/ugui.c3l/src/ugui_core.c3 +++ b/lib/ugui.c3l/src/ugui_core.c3 @@ -293,7 +293,7 @@ $if DEBUG == 1: // draw mouse position Cmd cmd = { .type = CMD_RECT, - .z_index = int.max, // hopefully over everything else + .z_index = int.max-1, // hopefully over everything else .rect.rect = { .x = ctx.input.mouse.pos.x - 2, .y = ctx.input.mouse.pos.y - 2, @@ -304,11 +304,16 @@ $if DEBUG == 1: }; ctx.cmd_queue.enqueue(&cmd)!; - // dump the command buffer - io::printn("Command Buffer Dump:"); - foreach(idx, c: ctx.cmd_queue) { - io::printfn("\t [%d] = {%s}", idx, c); - } +// dump the command buffer +// io::printn("Command Buffer Dump:"); +// foreach(idx, c: ctx.cmd_queue) { +// io::printfn("\t [%d] = {%s}", idx, c); +// } + ctx.cmd_queue.sort()!; +// io::printn("Sorted Command Buffer Dump:"); +// foreach(idx, c: ctx.cmd_queue) { +// io::printfn("\t [%d] = {%s}", idx, c); +// } $endif } diff --git a/lib/ugui.c3l/src/ugui_div.c3 b/lib/ugui.c3l/src/ugui_div.c3 index d4dcae6..4bfd45e 100644 --- a/lib/ugui.c3l/src/ugui_div.c3 +++ b/lib/ugui.c3l/src/ugui_div.c3 @@ -48,7 +48,6 @@ fn void? Ctx.div_begin(&ctx, String label, Rect size, bool scroll_x = false, boo elem.div.scroll_x.enabled = scroll_x; elem.div.scroll_y.enabled = scroll_y; elem.div.z_index = parent.div.z_index + 1; - io::printn(elem.div.z_index); // 2. layout the element Rect wanted_size = { diff --git a/lib/ugui.c3l/src/ugui_input.c3 b/lib/ugui.c3l/src/ugui_input.c3 index abad51c..5dcb12b 100644 --- a/lib/ugui.c3l/src/ugui_input.c3 +++ b/lib/ugui.c3l/src/ugui_input.c3 @@ -112,8 +112,8 @@ fn void Ctx.input_mouse_button(&ctx, MouseButtons buttons) // Mouse was moved, report absolute position fn void Ctx.input_mouse_abs(&ctx, short x, short y) { - ctx.input.mouse.pos.x = math::clamp(x, 0u16, ctx.width); - ctx.input.mouse.pos.y = math::clamp(y, 0u16, ctx.height); + ctx.input.mouse.pos.x = math::clamp(x, (short)0, ctx.width); + ctx.input.mouse.pos.y = math::clamp(y, (short)0, ctx.height); short dx, dy; dx = x - ctx.input.mouse.pos.x; @@ -135,8 +135,8 @@ fn void Ctx.input_mouse_delta(&ctx, short dx, short dy) mx = ctx.input.mouse.pos.x + dx; my = ctx.input.mouse.pos.y + dy; - ctx.input.mouse.pos.x = math::clamp(mx, 0u16, ctx.width); - ctx.input.mouse.pos.y = math::clamp(my, 0u16, ctx.height); + ctx.input.mouse.pos.x = math::clamp(mx, (short)0, ctx.width); + ctx.input.mouse.pos.y = math::clamp(my, (short)0, ctx.height); ctx.input.events.mouse_move = dx != 0 || dy != 0; } diff --git a/lib/ugui.c3l/src/vtree.c3 b/lib/ugui.c3l/src/vtree.c3 index 0a1e851..d18b749 100644 --- a/lib/ugui.c3l/src/vtree.c3 +++ b/lib/ugui.c3l/src/vtree.c3 @@ -1,3 +1,6 @@ +module vtree::faults; +faultdef CANNOT_SHRINK, INVALID_REFERENCE, TREE_FULL, REFERENCE_NOT_PRESENT, INVALID_ARGUMENT; + module vtree{ElemType}; import std::core::mem; @@ -9,7 +12,6 @@ struct VTree { isz[] refs, ordered_refs; } -faultdef CANNOT_SHRINK, INVALID_REFERENCE, TREE_FULL, REFERENCE_NOT_PRESENT, INVALID_ARGUMENT; macro VTree.ref_is_valid(&tree, isz ref) { return (ref >= 0 && ref < tree.refs.len); } macro VTree.ref_is_present(&tree, isz ref) { return tree.refs[ref] >= 0; } @@ -88,14 +90,14 @@ fn void? VTree.resize(&tree, usz newsize) { // return error when shrinking with too many elements if (newsize < tree.elements) { - return CANNOT_SHRINK?; + return vtree::faults::CANNOT_SHRINK?; } // pack the vector when shrinking to avoid data loss if ((int)newsize < tree.size()) { // FIXME: packing destroys all references to elements of vec // so shrinking may cause dangling pointers - return CANNOT_SHRINK?; + return vtree::faults::CANNOT_SHRINK?; } usz old_size = tree.size(); @@ -120,18 +122,18 @@ fn isz? VTree.add(&tree, ElemType elem, isz parent) { // invalid parent if (!tree.ref_is_valid(parent)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } // no space left if (tree.elements >= tree.size()) { - return TREE_FULL?; + return vtree::faults::TREE_FULL?; } // check if the parent exists // if there are no elements in the tree the first add will set the root if (!tree.ref_is_present(parent) && tree.elements != 0) { - return REFERENCE_NOT_PRESENT?; + return vtree::faults::REFERENCE_NOT_PRESENT?; } // get the first free spot @@ -143,7 +145,7 @@ fn isz? VTree.add(&tree, ElemType elem, isz parent) } } if (free_spot < 0) { - return TREE_FULL?; + return vtree::faults::TREE_FULL?; } // finally add the element @@ -159,7 +161,7 @@ fn isz? VTree.add(&tree, ElemType elem, isz parent) fn usz? VTree.prune(&tree, isz ref) { if (!tree.ref_is_valid(ref)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } if (!tree.ref_is_present(ref)) { @@ -193,7 +195,7 @@ fn usz VTree.nuke(&tree) fn usz? VTree.subtree_size(&tree, isz ref) { if (!tree.ref_is_valid(ref)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } if (!tree.ref_is_present(ref)) { @@ -215,17 +217,17 @@ fn usz? VTree.subtree_size(&tree, isz ref) fn isz? VTree.children_it(&tree, isz parent, isz *cursor) { if (cursor == null) { - return INVALID_ARGUMENT?; + return vtree::faults::INVALID_ARGUMENT?; } // if the cursor is out of bounds then we are done for sure if (!tree.ref_is_valid(*cursor)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } // same for the parent, if it's invalid it can't have children if (!tree.ref_is_valid(parent) || !tree.ref_is_present(parent)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } // find the first child, update the cursor and return the ref @@ -253,7 +255,7 @@ fn isz? VTree.children_it(&tree, isz parent, isz *cursor) fn isz? VTree.level_order_it(&tree, isz ref, isz *cursor) { if (cursor == null) { - return INVALID_ARGUMENT?; + return vtree::faults::INVALID_ARGUMENT?; } isz[] queue = tree.ordered_refs; @@ -300,11 +302,11 @@ fn isz? VTree.level_order_it(&tree, isz ref, isz *cursor) fn isz? VTree.parentof(&tree, isz ref) { if (!tree.ref_is_valid(ref)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } if (!tree.ref_is_present(ref)) { - return REFERENCE_NOT_PRESENT?; + return vtree::faults::REFERENCE_NOT_PRESENT?; } return tree.refs[ref]; @@ -313,11 +315,11 @@ fn isz? VTree.parentof(&tree, isz ref) fn ElemType? VTree.get(&tree, isz ref) { if (!tree.ref_is_valid(ref)) { - return INVALID_REFERENCE?; + return vtree::faults::INVALID_REFERENCE?; } if (!tree.ref_is_present(ref)) { - return REFERENCE_NOT_PRESENT?; + return vtree::faults::REFERENCE_NOT_PRESENT?; } return tree.vector[ref];