diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-07-26 21:44:08 +0100 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-07-26 21:44:08 +0100 |
commit | bb6ded706f87abe5d5f92404b0145ac95de76a11 (patch) | |
tree | 4886d27218841f1f21c6b5ec927c012a15ba818a | |
parent | ca7931e0c29785314d2fe88279dabd55c9afc7c2 (diff) | |
download | cw_tree-bb6ded706f87abe5d5f92404b0145ac95de76a11.tar.gz cw_tree-bb6ded706f87abe5d5f92404b0145ac95de76a11.tar.bz2 cw_tree-bb6ded706f87abe5d5f92404b0145ac95de76a11.zip |
Move all functions and state into one struct
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).
-rw-r--r-- | src/main.cpp | 137 |
1 files changed, 70 insertions, 67 deletions
diff --git a/src/main.cpp b/src/main.cpp index 5f8bc3c..1718090 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,30 +32,6 @@ #define LINE_TOP (7 * HEIGHT / 16) #define LINE_BOTTOM (9 * HEIGHT / 16) -Node rightmost_node(const NodeAllocator &allocator) -{ - auto node = allocator.getVal(0); - while (node.right.has_value()) - node = allocator.getVal(node.right.value()); - return node; -} - -Node leftmost_node(const NodeAllocator &allocator) -{ - auto node = allocator.getVal(0); - while (node.left.has_value()) - node = allocator.getVal(node.left.value()); - return node; -} - -constexpr word_t clamp_to_width(long double value, long double min, - long double max) -{ - // translate v in [min, max] -> v' in [0, WIDTH] - // [min, max] -> [0, max-min] -> [0, WIDTH] - return WIDTH / (max - min) * (value - min); -} - void draw_fraction(Fraction f, word_t x, word_t y) { std::string s{to_string(f)}; @@ -64,54 +40,77 @@ void draw_fraction(Fraction f, word_t x, word_t y) DrawText(s.c_str(), x - width / 2, y - FONT_SIZE, FONT_SIZE, WHITE); } -void draw_node_number_line(const NodeAllocator &allocator, long double lower, - long double upper) +struct State { - std::stack<Node> stack; - stack.push(allocator.getVal(0)); - while (!stack.empty()) + NodeAllocator allocator; + std::queue<word_t> iteration_queue; + word_t root; + Node leftmost, rightmost; + long double lower_bound, upper_bound; + + State(const Fraction start) : allocator{256} { - Node n = stack.top(); - stack.pop(); - word_t x = clamp_to_width(n.value.norm, lower, upper); - DrawLine(x, LINE_TOP, x, LINE_BOTTOM, RED); - if (n.left.has_value()) - stack.push(allocator.getVal(n.left.value())); - if (n.right.has_value()) - stack.push(allocator.getVal(n.right.value())); + root = allocator.alloc(start); + iteration_queue.push(root); + leftmost = allocator.getVal(root); + rightmost = allocator.getVal(root); + compute_bounds(); } -} -void draw_number_line(const NodeAllocator &allocator) -{ - // Draw a general guide number line - DrawLine(0, HEIGHT / 2, WIDTH, HEIGHT / 2, WHITE); - // Figure out the leftmost and rightmost nodes for bounds - const auto right = rightmost_node(allocator); - const auto left = leftmost_node(allocator); - const auto upper_bound = std::ceill(right.value.norm); - const auto lower_bound = std::floorl(left.value.norm); - - // Draw all the nodes - draw_node_number_line(allocator, lower_bound, upper_bound); - - // Draw the bounds, with their values, in white - word_t lower_x = clamp_to_width(left.value.norm, lower_bound, upper_bound); - word_t upper_x = clamp_to_width(right.value.norm, lower_bound, upper_bound); - draw_fraction(left.value, lower_x, 3 * HEIGHT / 8); - draw_fraction(right.value, upper_x, 3 * HEIGHT / 8); - DrawLine(lower_x, LINE_TOP, lower_x, LINE_BOTTOM, WHITE); - DrawLine(upper_x, LINE_TOP, upper_x, LINE_BOTTOM, WHITE); -} + void compute_bounds() + { + lower_bound = std::floorl(leftmost.value.norm); + upper_bound = std::ceill(rightmost.value.norm); + } + + void compute_bound_nodes() + { + leftmost = allocator.getVal(0); + while (leftmost.left.has_value()) + leftmost = allocator.getVal(leftmost.left.value()); + + rightmost = allocator.getVal(0); + while (rightmost.right.has_value()) + rightmost = allocator.getVal(rightmost.right.value()); + } + + constexpr word_t clamp_to_width(long double value) + { + return WIDTH / (upper_bound - lower_bound) * (value - lower_bound); + } + + void draw_bounds() + { + word_t lower_x = clamp_to_width(leftmost.value.norm); + word_t upper_x = clamp_to_width(rightmost.value.norm); + draw_fraction(leftmost.value, lower_x, 3 * HEIGHT / 8); + draw_fraction(rightmost.value, upper_x, 3 * HEIGHT / 8); + DrawLine(lower_x, LINE_TOP, lower_x, LINE_BOTTOM, WHITE); + DrawLine(upper_x, LINE_TOP, upper_x, LINE_BOTTOM, WHITE); + } + + void draw_nodes() + { + std::stack<Node> stack; + stack.push(allocator.getVal(0)); + while (!stack.empty()) + { + Node n = stack.top(); + stack.pop(); + word_t x = clamp_to_width(n.value.norm); + DrawLine(x, LINE_TOP, x, LINE_BOTTOM, RED); + if (n.left.has_value()) + stack.push(allocator.getVal(n.left.value())); + if (n.right.has_value()) + stack.push(allocator.getVal(n.right.value())); + } + } +}; int main(void) { - // Setup CW tree - NodeAllocator allocator{0}; - std::queue<word_t> to_iterate; - Fraction best_frac{1, 2}; - word_t root = allocator.alloc({best_frac}); - to_iterate.push(root); + // Setup state + State state{{1, 2}}; // Setup meta text (counter, iterations, etc) word_t count = 1, prev_count = 0; @@ -124,7 +123,9 @@ int main(void) { if (IsKeyPressed(KEY_SPACE)) { - iterate(to_iterate, allocator); + iterate(state.iteration_queue, state.allocator); + state.compute_bound_nodes(); + state.compute_bounds(); count += 2; } if (prev_count != count) @@ -139,7 +140,9 @@ int main(void) ClearBackground(BLACK); BeginDrawing(); - draw_number_line(allocator); + DrawLine(0, HEIGHT / 2, WIDTH, HEIGHT / 2, WHITE); + state.draw_nodes(); + state.draw_bounds(); DrawText(format_str.c_str(), WIDTH / 2 - format_str_width / 2, LINE_TOP - HEIGHT / 4, FONT_SIZE * 2, WHITE); EndDrawing(); |