Use text container for ingame server info MOTD

Optimize MOTD rendering in ingame menu by caching the text.

Use the correct text height based on the aligned font size instead of the original font size, to fix the discrepancy between the scrollable height and the text height.
This commit is contained in:
Robert Müller 2023-02-19 12:17:56 +01:00
parent c286f32b17
commit de99fecaa0
5 changed files with 47 additions and 5 deletions

View file

@ -2332,6 +2332,9 @@ void CMenus::OnStateChange(int NewState, int OldState)
// reset active item
UI()->SetActiveItem(nullptr);
if(OldState == IClient::STATE_ONLINE || OldState == IClient::STATE_OFFLINE)
TextRender()->DeleteTextContainer(m_MotdTextContainerIndex);
if(NewState == IClient::STATE_OFFLINE)
{
if(OldState >= IClient::STATE_ONLINE && NewState < IClient::STATE_QUITTING)
@ -2370,6 +2373,11 @@ void CMenus::OnStateChange(int NewState, int OldState)
}
}
void CMenus::OnWindowResize()
{
TextRender()->DeleteTextContainer(m_MotdTextContainerIndex);
}
void CMenus::OnRender()
{
UI()->StartCheck();

View file

@ -513,11 +513,13 @@ protected:
void RenderStartMenu(CUIRect MainView);
// found in menus_ingame.cpp
int m_MotdTextContainerIndex = -1;
void RenderGame(CUIRect MainView);
void PopupConfirmDisconnect();
void PopupConfirmDisconnectDummy();
void RenderPlayers(CUIRect MainView);
void RenderServerInfo(CUIRect MainView);
void RenderServerInfoMotd(CUIRect Motd);
void RenderServerControl(CUIRect MainView);
bool RenderServerControlKick(CUIRect MainView, bool FilterSpectators);
bool RenderServerControlServer(CUIRect MainView);
@ -590,6 +592,7 @@ public:
void OnConsoleInit() override;
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnWindowResize() override;
virtual void OnReset() override;
virtual void OnRender() override;
virtual bool OnInput(IInput::CEvent Event) override;

View file

@ -475,7 +475,11 @@ void CMenus::RenderServerInfo(CUIRect MainView)
TextRender()->Text(GameInfo.x + x, GameInfo.y + y, 20, aBuf, GameInfo.w - 10.0f);
}
// motd
RenderServerInfoMotd(Motd);
}
void CMenus::RenderServerInfoMotd(CUIRect Motd)
{
const float MotdFontSize = 16.0f;
Motd.HSplitTop(10.0f, nullptr, &Motd);
Motd.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f);
@ -487,6 +491,9 @@ void CMenus::RenderServerInfo(CUIRect MainView)
Motd.HSplitTop(5.0f, nullptr, &Motd);
TextRender()->Text(MotdHeader.x, MotdHeader.y, 2.0f * MotdFontSize, Localize("MOTD"), -1.0f);
if(!m_pClient->m_Motd.ServerMotd()[0])
return;
static CScrollRegion s_ScrollRegion;
vec2 ScrollOffset(0.0f, 0.0f);
CScrollRegionParams ScrollParams;
@ -494,10 +501,24 @@ void CMenus::RenderServerInfo(CUIRect MainView)
s_ScrollRegion.Begin(&Motd, &ScrollOffset, &ScrollParams);
Motd.y += ScrollOffset.y;
static float s_MotdHeight = 0.0f;
static int64_t s_MotdLastUpdateTime = -1;
if(m_MotdTextContainerIndex == -1 || s_MotdLastUpdateTime == -1 || s_MotdLastUpdateTime != m_pClient->m_Motd.ServerMotdUpdateTime())
{
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, 0.0f, 0.0f, MotdFontSize, TEXTFLAG_RENDER);
Cursor.m_LineWidth = Motd.w;
TextRender()->RecreateTextContainer(m_MotdTextContainerIndex, &Cursor, m_pClient->m_Motd.ServerMotd());
s_MotdHeight = Cursor.Height();
s_MotdLastUpdateTime = m_pClient->m_Motd.ServerMotdUpdateTime();
}
CUIRect MotdTextArea;
Motd.HSplitTop((str_countchr(m_pClient->m_Motd.ServerMotd(), '\n') + 1) * MotdFontSize, &MotdTextArea, &Motd);
Motd.HSplitTop(s_MotdHeight, &MotdTextArea, &Motd);
s_ScrollRegion.AddRect(MotdTextArea);
TextRender()->Text(MotdTextArea.x, MotdTextArea.y, MotdFontSize, m_pClient->m_Motd.ServerMotd(), MotdTextArea.w);
if(m_MotdTextContainerIndex != -1)
TextRender()->RenderTextContainer(m_MotdTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), MotdTextArea.x, MotdTextArea.y);
s_ScrollRegion.End();
}

View file

@ -10,6 +10,13 @@
#include "motd.h"
CMotd::CMotd()
{
m_aServerMotd[0] = '\0';
m_ServerMotdTime = 0;
m_ServerMotdUpdateTime = 0;
}
void CMotd::Clear()
{
m_ServerMotdTime = 0;
@ -112,8 +119,9 @@ void CMotd::OnMessage(int MsgType, void *pRawMsg)
if(g_Config.m_ClPrintMotd && *pLast != '\0')
m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageHighlightColor)));
m_ServerMotdUpdateTime = time();
if(m_aServerMotd[0] && g_Config.m_ClMotdTime)
m_ServerMotdTime = time() + time_freq() * g_Config.m_ClMotdTime;
m_ServerMotdTime = m_ServerMotdUpdateTime + time_freq() * g_Config.m_ClMotdTime;
else
m_ServerMotdTime = 0;
TextRender()->DeleteTextContainer(m_TextContainerIndex);

View file

@ -6,16 +6,18 @@
class CMotd : public CComponent
{
// motd
char m_aServerMotd[900];
int64_t m_ServerMotdTime;
int64_t m_ServerMotdUpdateTime;
int m_RectQuadContainer = -1;
int m_TextContainerIndex = -1;
public:
CMotd();
virtual int Sizeof() const override { return sizeof(*this); }
const char *ServerMotd() const { return m_aServerMotd; }
int64_t ServerMotdUpdateTime() const { return m_ServerMotdUpdateTime; }
void Clear();
bool IsActive() const;