Skip to content

Commit 599b73e

Browse files
committed
move unnecessary logic out of render functions
1 parent bbed0af commit 599b73e

1 file changed

Lines changed: 71 additions & 16 deletions

File tree

library/SDLConsole_impl.cpp

Lines changed: 71 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,9 +2264,21 @@ class TextSelection {
22642264
};
22652265

22662266
class OutputPane : public Widget {
2267+
private:
2268+
struct VisibleRow {
2269+
std::u32string_view text;
2270+
SDL_Point coord;
2271+
SDL_Color color;
2272+
};
2273+
2274+
struct VisibleRowsCache {
2275+
std::vector<VisibleRow> rows;
2276+
bool rebuild { true };
2277+
};
22672278
public:
22682279
// Use deque to hold a stable reference.
22692280
std::deque<TextEntry> entries;
2281+
VisibleRowsCache visible_rows_cache;
22702282
Prompt prompt;
22712283
Scrollbar scrollbar;
22722284
// Scrollbar could be made optional.
@@ -2346,7 +2358,7 @@ class OutputPane : public Widget {
23462358
});
23472359

23482360
scrollbar.connect<SDL_UserEvent>(InternalEventType::value_changed, [this](SDL_UserEvent& e) {
2349-
scroll_offset = SignalEmitter::copy_data1_from_userevent<int>(e, 0);
2361+
set_scroll_offset_from_scrollbar(SignalEmitter::copy_data1_from_userevent<int>(e, 0));
23502362
});
23512363
}
23522364

@@ -2475,12 +2487,20 @@ class OutputPane : public Widget {
24752487
scrollbar.set_content_size(1);
24762488
text_selection.reset();
24772489
emit_text_selection_changed();
2490+
visible_rows_cache.rebuild = true;
24782491
}
24792492

24802493
void set_scroll_offset(int v)
24812494
{
24822495
scroll_offset = v;
24832496
scrollbar.scroll_to(v);
2497+
visible_rows_cache.rebuild = true;
2498+
}
2499+
2500+
void set_scroll_offset_from_scrollbar(int v)
2501+
{
2502+
scroll_offset = v;
2503+
visible_rows_cache.rebuild = true;
24842504
}
24852505

24862506
void begin_text_selection(const SDL_Point p)
@@ -2519,22 +2539,23 @@ class OutputPane : public Widget {
25192539

25202540
void scroll(ScrollAction sa)
25212541
{
2542+
int v = 0;
25222543
switch (sa) {
25232544
case ScrollAction::up:
2524-
scroll_offset += 1;
2545+
v = 1;
25252546
break;
25262547
case ScrollAction::down:
2527-
scroll_offset -= 1;
2548+
v = -1;
25282549
break;
25292550
case ScrollAction::page_up:
2530-
scroll_offset += rows() / 2;
2551+
v = rows() / 2;
25312552
break;
25322553
case ScrollAction::page_down:
2533-
scroll_offset -= rows() / 2;
2554+
v = -rows() / 2;
25342555
break;
25352556
}
25362557

2537-
set_scroll_offset(std::min(std::max(0, scroll_offset), num_rows - 1));
2558+
set_scroll_offset(std::min(std::max(0, v + scroll_offset), num_rows - 1));
25382559
}
25392560

25402561
void resize(const SDL_Rect& rect) override
@@ -2551,6 +2572,8 @@ class OutputPane : public Widget {
25512572
wrap_text(e);
25522573
}
25532574

2575+
visible_rows_cache.rebuild = true;
2576+
25542577
context.props.set(property::RT_OUTPUT_COLUMNS, columns());
25552578
context.props.set(property::RT_OUTPUT_ROWS, rows());
25562579
}
@@ -2604,6 +2627,7 @@ class OutputPane : public Widget {
26042627
entry.wrap_text(font->char_width, content_rect.w);
26052628
num_rows += entry.size;
26062629
scrollbar.set_content_size(num_rows + prompt.entry.size);
2630+
visible_rows_cache.rebuild = true;
26072631
}
26082632

26092633
/*
@@ -2709,6 +2733,7 @@ class OutputPane : public Widget {
27092733
}
27102734
#endif
27112735

2736+
27122737
void render() override
27132738
{
27142739
// SDL_RenderSetScale(renderer(), 1.2, 1.2);
@@ -2721,20 +2746,31 @@ class OutputPane : public Widget {
27212746
// SDL_SetTextureColorMod(font->texture, 0, 128, 0);
27222747

27232748
render_prompt_and_output();
2749+
27242750
// SDL_SetTextureColorMod(font->texture, 255, 255, 255);
27252751
prompt.render_cursor(scroll_offset);
27262752
sdl_console::SDL_RenderSetViewport(renderer(), &parent->frame);
27272753
scrollbar.render();
27282754
// SDL_RenderSetScale(renderer(), 1.0, 1.0);
27292755
}
27302756

2731-
void render_prompt_and_output()
2757+
void build_visible_prompt_and_output_rows()
27322758
{
2759+
visible_rows_cache.rows.clear();
2760+
visible_rows_cache.rebuild = false;
2761+
27332762
const int max_row = rows() + scroll_offset;
27342763
int ypos = content_rect.h; // Start from the bottom
2735-
int row_counter = scroll_offset;
2764+
int row_counter = 0;
27362765

2737-
render_entry(prompt.entry, ypos, row_counter, max_row);
2766+
std::vector<VisibleRow> rows;
2767+
2768+
auto append_visible_rows = [this, &ypos, &row_counter, max_row](auto&& entry) {
2769+
auto more = get_visible_entry_rows(entry, ypos, row_counter, max_row);
2770+
std::ranges::move(more, std::back_inserter(visible_rows_cache.rows));
2771+
};
2772+
2773+
append_visible_rows(prompt.entry);
27382774

27392775
if (entries.empty()) {
27402776
return;
@@ -2744,14 +2780,15 @@ class OutputPane : public Widget {
27442780
if (row_counter > max_row) {
27452781
break;
27462782
}
2747-
render_entry(entry, ypos, row_counter, max_row);
2783+
2784+
append_visible_rows(entry);
27482785
}
27492786
}
27502787

27512788
// FIXME: Position and rows to render calculations should be done elsewhere.
2752-
void render_entry(TextEntry& entry, int& ypos, int& row_counter, int max_row)
2789+
std::vector<VisibleRow> get_visible_entry_rows(TextEntry& entry, int& ypos, int& row_counter, int max_row)
27532790
{
2754-
auto scoped_color = font->set_color(entry.color_opt);
2791+
std::vector<VisibleRow> vrows;
27552792

27562793
for (auto& row : entry.fragments() | std::views::reverse) {
27572794
row_counter++;
@@ -2765,6 +2802,24 @@ class OutputPane : public Widget {
27652802

27662803
ypos -= font->line_height_with_spacing();
27672804
row.coord.y = ypos;
2805+
2806+
vrows.push_back({
2807+
row.text,
2808+
{ row.coord.x, ypos },
2809+
entry.color_opt.value_or(SDL_Color{255,255,255,255})
2810+
});
2811+
}
2812+
return vrows;
2813+
}
2814+
2815+
void render_prompt_and_output()
2816+
{
2817+
if (visible_rows_cache.rebuild) {
2818+
build_visible_prompt_and_output_rows();
2819+
}
2820+
2821+
for (const auto& row : visible_rows_cache.rows) {
2822+
font->set_color(row.color);
27682823
font->render(row.text, row.coord.x, row.coord.y);
27692824
}
27702825
}
@@ -3170,15 +3225,15 @@ class SDLConsole_impl : public std::enable_shared_from_this<SDLConsole_impl> {
31703225
handle_tasks();
31713226

31723227
static auto last_tick = SDL_GetTicks64();
3173-
constexpr Uint32 shown_min_frame_time = 1000 / 20; // 20 fps;
3174-
constexpr Uint32 minimized_min_frame_time = 1000;
3228+
constexpr Uint32 shown_rate = 1000 / 20; // 20 fps;
3229+
constexpr Uint32 minimized_rate = 1000;
31753230

31763231
auto current_tick = SDL_GetTicks64();
31773232
if (main_window.is_shown)
31783233
{
3179-
auto min_frame_time = main_window.is_minimized ? minimized_min_frame_time : shown_min_frame_time;
3234+
auto rate = main_window.is_minimized ? minimized_rate : shown_rate;
31803235

3181-
if (current_tick - last_tick >= min_frame_time) {
3236+
if (current_tick - last_tick >= rate) {
31823237
render_frame();
31833238
last_tick = current_tick;
31843239
}

0 commit comments

Comments
 (0)