sorting the command buffer
This commit is contained in:
parent
c9b74aebc7
commit
ac3fcae649
@ -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)!;
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user