Just standard multithreading stuff; access to the allocator while hot
threads are running means stuff can change underneath us even /during/
a read. I've mutex locked state for stuff in the drawing domain which
stops this issue.
Seems near the 100,000 node mark, the vector craps itself? I keep
getting "heap use after free" errors here when trying to access the
allocator vector. Disabling fsan just leads to a segment fault near
the same point.
I think we might need to introduce our own vector :)
Arranges a thread set, draws based on draw_state. No need to lock the
mutex since drawing should only require reading. Still has a timer in
case we need to do timed checks.
One God structure which will hold all the necessary state, ensuring I
only need to compute stuff like bounds at most once, better than
computing it on every draw (which is WAY slower at scale).
Using a stack or queue, we can replace a function recursive tree
traversal with a single call. A stack would make it a DFS while a
queue would be a BFS. Since there's only ever two children, and at
high iteration counts we're getting quite large depth, it would be
best to do a DFS, hence the stack.
Draws the current node by converting its norm value (which is in
(lower, upper)) to a screen value, drawing a line there.
It then recurs on the children of the node.
An index is a pointer, and they don't change if the vector decides to
reallocate internally unlike the bastardised pointers I was rolling up
before. This simplifies design a bit.
Pops an item off the queue and generate left and right children for it,
if those are empty. Then push those children into the queue for the
next iteration.
NOTE: Because we're using a queue, this does a breadth first
generation of the tree, which is what we want.