Fix client-side performance of chat UI (#11612)

master
DS 2021-09-19 20:23:35 +02:00 committed by Maksim
parent 3a7a77f3b2
commit 635e2893ad
5 changed files with 47 additions and 18 deletions

View File

@ -39,6 +39,8 @@ ChatBuffer::ChatBuffer(u32 scrollback):
void ChatBuffer::addLine(const std::wstring &name, const std::wstring &text) void ChatBuffer::addLine(const std::wstring &name, const std::wstring &text)
{ {
m_lines_modified = true;
ChatLine line(name, text); ChatLine line(name, text);
m_unformatted.push_back(line); m_unformatted.push_back(line);
@ -61,6 +63,7 @@ void ChatBuffer::clear()
m_unformatted.clear(); m_unformatted.clear();
m_formatted.clear(); m_formatted.clear();
m_scroll = 0; m_scroll = 0;
m_lines_modified = true;
} }
u32 ChatBuffer::getLineCount() const u32 ChatBuffer::getLineCount() const
@ -88,14 +91,11 @@ void ChatBuffer::deleteOldest(u32 count)
u32 del_unformatted = 0; u32 del_unformatted = 0;
u32 del_formatted = 0; u32 del_formatted = 0;
while (count > 0 && del_unformatted < m_unformatted.size()) while (count > 0 && del_unformatted < m_unformatted.size()) {
{
++del_unformatted; ++del_unformatted;
// keep m_formatted in sync // keep m_formatted in sync
if (del_formatted < m_formatted.size()) if (del_formatted < m_formatted.size()) {
{
sanity_check(m_formatted[del_formatted].first); sanity_check(m_formatted[del_formatted].first);
++del_formatted; ++del_formatted;
while (del_formatted < m_formatted.size() && while (del_formatted < m_formatted.size() &&
@ -109,6 +109,9 @@ void ChatBuffer::deleteOldest(u32 count)
m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted); m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted);
m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted); m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted);
if (del_unformatted > 0)
m_lines_modified = true;
if (at_bottom) if (at_bottom)
m_scroll = getBottomScrollPos(); m_scroll = getBottomScrollPos();
else else

View File

@ -111,6 +111,13 @@ public:
// Scroll to top of buffer (oldest) // Scroll to top of buffer (oldest)
void scrollTop(); void scrollTop();
// Functions for keeping track of whether the lines were modified by any
// preceding operations
// If they were not changed, getLineCount() and getLine() output the same as
// before
bool getLinesModified() const { return m_lines_modified; }
void resetLinesModified() { m_lines_modified = false; }
// Format a chat line for the given number of columns. // Format a chat line for the given number of columns.
// Appends the formatted lines to the destination array and // Appends the formatted lines to the destination array and
// returns the number of formatted lines. // returns the number of formatted lines.
@ -138,6 +145,11 @@ private:
std::vector<ChatFormattedLine> m_formatted; std::vector<ChatFormattedLine> m_formatted;
// Empty formatted line, for error returns // Empty formatted line, for error returns
ChatFormattedLine m_empty_formatted_line; ChatFormattedLine m_empty_formatted_line;
// Whether the lines were modified since last markLinesUnchanged()
// Is always set to true when m_unformatted is modified, because that's what
// determines the output of getLineCount() and getLine()
bool m_lines_modified = true;
}; };
class ChatPrompt class ChatPrompt

View File

@ -849,7 +849,7 @@ private:
CameraOrientation *cam); CameraOrientation *cam);
void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam); void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
void updateChat(f32 dtime, const v2u32 &screensize); void updateChat(f32 dtime);
bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item, bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed, const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
@ -2975,7 +2975,7 @@ void Game::processClientEvents(CameraOrientation *cam)
} }
} }
void Game::updateChat(f32 dtime, const v2u32 &screensize) void Game::updateChat(f32 dtime)
{ {
// Get new messages from error log buffer // Get new messages from error log buffer
while (!m_chat_log_buf.empty()) while (!m_chat_log_buf.empty())
@ -2991,8 +2991,14 @@ void Game::updateChat(f32 dtime, const v2u32 &screensize)
chat_backend->step(dtime); chat_backend->step(dtime);
// Display all messages in a static text element // Display all messages in a static text element
m_game_ui->setChatText(chat_backend->getRecentChat(), auto &buf = chat_backend->getRecentBuffer();
chat_backend->getRecentBuffer().getLineCount()); if (buf.getLinesModified()) {
buf.resetLinesModified();
m_game_ui->setChatText(chat_backend->getRecentChat(), buf.getLineCount());
}
// Make sure that the size is still correct
m_game_ui->updateChatSize();
} }
void Game::updateCamera(u32 busy_time, f32 dtime) void Game::updateCamera(u32 busy_time, f32 dtime)
@ -3917,9 +3923,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
Get chat messages from client Get chat messages from client
*/ */
v2u32 screensize = driver->getScreenSize(); updateChat(dtime);
updateChat(dtime, screensize);
/* /*
Inventory Inventory
@ -4033,6 +4037,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
/* /*
Profiler graph Profiler graph
*/ */
v2u32 screensize = driver->getScreenSize();
if (m_game_ui->m_flags.show_profiler_graph) if (m_game_ui->m_flags.show_profiler_graph)
graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont()); graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont());

View File

@ -233,7 +233,13 @@ void GameUI::showTranslatedStatusText(const char *str)
void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count) void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)
{ {
setStaticText(m_guitext_chat, chat_text);
m_recent_chat_count = recent_chat_count;
}
void GameUI::updateChatSize()
{
// Update gui element size and position // Update gui element size and position
s32 chat_y = 5 + g_fontengine->getLineHeight();; s32 chat_y = 5 + g_fontengine->getLineHeight();;
@ -242,15 +248,15 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)
const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize(); const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
core::rect<s32> chat_size(10, chat_y, core::rect<s32> chat_size(10, chat_y, window_size.X - 20, 0);
window_size.X - 20, 0);
chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y, chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y,
m_guitext_chat->getTextHeight() + chat_y); m_guitext_chat->getTextHeight() + chat_y);
if (chat_size == m_current_chat_size)
return;
m_current_chat_size = chat_size;
m_guitext_chat->setRelativePosition(chat_size); m_guitext_chat->setRelativePosition(chat_size);
setStaticText(m_guitext_chat, chat_text);
m_recent_chat_count = recent_chat_count;
} }
void GameUI::updateProfiler() void GameUI::updateProfiler()

View File

@ -88,6 +88,7 @@ public:
return m_flags.show_chat && m_recent_chat_count != 0 && m_profiler_current_page == 0; return m_flags.show_chat && m_recent_chat_count != 0 && m_profiler_current_page == 0;
} }
void setChatText(const EnrichedString &chat_text, u32 recent_chat_count); void setChatText(const EnrichedString &chat_text, u32 recent_chat_count);
void updateChatSize();
void updateProfiler(); void updateProfiler();
@ -121,6 +122,7 @@ private:
gui::IGUIStaticText *m_guitext_chat = nullptr; // Chat text gui::IGUIStaticText *m_guitext_chat = nullptr; // Chat text
u32 m_recent_chat_count = 0; u32 m_recent_chat_count = 0;
core::rect<s32> m_current_chat_size{0, 0, 0, 0};
gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text
u8 m_profiler_current_page = 0; u8 m_profiler_current_page = 0;