From 2eccbbbe6fe2589f9133b7e5702832e21b26e8cf Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 17 Sep 2019 19:06:49 +1000 Subject: [PATCH] Avoid unnecessary allocations in NCursesUI::Window::draw calls Pass an ArrayView instead of a DisplayLine& so that the newly common case of passing a single atom does not require constructing a Vector. --- src/display_buffer.hh | 3 +++ src/ncurses_ui.cc | 41 +++++++++++++++++++---------------------- src/ncurses_ui.hh | 8 ++++---- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/display_buffer.hh b/src/display_buffer.hh index 045a1cc8..1c8fc53d 100644 --- a/src/display_buffer.hh +++ b/src/display_buffer.hh @@ -30,6 +30,9 @@ public: DisplayAtom(String str, Face face) : face(face), m_type(Text), m_text(std::move(str)) {} + explicit DisplayAtom(String str) + : DisplayAtom(std::move(str), Face{}) {} + StringView content() const; ColumnCount length() const; diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 2c83a63a..7196f344 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -66,10 +66,8 @@ void NCursesUI::Window::move_cursor(DisplayCoord coord) wmove(win, (int)coord.line, (int)coord.column); } -void NCursesUI::Window::draw_line(Palette& palette, - const DisplayLine& line, - ColumnCount width, - const Face& default_face) +void NCursesUI::Window::draw(Palette& palette, ConstArrayView atoms, + ColumnCount max_width, const Face& default_face) { auto add_str = [&](StringView str) { waddnstr(win, str.begin(), (int)str.length()); }; @@ -101,7 +99,7 @@ void NCursesUI::Window::draw_line(Palette& palette, wbkgdset(win, COLOR_PAIR(palette.get_color_pair(default_face))); ColumnCount column = 0; - for (const DisplayAtom& atom : line) + for (const DisplayAtom& atom : atoms) { set_face(atom.face); @@ -109,7 +107,7 @@ void NCursesUI::Window::draw_line(Palette& palette, if (content.empty()) continue; - const auto remaining_columns = width - column; + const auto remaining_columns = max_width - column; if (content.back() == '\n' and content.column_length() - 1 < remaining_columns) { @@ -123,7 +121,7 @@ void NCursesUI::Window::draw_line(Palette& palette, column += content.column_length(); } } - if (column < width) + if (column < max_width) wclrtoeol(win); } @@ -465,16 +463,15 @@ void NCursesUI::draw(const DisplayBuffer& display_buffer, for (const DisplayLine& line : display_buffer.lines()) { m_window.move_cursor(line_index); - m_window.draw_line(m_palette, line, dim.column, default_face); + m_window.draw(m_palette, line.atoms(), dim.column, default_face); ++line_index; } auto face = merge_faces(default_face, padding_face); - DisplayLine line("~", {}); while (line_index < dim.line + line_offset) { m_window.move_cursor(line_index++); - m_window.draw_line(m_palette, line, dim.column, face); + m_window.draw(m_palette, DisplayAtom("~"), dim.column, face); } m_dirty = true; @@ -487,7 +484,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, const LineCount status_line_pos = m_status_on_top ? 0 : m_dimensions.line; m_window.move_cursor(status_line_pos); - m_window.draw_line(m_palette, status_line, m_dimensions.column, default_face); + m_window.draw(m_palette, status_line.atoms(), m_dimensions.column, default_face); const auto mode_len = mode_line.length(); m_status_len = status_line.length(); @@ -496,7 +493,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, { ColumnCount col = m_dimensions.column - mode_len; m_window.move_cursor({status_line_pos, col}); - m_window.draw_line(m_palette, mode_line, m_dimensions.column - col, default_face); + m_window.draw(m_palette, mode_line.atoms(), m_dimensions.column - col, default_face); } else if (remaining > 2) { @@ -507,7 +504,7 @@ void NCursesUI::draw_status(const DisplayLine& status_line, ColumnCount col = m_dimensions.column - remaining + 1; m_window.move_cursor({status_line_pos, col}); - m_window.draw_line(m_palette, trimmed_mode_line, m_dimensions.column - col, default_face); + m_window.draw(m_palette, trimmed_mode_line.atoms(), m_dimensions.column - col, default_face); } if (m_set_title) @@ -803,8 +800,8 @@ void NCursesUI::draw_menu() ColumnCount pos = 0; m_menu.move_cursor({0, 0}); - m_menu.draw_line(m_palette, DisplayLine(m_menu.first_item > 0 ? "< " : " ", {}), - m_menu.size.column, m_menu.bg); + m_menu.draw(m_palette, DisplayAtom(m_menu.first_item > 0 ? "< " : " "), + m_menu.size.column, m_menu.bg); int i = m_menu.first_item; for (; i < item_count and pos < win_width; ++i) @@ -812,14 +809,14 @@ void NCursesUI::draw_menu() const DisplayLine& item = m_menu.items[i]; const ColumnCount item_width = item.length(); auto& face = i == m_menu.selected_item ? m_menu.fg : m_menu.bg; - m_menu.draw_line(m_palette, item, win_width - pos, face); - m_menu.draw_line(m_palette, DisplayLine(item_width > win_width - pos ? "…" : " ", {}), + m_menu.draw(m_palette, item.atoms(), win_width - pos, face); + m_menu.draw(m_palette, DisplayAtom(item_width > win_width - pos ? "…" : " "), win_width - pos - item_width, m_menu.bg); pos += item_width + 1; } auto end_str = String{' ', pos > win_width ? 0 : win_width - pos + 1} + (i == item_count ? " " : ">"); - m_menu.draw_line(m_palette, DisplayLine(end_str, {}), m_menu.size.column - pos, m_menu.bg); + m_menu.draw(m_palette, DisplayAtom(end_str), m_menu.size.column - pos, m_menu.bg); m_dirty = true; return; @@ -850,14 +847,14 @@ void NCursesUI::draw_menu() if (item_idx < item_count) { const DisplayLine& item = m_menu.items[item_idx]; - m_menu.draw_line(m_palette, item, column_width, face); + m_menu.draw(m_palette, item.atoms(), column_width, face); column = item.length(); } - m_menu.draw_line(m_palette, DisplayLine(String{' ', column_width - column}, {}), column_width - column, face); + m_menu.draw(m_palette, DisplayAtom(String{' ', column_width - column}), column_width - column, face); } const bool is_mark = line >= mark_line and line < mark_line + mark_height; m_menu.move_cursor({line, m_menu.size.column - 1}); - m_menu.draw_line(m_palette, DisplayLine(is_mark ? "█" : "░", {}), 1, m_menu.bg); + m_menu.draw(m_palette, DisplayAtom(is_mark ? "█" : "░"), 1, m_menu.bg); } m_dirty = true; } @@ -1185,7 +1182,7 @@ void NCursesUI::info_show(StringView title, StringView content, for (auto line = 0_line; line < info_box.size.line; ++line) { m_info.move_cursor(line); - m_info.draw_line(m_palette, DisplayLine(info_box.contents[(int)line], {}), info_box.size.column, face); + m_info.draw(m_palette, DisplayAtom(info_box.contents[(int)line]), info_box.size.column, face); } m_dirty = true; } diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh index 021a02e6..ee695fc3 100644 --- a/src/ncurses_ui.hh +++ b/src/ncurses_ui.hh @@ -15,6 +15,8 @@ namespace Kakoune { +class DisplayAtom; + struct NCursesWin; class NCursesUI : public UserInterface, public Singleton @@ -101,10 +103,8 @@ private: void refresh(bool force); void move_cursor(DisplayCoord coord); void mark_dirty(LineCount pos, LineCount count); - void draw_line(Palette& palette, - const DisplayLine& line, - ColumnCount width, - const Face& default_face); + void draw(Palette& palette, ConstArrayView atoms, + ColumnCount width, const Face& default_face); explicit operator bool() const { return win; }