Skip to content

Commit

Permalink
Fix client-side performance of chat UI (#11612)
Browse files Browse the repository at this point in the history
  • Loading branch information
Desour committed Sep 19, 2021
1 parent 40ea4dd commit e79d615
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 18 deletions.
13 changes: 8 additions & 5 deletions src/chat.cpp
Expand Up @@ -50,6 +50,8 @@ ChatBuffer::ChatBuffer(u32 scrollback):

void ChatBuffer::addLine(const std::wstring &name, const std::wstring &text)
{
m_lines_modified = true;

ChatLine line(name, text);
m_unformatted.push_back(line);

Expand All @@ -72,6 +74,7 @@ void ChatBuffer::clear()
m_unformatted.clear();
m_formatted.clear();
m_scroll = 0;
m_lines_modified = true;
}

u32 ChatBuffer::getLineCount() const
Expand Down Expand Up @@ -99,14 +102,11 @@ void ChatBuffer::deleteOldest(u32 count)
u32 del_unformatted = 0;
u32 del_formatted = 0;

while (count > 0 && del_unformatted < m_unformatted.size())
{
while (count > 0 && del_unformatted < m_unformatted.size()) {
++del_unformatted;

// keep m_formatted in sync
if (del_formatted < m_formatted.size())
{

if (del_formatted < m_formatted.size()) {
sanity_check(m_formatted[del_formatted].first);
++del_formatted;
while (del_formatted < m_formatted.size() &&
Expand All @@ -120,6 +120,9 @@ void ChatBuffer::deleteOldest(u32 count)
m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted);
m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted);

if (del_unformatted > 0)
m_lines_modified = true;

if (at_bottom)
m_scroll = getBottomScrollPos();
else
Expand Down
12 changes: 12 additions & 0 deletions src/chat.h
Expand Up @@ -113,6 +113,13 @@ class ChatBuffer
// Scroll to top of buffer (oldest)
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.
// Appends the formatted lines to the destination array and
// returns the number of formatted lines.
Expand Down Expand Up @@ -146,6 +153,11 @@ class ChatBuffer
bool m_cache_clickable_chat_weblinks;
// Color of clickable chat weblinks
irr::video::SColor m_cache_chat_weblink_color;

// 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
Expand Down
20 changes: 13 additions & 7 deletions src/client/game.cpp
Expand Up @@ -804,7 +804,7 @@ class Game {
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,
const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
Expand Down Expand Up @@ -2922,7 +2922,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
while (!m_chat_log_buf.empty())
Expand All @@ -2938,8 +2938,14 @@ void Game::updateChat(f32 dtime, const v2u32 &screensize)
chat_backend->step(dtime);

// Display all messages in a static text element
m_game_ui->setChatText(chat_backend->getRecentChat(),
chat_backend->getRecentBuffer().getLineCount());
auto &buf = chat_backend->getRecentBuffer();
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)
Expand Down Expand Up @@ -3861,9 +3867,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
Get chat messages from client
*/

v2u32 screensize = driver->getScreenSize();

updateChat(dtime, screensize);
updateChat(dtime);

/*
Inventory
Expand Down Expand Up @@ -3957,6 +3961,8 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
/*
Profiler graph
*/
v2u32 screensize = driver->getScreenSize();

if (m_game_ui->m_flags.show_profiler_graph)
graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont());

Expand Down
18 changes: 12 additions & 6 deletions src/client/gameui.cpp
Expand Up @@ -227,7 +227,13 @@ void GameUI::showTranslatedStatusText(const char *str)

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
s32 chat_y = 5;

Expand All @@ -238,15 +244,15 @@ void GameUI::setChatText(const EnrichedString &chat_text, u32 recent_chat_count)

const v2u32 &window_size = RenderingEngine::getWindowSize();

core::rect<s32> chat_size(10, chat_y,
window_size.X - 20, 0);
core::rect<s32> chat_size(10, chat_y, window_size.X - 20, 0);
chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y,
m_guitext_chat->getTextHeight() + chat_y);
m_guitext_chat->getTextHeight() + chat_y);

m_guitext_chat->setRelativePosition(chat_size);
setStaticText(m_guitext_chat, chat_text);
if (chat_size == m_current_chat_size)
return;
m_current_chat_size = chat_size;

m_recent_chat_count = recent_chat_count;
m_guitext_chat->setRelativePosition(chat_size);
}

void GameUI::updateProfiler()
Expand Down
2 changes: 2 additions & 0 deletions src/client/gameui.h
Expand Up @@ -89,6 +89,7 @@ class GameUI
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 updateChatSize();

void updateProfiler();

Expand Down Expand Up @@ -122,6 +123,7 @@ class GameUI

gui::IGUIStaticText *m_guitext_chat = nullptr; // Chat text
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
u8 m_profiler_current_page = 0;
Expand Down

0 comments on commit e79d615

Please sign in to comment.