use the specified allocator for the element caches
This commit is contained in:
parent
4a690fdeb5
commit
5e5c912092
2
TODO
2
TODO
@ -5,7 +5,7 @@
|
||||
[x] Port font system from C to C3 (rewrite1)
|
||||
[ ] Update ARCHITECTURE.md
|
||||
[ ] Write a README.md
|
||||
[ ] Use an arena allocator for cache
|
||||
[x] Use an arena allocator for cache
|
||||
[ ] Do not redraw if there was no update (no layout and no draw)
|
||||
[ ] Do command buffer damage tracking based on a context grid (see rxi writeup)
|
||||
[x] Better handling of the active and focused widgets, try
|
||||
|
@ -25,6 +25,7 @@ alias IdTableEntry = map::Entry{Key, usz};
|
||||
const usz CACHE_NCYCLES = (usz)(SIZE * 2.0/3.0);
|
||||
|
||||
struct Cache {
|
||||
Allocator allocator;
|
||||
BitArr present, used;
|
||||
IdTable table;
|
||||
Value[] pool;
|
||||
@ -43,19 +44,20 @@ macro Cache.cycle(&cache) @private {
|
||||
}
|
||||
}
|
||||
|
||||
fn void? Cache.init(&cache)
|
||||
fn void? Cache.init(&cache, Allocator allocator)
|
||||
{
|
||||
cache.table.init(allocator::heap(), capacity: SIZE);
|
||||
cache.allocator = allocator;
|
||||
cache.table.init(allocator, capacity: SIZE);
|
||||
// FIXME: this shit is SLOW
|
||||
foreach (idx, bit : cache.used) { cache.used[idx] = false; }
|
||||
foreach (idx, bit : cache.present) { cache.present[idx] = false; }
|
||||
cache.pool = mem::new_array(Value, SIZE);
|
||||
cache.pool = allocator::new_array(allocator, Value, SIZE);
|
||||
}
|
||||
|
||||
fn void Cache.free(&cache)
|
||||
{
|
||||
(void)cache.table.free();
|
||||
(void)mem::free(cache.pool);
|
||||
(void)allocator::free(cache.allocator, cache.pool);
|
||||
}
|
||||
|
||||
fn Value*? Cache.search(&cache, Key id)
|
||||
|
@ -9,21 +9,23 @@ import std::sort;
|
||||
// TODO: specify the allocator
|
||||
|
||||
struct Fifo {
|
||||
Allocator allocator;
|
||||
Type[] arr;
|
||||
usz out;
|
||||
usz count;
|
||||
}
|
||||
|
||||
fn void? Fifo.init(&fifo, usz size)
|
||||
fn void? Fifo.init(&fifo, usz size, Allocator allocator)
|
||||
{
|
||||
fifo.arr = mem::new_array(Type, size);
|
||||
fifo.allocator = allocator;
|
||||
fifo.arr = allocator::new_array(fifo.allocator, Type, size);
|
||||
fifo.out = 0;
|
||||
fifo.count = 0;
|
||||
}
|
||||
|
||||
fn void Fifo.free(&fifo)
|
||||
{
|
||||
(void)mem::free(fifo.arr);
|
||||
(void)allocator::free(fifo.allocator, fifo.arr);
|
||||
}
|
||||
|
||||
fn void? Fifo.enqueue(&fifo, Type *elem)
|
||||
@ -69,8 +71,8 @@ macro usz Fifo.len(&fifo) @operator(len)
|
||||
|
||||
fn void? Fifo.sort(&fifo)
|
||||
{
|
||||
Type[] arr = mem::new_array(Type, fifo.count);
|
||||
defer mem::free(arr);
|
||||
Type[] arr = allocator::new_array(fifo.allocator, Type, fifo.count);
|
||||
defer allocator::free(fifo.allocator, arr);
|
||||
|
||||
foreach(i, c: fifo) {
|
||||
arr[i] = c;
|
||||
|
@ -187,18 +187,18 @@ fn Elem*? Ctx.get_active_div(&ctx)
|
||||
return ctx.cache.search(id);
|
||||
}
|
||||
|
||||
fn void? Ctx.init(&ctx)
|
||||
fn void? Ctx.init(&ctx, Allocator allocator)
|
||||
{
|
||||
ctx.tree.init(MAX_ELEMENTS)!;
|
||||
ctx.tree.init(MAX_ELEMENTS, allocator)!;
|
||||
defer catch { (void)ctx.tree.free(); }
|
||||
|
||||
ctx.cache.init()!;
|
||||
ctx.cache.init(allocator)!;
|
||||
defer catch { (void)ctx.cache.free(); }
|
||||
|
||||
ctx.cmd_queue.init(MAX_CMDS)!;
|
||||
ctx.cmd_queue.init(MAX_CMDS, allocator)!;
|
||||
defer catch { (void)ctx.cmd_queue.free(); }
|
||||
|
||||
ctx.styles.init(allocator::heap());
|
||||
ctx.styles.init(allocator);
|
||||
ctx.styles.register_style(&DEFAULT_STYLE, @str_hash("default"));
|
||||
defer catch { ctx.styles.free(); }
|
||||
|
||||
|
@ -4,39 +4,43 @@ faultdef CANNOT_SHRINK, INVALID_REFERENCE, TREE_FULL, REFERENCE_NOT_PRESENT, INV
|
||||
module vtree{ElemType};
|
||||
|
||||
import std::core::mem;
|
||||
import std::core::mem::allocator;
|
||||
import std::io;
|
||||
|
||||
struct VTree {
|
||||
Allocator allocator;
|
||||
usz elements;
|
||||
ElemType[] vector; // vector of element ids
|
||||
isz[] refs, ordered_refs;
|
||||
}
|
||||
|
||||
|
||||
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.size(&tree) { return tree.refs.len; }
|
||||
macro VTree.ref_is_valid(&tree, isz ref) => (ref >= 0 && ref < tree.refs.len);
|
||||
macro VTree.ref_is_present(&tree, isz ref) => tree.refs[ref] >= 0;
|
||||
macro VTree.size(&tree) => tree.refs.len;
|
||||
|
||||
// macro to zero an elemen
|
||||
// macro to zero an element
|
||||
macro @zero()
|
||||
{
|
||||
$if $assignable(0, ElemType):
|
||||
$if @assignable_to(0, ElemType):
|
||||
return 0;
|
||||
$else
|
||||
return {};
|
||||
$endif
|
||||
}
|
||||
|
||||
fn void? VTree.init(&tree, usz size)
|
||||
fn void? VTree.init(&tree, usz size, Allocator allocator)
|
||||
{
|
||||
tree.vector = mem::new_array(ElemType, size);
|
||||
defer catch { (void)mem::free(tree.vector); }
|
||||
tree.allocator = allocator;
|
||||
|
||||
tree.refs = mem::new_array(isz, size);
|
||||
defer catch { (void)mem::free(tree.refs); }
|
||||
tree.vector = allocator::new_array(tree.allocator, ElemType, size);
|
||||
defer catch { (void)allocator::free(tree.allocator, tree.vector); }
|
||||
|
||||
tree.ordered_refs = mem::new_array(isz, size);
|
||||
defer catch { (void)mem::free(tree.ordered_refs); }
|
||||
tree.refs = allocator::new_array(tree.allocator, isz, size);
|
||||
defer catch { (void)allocator::free(tree.allocator, tree.refs); }
|
||||
|
||||
tree.ordered_refs = allocator::new_array(tree.allocator, isz, size);
|
||||
defer catch { (void)allocator::free(tree.allocator, tree.ordered_refs); }
|
||||
|
||||
// set all refs to -1, meaning invalid (free) element
|
||||
tree.refs[..] = -1;
|
||||
@ -46,9 +50,9 @@ fn void? VTree.init(&tree, usz size)
|
||||
|
||||
fn void VTree.free(&tree)
|
||||
{
|
||||
(void)mem::free(tree.vector);
|
||||
(void)mem::free(tree.refs);
|
||||
(void)mem::free(tree.ordered_refs);
|
||||
(void)allocator::free(tree.allocator, tree.vector);
|
||||
(void)allocator::free(tree.allocator, tree.refs);
|
||||
(void)allocator::free(tree.allocator, tree.ordered_refs);
|
||||
}
|
||||
|
||||
fn void VTree.pack(&tree)
|
||||
@ -102,14 +106,14 @@ fn void? VTree.resize(&tree, usz newsize)
|
||||
|
||||
usz old_size = tree.size();
|
||||
|
||||
tree.vector = ((ElemType*)mem::realloc(tree.vector, newsize*ElemType.sizeof))[:newsize];
|
||||
defer catch { (void)mem::free(tree.vector); }
|
||||
tree.vector = ((ElemType*)allocator::realloc(tree.allocator, tree.vector, newsize*ElemType.sizeof))[:newsize];
|
||||
defer catch { (void)allocator::free(tree.allocator, tree.vector); }
|
||||
|
||||
tree.refs = ((isz*)mem::realloc(tree.refs, newsize*isz.sizeof))[:newsize];
|
||||
defer catch { (void)mem::free(tree.refs); }
|
||||
tree.refs = ((isz*)allocator::realloc(tree.allocator, tree.refs, newsize*isz.sizeof))[:newsize];
|
||||
defer catch { (void)allocator::free(tree.allocator, tree.refs); }
|
||||
|
||||
tree.ordered_refs = ((isz*)mem::realloc(tree.ordered_refs, newsize*isz.sizeof))[:newsize];
|
||||
defer catch { (void)mem::free(tree.ordered_refs); }
|
||||
tree.ordered_refs = ((isz*)allocator::realloc(tree.allocator, tree.ordered_refs, newsize*isz.sizeof))[:newsize];
|
||||
defer catch { (void)allocator::free(tree.allocator, tree.ordered_refs); }
|
||||
|
||||
if (newsize > tree.size()) {
|
||||
tree.vector[old_size..newsize-1] = @zero();
|
||||
|
@ -6,6 +6,7 @@ import std::time;
|
||||
import std::collections::ringbuffer;
|
||||
import std::core::string;
|
||||
import std::ascii;
|
||||
import std::core::mem::allocator;
|
||||
import sdlrenderer::ren;
|
||||
import sdl3::sdl;
|
||||
|
||||
@ -58,8 +59,13 @@ const char[*] STYLESHEET_PATH = "resources/style.css";
|
||||
|
||||
fn int main(String[] args)
|
||||
{
|
||||
ArenaAllocator arena;
|
||||
char[] mem = mem::new_array(char, 1024*1024);
|
||||
defer (void)mem::free(mem);
|
||||
arena.init(mem);
|
||||
|
||||
ugui::Ctx ui;
|
||||
ui.init()!!;
|
||||
ui.init(&arena)!!;
|
||||
defer ui.free();
|
||||
|
||||
ren::Renderer ren;
|
||||
|
Loading…
Reference in New Issue
Block a user