1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
use ui;
/**
* A separate allocation, i.e. a top-level object.
*/
class Allocation on Render {
// The data in this allocation.
Data data;
// Object representing this allocation, if any.
unsafe:RawPtr src;
// Was this allocation visited? This is used by World during traversals.
Bool visited;
// Is this allocation unreachable?
Bool unreachable;
// Create.
init(unsafe:RawPtr src, Data data) {
init {
data = data;
src = src;
visited = false;
}
}
// Update.
void update(World:Traversal t, Nat id) {
t.allocMap.put(src, id);
data.update(t, src, 0);
}
// Traverse this allocation. Marks it as 'visited' as well.
void traverse(World:Traversal t) {
visited = true;
data.traverse(t, src, 0);
}
// Called when this allocation is no longer reachable. If 'true', the allocation will be
// removed, otherwise it will remain.
Bool remove() {
true;
}
// Register all sub-data.
void register(Registrator r) {
r.setAllocation(this);
visit(r);
r.setAllocation(null);
}
// Visit all data.
void visit(DataVisitor v) {
data.visit(v);
}
}
/**
* A sticky allocation that remains without references. Will not be treated as 'unreachable' either.
*/
class StickyAllocation extends Allocation {
init(unsafe:RawPtr src, Data data) {
init(src, data) {}
}
private Bool removeMe;
Bool remove() : override {
unreachable = false;
removeMe;
}
// Unstick the allocation.
void unstick() {
removeMe = true;
}
}
/**
* Registrator. Maps data to their allocation.
*/
class Registrator extends DataVisitor {
// Current allocation.
private Allocation? current;
// Result data.
Data->Allocation result;
void setAllocation(Allocation? a) {
current = a;
}
void visit(Data d) : override {
if (current)
result.put(d, current);
}
}
|