1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Reduce excessive updates of garrisons. Fixes selection reset in simturns

This commit is contained in:
Ivan Savenko 2023-11-09 00:01:48 +02:00
parent 8aea2be0db
commit 864462b84a
13 changed files with 111 additions and 24 deletions

View File

@ -499,8 +499,9 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
adventureInt->onHeroChanged(nullptr);
adventureInt->onTownChanged(town);
for (auto gh : GH.windows().findWindows<IGarrisonHolder>())
gh->updateGarrisons();
for (auto cgh : GH.windows().findWindows<IGarrisonHolder>())
if (cgh->holdsGarrison(town))
cgh->updateGarrisons();
for (auto ki : GH.windows().findWindows<CKingdomInterface>())
ki->townChanged(town);
@ -521,49 +522,42 @@ void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownIn
void CPlayerInterface::garrisonsChanged(ObjectInstanceID id1, ObjectInstanceID id2)
{
std::vector<const CGObjectInstance *> instances;
std::vector<const CArmedInstance *> instances;
if(auto obj = cb->getObj(id1))
if(auto obj = dynamic_cast<const CArmedInstance *>(cb->getObjInstance(id1)))
instances.push_back(obj);
if(id2 != ObjectInstanceID() && id2 != id1)
{
if(auto obj = cb->getObj(id2))
if(auto obj = dynamic_cast<const CArmedInstance *>(cb->getObjInstance(id2)))
instances.push_back(obj);
}
garrisonsChanged(instances);
}
void CPlayerInterface::garrisonsChanged(std::vector<const CGObjectInstance *> objs)
void CPlayerInterface::garrisonsChanged(std::vector<const CArmedInstance *> objs)
{
for (auto object : objs)
{
auto * hero = dynamic_cast<const CGHeroInstance*>(object);
auto * town = dynamic_cast<const CGTownInstance*>(object);
if (town)
adventureInt->onTownChanged(town);
if (hero)
{
adventureInt->onHeroChanged(hero);
if(hero->inTownGarrison)
{
if(hero->inTownGarrison && hero->visitedTown != town)
adventureInt->onTownChanged(hero->visitedTown);
}
}
if (town)
adventureInt->onTownChanged(town);
}
for (auto cgh : GH.windows().findWindows<IGarrisonHolder>())
cgh->updateGarrisons();
for (auto cmw : GH.windows().findWindows<CAltarWindow>())
{
if(vstd::contains(objs, cmw->getHero()))
cmw->updateGarrison();
}
if (cgh->holdsGarrisons(objs))
cgh->updateGarrisons();
GH.windows().totalRedraw();
}

View File

@ -223,7 +223,7 @@ private:
};
void heroKilled(const CGHeroInstance* hero);
void garrisonsChanged(std::vector<const CGObjectInstance *> objs);
void garrisonsChanged(std::vector<const CArmedInstance *> objs);
void requestReturningToMainMenu(bool won);
void acceptTurn(QueryID queryID); //used during hot seat after your turn message is close
void initializeHeroTownList();

View File

@ -19,6 +19,10 @@ class CGuiHandler;
class CPicture;
class Canvas;
VCMI_LIB_NAMESPACE_BEGIN
class CArmedInstance;
VCMI_LIB_NAMESPACE_BEGIN
class IUpdateable
{
public:
@ -150,6 +154,15 @@ protected:
class IGarrisonHolder
{
public:
bool holdsGarrisons(std::vector<const CArmedInstance *> armies)
{
for (auto const * army : armies)
if (holdsGarrison(army))
return true;
return false;
}
virtual bool holdsGarrison(const CArmedInstance * army) = 0;
virtual void updateGarrisons() = 0;
};

View File

@ -45,12 +45,17 @@ void CAltarWindow::updateExpToLevel()
altar->expToLevel->setText(std::to_string(CGI->heroh->reqExp(CGI->heroh->level(altar->hero->exp) + 1) - altar->hero->exp));
}
void CAltarWindow::updateGarrison()
void CAltarWindow::updateGarrisons()
{
if(auto altarCreatures = std::static_pointer_cast<CAltarCreatures>(altar))
altarCreatures->updateGarrison();
}
bool CAltarWindow::holdsGarrison(const CArmedInstance * army)
{
return hero == army;
}
const CGHeroInstance * CAltarWindow::getHero() const
{
return hero;

View File

@ -13,12 +13,13 @@
#include "../widgets/CWindowWithArtifacts.h"
#include "CWindowObject.h"
class CAltarWindow : public CWindowObject, public CWindowWithArtifacts
class CAltarWindow : public CWindowObject, public CWindowWithArtifacts, public IGarrisonHolder
{
public:
CAltarWindow(const IMarket * market, const CGHeroInstance * hero, const std::function<void()> & onWindowClosed, EMarketMode mode);
void updateExpToLevel();
void updateGarrison();
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
const CGHeroInstance * getHero() const;
void close() override;

View File

@ -1262,6 +1262,11 @@ void CCastleInterface::updateGarrisons()
redraw();
}
bool CCastleInterface::holdsGarrison(const CArmedInstance * army)
{
return army == town || army == town->getUpperArmy() || army == town->visitingHero;
}
void CCastleInterface::close()
{
if(town->tempOwner == LOCPLINT->playerID) //we may have opened window for an allied town

View File

@ -249,7 +249,8 @@ public:
CCastleInterface(const CGTownInstance * Town, const CGTownInstance * from = nullptr);
~CCastleInterface();
virtual void updateGarrisons() override;
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
void castleTeleport(int where);
void townChange();

View File

@ -353,3 +353,8 @@ void CHeroWindow::updateGarrisons()
garr->recreateSlots();
morale->set(curHero);
}
bool CHeroWindow::holdsGarrison(const CArmedInstance * army)
{
return army == curHero;
}

View File

@ -107,6 +107,7 @@ public:
void commanderWindow();
void switchHero(); //changes displayed hero
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
void createBackpackWindow();
//friends

View File

@ -662,6 +662,11 @@ void CKingdomInterface::updateGarrisons()
garrison->updateGarrisons();
}
bool CKingdomInterface::holdsGarrison(const CArmedInstance * army)
{
return army->getOwner() == LOCPLINT->playerID;
}
void CKingdomInterface::artifactAssembled(const ArtifactLocation& artLoc)
{
if(auto arts = std::dynamic_pointer_cast<CArtifactHolder>(tabArea->getItem()))
@ -709,6 +714,15 @@ void CKingdHeroList::updateGarrisons()
}
}
bool CKingdHeroList::holdsGarrison(const CArmedInstance * army)
{
for(std::shared_ptr<CIntObject> object : heroes->getItems())
if(IGarrisonHolder * garrison = dynamic_cast<IGarrisonHolder*>(object.get()))
if (garrison->holdsGarrison(army))
return true;
return false;
}
std::shared_ptr<CIntObject> CKingdHeroList::createHeroItem(size_t index)
{
ui32 picCount = 4; // OVSLOT contains 4 images
@ -761,6 +775,15 @@ void CKingdTownList::updateGarrisons()
}
}
bool CKingdTownList::holdsGarrison(const CArmedInstance * army)
{
for(std::shared_ptr<CIntObject> object : towns->getItems())
if(IGarrisonHolder * garrison = dynamic_cast<IGarrisonHolder*>(object.get()))
if (garrison->holdsGarrison(army))
return true;
return false;
}
std::shared_ptr<CIntObject> CKingdTownList::createTownItem(size_t index)
{
ui32 picCount = 4; // OVSLOT contains 4 images
@ -836,6 +859,11 @@ void CTownItem::updateGarrisons()
garr->recreateSlots();
}
bool CTownItem::holdsGarrison(const CArmedInstance * army)
{
return army == town || army == town->getUpperArmy() || army == town->visitingHero;
}
void CTownItem::update()
{
std::string incomeVal = std::to_string(town->dailyIncome()[EGameResID::GOLD]);
@ -998,6 +1026,11 @@ void CHeroItem::updateGarrisons()
garr->recreateSlots();
}
bool CHeroItem::holdsGarrison(const CArmedInstance * army)
{
return hero == army;
}
std::shared_ptr<CIntObject> CHeroItem::onTabSelected(size_t index)
{
return artTabs.at(index);

View File

@ -253,6 +253,7 @@ public:
void townChanged(const CGTownInstance *town);
void heroRemoved();
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
void artifactRemoved(const ArtifactLocation &artLoc) override;
void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc, bool withRedraw) override;
void artifactDisassembled(const ArtifactLocation &artLoc) override;
@ -290,6 +291,7 @@ public:
CTownItem(const CGTownInstance * Town);
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
void update();
};
@ -322,6 +324,7 @@ public:
std::shared_ptr<CArtifactsOfHeroKingdom> heroArts;
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
CHeroItem(const CGHeroInstance * hero);
};
@ -340,6 +343,7 @@ public:
CKingdHeroList(size_t maxSize);
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
};
/// Tab with all town-specific data
@ -358,4 +362,5 @@ public:
void townChanged(const CGTownInstance * town);
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
};

View File

@ -861,6 +861,11 @@ void CExchangeWindow::updateGarrisons()
updateWidgets();
}
bool CExchangeWindow::holdsGarrison(const CArmedInstance * army)
{
return garr->upperArmy() == army || garr->lowerArmy() == army;
}
void CExchangeWindow::questlog(int whichHero)
{
CCS->curh->dragAndDropCursor(nullptr);
@ -1008,6 +1013,11 @@ void CTransformerWindow::updateGarrisons()
item->update();
}
bool CTransformerWindow::holdsGarrison(const CArmedInstance * army)
{
return army == hero;
}
CTransformerWindow::CTransformerWindow(const IMarket * _market, const CGHeroInstance * _hero, const std::function<void()> & onWindowClosed)
: CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("SKTRNBK")),
hero(_hero),
@ -1251,6 +1261,11 @@ void CGarrisonWindow::updateGarrisons()
garr->recreateSlots();
}
bool CGarrisonWindow::holdsGarrison(const CArmedInstance * army)
{
return garr->upperArmy() == army || garr->lowerArmy() == army;
}
CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectInstance * object)
: CStatusbarWindow(PLAYER_COLORED, ImagePath::builtin("APHLFTBK")),
fort(object),
@ -1292,6 +1307,11 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance * visitor, const CGObjectI
updateGarrisons();
}
bool CHillFortWindow::holdsGarrison(const CArmedInstance * army)
{
return hero == army;
}
void CHillFortWindow::updateGarrisons()
{
std::array<TResources, slotsCount> costs;// costs [slot ID] [resource ID] = resource count for upgrade

View File

@ -290,6 +290,7 @@ public:
std::array<std::shared_ptr<CArtifactsOfHeroMain>, 2> artifs;
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right
@ -362,6 +363,7 @@ public:
void addAll();
void close() override;
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
CTransformerWindow(const IMarket * _market, const CGHeroInstance * _hero, const std::function<void()> & onWindowClosed);
};
@ -443,6 +445,7 @@ public:
CGarrisonWindow(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits);
void updateGarrisons() override;
bool holdsGarrison(const CArmedInstance * army) override;
};
/// Hill fort is the building where you can upgrade units
@ -482,6 +485,7 @@ private:
public:
CHillFortWindow(const CGHeroInstance * visitor, const CGObjectInstance * object);
void updateGarrisons() override;//update buttons after garrison changes
bool holdsGarrison(const CArmedInstance * army) override;
};
class CThievesGuildWindow : public CStatusbarWindow