diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index b66e3aac9a..453dbde5e8 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -6009,6 +6009,15 @@ void InGameUI::drawObserverStats(Int& x, Int& y) Real scale = (Real)screenW / 1920.0f; scale = (scale < 0.7f) ? 0.7f : (scale > 2.0f) ? 2.0f : scale; + auto freeDisplayStrings = [](std::vector& strings) { + for (DisplayString* ds : strings) { + if (ds) { + TheDisplayStringManager->freeDisplayString(ds); + } + } + strings.clear(); + }; + static const Int numCols = 8; static const wchar_t* headers[numCols] = { L"(T) Name", L"Army", L"Cash", L"Cash/m", L"(R) XP", L"SP", L"K/D", L"Power" @@ -6023,6 +6032,10 @@ void InGameUI::drawObserverStats(Int& x, Int& y) static Int totalWidth = 0; static Int totalHeight = 0; + static bool isUpdating = false; + if (isUpdating) + return; + UnsignedInt currentFrame = TheGameLogic ? TheGameLogic->getFrame() : 0; Bool needUpdate = (lastUpdateFrame == 0) || (currentFrame - lastUpdateFrame >= LOGICFRAMES_PER_SECOND) || @@ -6032,6 +6045,7 @@ void InGameUI::drawObserverStats(Int& x, Int& y) // UPDATE: gather data, format strings, measure layout // ==================================================================== if (needUpdate) { + isUpdating = true; lastUpdateFrame = currentFrame; lastFontSize = TheWritableGlobalData->m_observerStatsFontSize; refreshObserverStatsResources(); @@ -6127,6 +6141,7 @@ void InGameUI::drawObserverStats(Int& x, Int& y) // Create Display Strings if (headerStrings.size() != numCols) { + freeDisplayStrings(headerStrings); headerStrings.clear(); for (Int i = 0; i < numCols; ++i) { DisplayString* ds = TheDisplayStringManager->newDisplayString(); @@ -6138,12 +6153,12 @@ void InGameUI::drawObserverStats(Int& x, Int& y) headerStrings[i]->setFont(m_observerStatsString->getFont()); headerStrings[i]->setText(headers[i]); } - + for (DisplayString* ds : cellStrings) { if (ds) TheDisplayStringManager->freeDisplayString(ds); } - cellStrings.clear(); + freeDisplayStrings(cellStrings); cellStrings.reserve(players.size() * numCols); for (const PlayerData& pd : players) { @@ -6163,6 +6178,13 @@ void InGameUI::drawObserverStats(Int& x, Int& y) for (Int i = 0; i < numCols; ++i) { DisplayString* ds = TheDisplayStringManager->newDisplayString(); + if (!ds) { + freeDisplayStrings(headerStrings); + freeDisplayStrings(cellStrings); + players.clear(); + isUpdating = false; + return; + } ds->setFont(m_observerStatsString->getFont()); ds->setText(cells[i]); cellStrings.push_back(ds); @@ -6193,11 +6215,15 @@ void InGameUI::drawObserverStats(Int& x, Int& y) Int lineHeight = (m_observerStatsLineStep > 0) ? m_observerStatsLineStep : Int(16 * scale); Int rowSpacing = Int(2 * scale); totalHeight = (lineHeight + rowSpacing) * (1 + Int(players.size())); + isUpdating = false; } if (players.empty()) return; + if (cellStrings.size() != players.size() * numCols) + return; + // ==================================================================== // DRAWINGS // ==================================================================== @@ -6668,3 +6694,4 @@ void InGameUI::drawGameTime() +