Codechange: Defer refreshing company finance windows. (#14111)

During each game tick every cargo payment will issue an Invalidate of the status bar and company finance window. While this doesn't paint the window yet, it does need to search for open windows, and then mark a area of dirty blocks, which is done for every Invalidate.

Instead, set a bit in a CompanyMask, and test these bits once after the game tick is complete.

This reduces the amount of dirtying, and allows more specific widgets to be dirtied instead of the whole window.
This commit is contained in:
Peter Nelson 2025-04-26 11:50:51 +01:00 committed by GitHub
parent a1f086e60c
commit dfd9fbf873
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 25 additions and 3 deletions

View File

@ -203,16 +203,34 @@ static bool IsValidCompanyManagerFace(CompanyManagerFace cmf)
return true;
}
static CompanyMask _dirty_company_finances{}; ///< Bitmask of compamy finances that should be marked dirty.
/**
* Refresh all windows owned by a company.
* Mark all finance windows owned by a company as needing a refresh.
* The actual refresh is deferred until the end of the gameloop to reduce duplicated work.
* @param company Company that changed, and needs its windows refreshed.
*/
void InvalidateCompanyWindows(const Company *company)
{
CompanyID cid = company->index;
_dirty_company_finances.Set(cid);
}
if (cid == _local_company) SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_RIGHT);
SetWindowDirty(WC_FINANCES, cid);
/**
* Refresh all company finance windows previously marked dirty.
*/
void InvalidateCompanyWindows()
{
for (CompanyID cid : _dirty_company_finances) {
if (cid == _local_company) SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_RIGHT);
Window *w = FindWindowById(WC_FINANCES, cid);
if (w != nullptr) {
w->SetWidgetDirty(WID_CF_EXPS_PRICE3);
w->SetWidgetDirty(WID_CF_OWN_VALUE);
w->SetWidgetDirty(WID_CF_BALANCE_VALUE);
}
}
_dirty_company_finances = {};
}
/**

View File

@ -23,6 +23,7 @@ void ShowCompanyFinances(CompanyID company);
void ShowCompany(CompanyID company);
void InvalidateCompanyWindows(const Company *c);
void InvalidateCompanyWindows();
void CloseCompanyWindows(CompanyID company);
void DirtyCompanyInfrastructureWindows(CompanyID company);

View File

@ -27,6 +27,7 @@
#include "saveload/saveload.h"
#include "company_cmd.h"
#include "company_func.h"
#include "company_gui.h"
#include "command_func.h"
#include "news_func.h"
#include "fios.h"
@ -1229,6 +1230,7 @@ void StateGameLoop()
CallWindowGameTickEvent();
NewsLoop();
InvalidateCompanyWindows();
} else {
if (_debug_desync_level > 2 && TimerGameEconomy::date_fract == 0 && (TimerGameEconomy::date.base() & 0x1F) == 0) {
/* Save the desync savegame if needed. */
@ -1265,6 +1267,7 @@ void StateGameLoop()
CallWindowGameTickEvent();
NewsLoop();
InvalidateCompanyWindows();
cur_company.Restore();
}