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};
|
module fifo{Type};
|
||||||
|
|
||||||
import std::core::mem;
|
import std::core::mem;
|
||||||
|
import std::sort;
|
||||||
faultdef FULL, EMPTY;
|
|
||||||
|
|
||||||
// TODO: specify the allocator
|
// TODO: specify the allocator
|
||||||
|
|
||||||
@ -27,7 +29,7 @@ fn void Fifo.free(&fifo)
|
|||||||
fn void? Fifo.enqueue(&fifo, Type *elem)
|
fn void? Fifo.enqueue(&fifo, Type *elem)
|
||||||
{
|
{
|
||||||
if (fifo.count >= fifo.arr.len) {
|
if (fifo.count >= fifo.arr.len) {
|
||||||
return FULL?;
|
return fifo::faults::FULL?;
|
||||||
}
|
}
|
||||||
usz in = (fifo.out + fifo.count) % fifo.arr.len;
|
usz in = (fifo.out + fifo.count) % fifo.arr.len;
|
||||||
fifo.arr[in] = *elem;
|
fifo.arr[in] = *elem;
|
||||||
@ -37,7 +39,7 @@ fn void? Fifo.enqueue(&fifo, Type *elem)
|
|||||||
fn Type*? Fifo.dequeue(&fifo)
|
fn Type*? Fifo.dequeue(&fifo)
|
||||||
{
|
{
|
||||||
if (fifo.count == 0) {
|
if (fifo.count == 0) {
|
||||||
return EMPTY?;
|
return fifo::faults::EMPTY?;
|
||||||
}
|
}
|
||||||
Type *ret = &fifo.arr[fifo.out];
|
Type *ret = &fifo.arr[fifo.out];
|
||||||
fifo.count--;
|
fifo.count--;
|
||||||
@ -64,3 +66,26 @@ macro usz Fifo.len(&fifo) @operator(len)
|
|||||||
{
|
{
|
||||||
return fifo.count;
|
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
|
// implement the Printable interface
|
||||||
fn usz? Cmd.to_format(Cmd* cmd, Formatter *f) @dynamic
|
fn usz? Cmd.to_format(Cmd* cmd, Formatter *f) @dynamic
|
||||||
{
|
{
|
||||||
|
@ -293,7 +293,7 @@ $if DEBUG == 1:
|
|||||||
// draw mouse position
|
// draw mouse position
|
||||||
Cmd cmd = {
|
Cmd cmd = {
|
||||||
.type = CMD_RECT,
|
.type = CMD_RECT,
|
||||||
.z_index = int.max, // hopefully over everything else
|
.z_index = int.max-1, // hopefully over everything else
|
||||||
.rect.rect = {
|
.rect.rect = {
|
||||||
.x = ctx.input.mouse.pos.x - 2,
|
.x = ctx.input.mouse.pos.x - 2,
|
||||||
.y = ctx.input.mouse.pos.y - 2,
|
.y = ctx.input.mouse.pos.y - 2,
|
||||||
@ -304,11 +304,16 @@ $if DEBUG == 1:
|
|||||||
};
|
};
|
||||||
ctx.cmd_queue.enqueue(&cmd)!;
|
ctx.cmd_queue.enqueue(&cmd)!;
|
||||||
|
|
||||||
// dump the command buffer
|
// dump the command buffer
|
||||||
io::printn("Command Buffer Dump:");
|
// io::printn("Command Buffer Dump:");
|
||||||
foreach(idx, c: ctx.cmd_queue) {
|
// foreach(idx, c: ctx.cmd_queue) {
|
||||||
io::printfn("\t [%d] = {%s}", idx, c);
|
// 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
|
$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_x.enabled = scroll_x;
|
||||||
elem.div.scroll_y.enabled = scroll_y;
|
elem.div.scroll_y.enabled = scroll_y;
|
||||||
elem.div.z_index = parent.div.z_index + 1;
|
elem.div.z_index = parent.div.z_index + 1;
|
||||||
io::printn(elem.div.z_index);
|
|
||||||
|
|
||||||
// 2. layout the element
|
// 2. layout the element
|
||||||
Rect wanted_size = {
|
Rect wanted_size = {
|
||||||
|
@ -112,8 +112,8 @@ fn void Ctx.input_mouse_button(&ctx, MouseButtons buttons)
|
|||||||
// Mouse was moved, report absolute position
|
// Mouse was moved, report absolute position
|
||||||
fn void Ctx.input_mouse_abs(&ctx, short x, short y)
|
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.x = math::clamp(x, (short)0, ctx.width);
|
||||||
ctx.input.mouse.pos.y = math::clamp(y, 0u16, ctx.height);
|
ctx.input.mouse.pos.y = math::clamp(y, (short)0, ctx.height);
|
||||||
|
|
||||||
short dx, dy;
|
short dx, dy;
|
||||||
dx = x - ctx.input.mouse.pos.x;
|
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;
|
mx = ctx.input.mouse.pos.x + dx;
|
||||||
my = ctx.input.mouse.pos.y + dy;
|
my = ctx.input.mouse.pos.y + dy;
|
||||||
|
|
||||||
ctx.input.mouse.pos.x = math::clamp(mx, 0u16, ctx.width);
|
ctx.input.mouse.pos.x = math::clamp(mx, (short)0, ctx.width);
|
||||||
ctx.input.mouse.pos.y = math::clamp(my, 0u16, ctx.height);
|
ctx.input.mouse.pos.y = math::clamp(my, (short)0, ctx.height);
|
||||||
|
|
||||||
ctx.input.events.mouse_move = dx != 0 || dy != 0;
|
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};
|
module vtree{ElemType};
|
||||||
|
|
||||||
import std::core::mem;
|
import std::core::mem;
|
||||||
@ -9,7 +12,6 @@ struct VTree {
|
|||||||
isz[] refs, ordered_refs;
|
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_valid(&tree, isz ref) { return (ref >= 0 && ref < tree.refs.len); }
|
||||||
macro VTree.ref_is_present(&tree, isz ref) { return tree.refs[ref] >= 0; }
|
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
|
// return error when shrinking with too many elements
|
||||||
if (newsize < tree.elements) {
|
if (newsize < tree.elements) {
|
||||||
return CANNOT_SHRINK?;
|
return vtree::faults::CANNOT_SHRINK?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pack the vector when shrinking to avoid data loss
|
// pack the vector when shrinking to avoid data loss
|
||||||
if ((int)newsize < tree.size()) {
|
if ((int)newsize < tree.size()) {
|
||||||
// FIXME: packing destroys all references to elements of vec
|
// FIXME: packing destroys all references to elements of vec
|
||||||
// so shrinking may cause dangling pointers
|
// so shrinking may cause dangling pointers
|
||||||
return CANNOT_SHRINK?;
|
return vtree::faults::CANNOT_SHRINK?;
|
||||||
}
|
}
|
||||||
|
|
||||||
usz old_size = tree.size();
|
usz old_size = tree.size();
|
||||||
@ -120,18 +122,18 @@ fn isz? VTree.add(&tree, ElemType elem, isz parent)
|
|||||||
{
|
{
|
||||||
// invalid parent
|
// invalid parent
|
||||||
if (!tree.ref_is_valid(parent)) {
|
if (!tree.ref_is_valid(parent)) {
|
||||||
return INVALID_REFERENCE?;
|
return vtree::faults::INVALID_REFERENCE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no space left
|
// no space left
|
||||||
if (tree.elements >= tree.size()) {
|
if (tree.elements >= tree.size()) {
|
||||||
return TREE_FULL?;
|
return vtree::faults::TREE_FULL?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the parent exists
|
// check if the parent exists
|
||||||
// if there are no elements in the tree the first add will set the root
|
// if there are no elements in the tree the first add will set the root
|
||||||
if (!tree.ref_is_present(parent) && tree.elements != 0) {
|
if (!tree.ref_is_present(parent) && tree.elements != 0) {
|
||||||
return REFERENCE_NOT_PRESENT?;
|
return vtree::faults::REFERENCE_NOT_PRESENT?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the first free spot
|
// get the first free spot
|
||||||
@ -143,7 +145,7 @@ fn isz? VTree.add(&tree, ElemType elem, isz parent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (free_spot < 0) {
|
if (free_spot < 0) {
|
||||||
return TREE_FULL?;
|
return vtree::faults::TREE_FULL?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally add the element
|
// finally add the element
|
||||||
@ -159,7 +161,7 @@ fn isz? VTree.add(&tree, ElemType elem, isz parent)
|
|||||||
fn usz? VTree.prune(&tree, isz ref)
|
fn usz? VTree.prune(&tree, isz ref)
|
||||||
{
|
{
|
||||||
if (!tree.ref_is_valid(ref)) {
|
if (!tree.ref_is_valid(ref)) {
|
||||||
return INVALID_REFERENCE?;
|
return vtree::faults::INVALID_REFERENCE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tree.ref_is_present(ref)) {
|
if (!tree.ref_is_present(ref)) {
|
||||||
@ -193,7 +195,7 @@ fn usz VTree.nuke(&tree)
|
|||||||
fn usz? VTree.subtree_size(&tree, isz ref)
|
fn usz? VTree.subtree_size(&tree, isz ref)
|
||||||
{
|
{
|
||||||
if (!tree.ref_is_valid(ref)) {
|
if (!tree.ref_is_valid(ref)) {
|
||||||
return INVALID_REFERENCE?;
|
return vtree::faults::INVALID_REFERENCE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tree.ref_is_present(ref)) {
|
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)
|
fn isz? VTree.children_it(&tree, isz parent, isz *cursor)
|
||||||
{
|
{
|
||||||
if (cursor == null) {
|
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 the cursor is out of bounds then we are done for sure
|
||||||
if (!tree.ref_is_valid(*cursor)) {
|
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
|
// same for the parent, if it's invalid it can't have children
|
||||||
if (!tree.ref_is_valid(parent) || !tree.ref_is_present(parent)) {
|
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
|
// 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)
|
fn isz? VTree.level_order_it(&tree, isz ref, isz *cursor)
|
||||||
{
|
{
|
||||||
if (cursor == null) {
|
if (cursor == null) {
|
||||||
return INVALID_ARGUMENT?;
|
return vtree::faults::INVALID_ARGUMENT?;
|
||||||
}
|
}
|
||||||
|
|
||||||
isz[] queue = tree.ordered_refs;
|
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)
|
fn isz? VTree.parentof(&tree, isz ref)
|
||||||
{
|
{
|
||||||
if (!tree.ref_is_valid(ref)) {
|
if (!tree.ref_is_valid(ref)) {
|
||||||
return INVALID_REFERENCE?;
|
return vtree::faults::INVALID_REFERENCE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tree.ref_is_present(ref)) {
|
if (!tree.ref_is_present(ref)) {
|
||||||
return REFERENCE_NOT_PRESENT?;
|
return vtree::faults::REFERENCE_NOT_PRESENT?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree.refs[ref];
|
return tree.refs[ref];
|
||||||
@ -313,11 +315,11 @@ fn isz? VTree.parentof(&tree, isz ref)
|
|||||||
fn ElemType? VTree.get(&tree, isz ref)
|
fn ElemType? VTree.get(&tree, isz ref)
|
||||||
{
|
{
|
||||||
if (!tree.ref_is_valid(ref)) {
|
if (!tree.ref_is_valid(ref)) {
|
||||||
return INVALID_REFERENCE?;
|
return vtree::faults::INVALID_REFERENCE?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tree.ref_is_present(ref)) {
|
if (!tree.ref_is_present(ref)) {
|
||||||
return REFERENCE_NOT_PRESENT?;
|
return vtree::faults::REFERENCE_NOT_PRESENT?;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree.vector[ref];
|
return tree.vector[ref];
|
||||||
|
Loading…
Reference in New Issue
Block a user