From ad3e54e6c0c30322d8f8122e5b279431f85c5f98 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 16 May 2023 18:34:23 +0300 Subject: [PATCH] Reduced usage of topWindow() method --- client/CPlayerInterface.cpp | 33 +++++++---------- client/CServerHandler.cpp | 3 +- client/Client.cpp | 5 +-- client/adventureMap/AdventureMapInterface.cpp | 10 ++--- client/adventureMap/CInGameConsole.cpp | 7 ++-- client/adventureMap/CInfoBar.cpp | 6 +-- client/adventureMap/CList.cpp | 4 +- client/adventureMap/CMinimap.cpp | 4 +- client/battle/BattleActionsController.cpp | 12 +++--- client/battle/BattleInterfaceClasses.cpp | 2 +- client/battle/BattleWindow.cpp | 5 ++- client/gui/CGuiHandler.cpp | 17 ++++++++- client/gui/CGuiHandler.h | 13 ++++++- client/gui/CIntObject.cpp | 2 +- client/gui/CIntObject.h | 9 +++++ client/gui/WindowHandler.cpp | 17 ++++++++- client/gui/WindowHandler.h | 20 ++++++++-- client/lobby/RandomMapTab.cpp | 16 ++++---- client/mainmenu/CMainMenu.cpp | 8 ++-- client/mapView/MapViewActions.cpp | 2 +- client/mapView/MapViewController.cpp | 4 +- client/renderSDL/ScreenHandler.cpp | 1 - client/widgets/Buttons.cpp | 8 ++-- client/widgets/CGarrisonInt.cpp | 6 +-- client/widgets/MiscWidgets.cpp | 8 ++-- client/widgets/TextControls.cpp | 9 ++--- client/windows/CCastleInterface.cpp | 37 ++++++++++--------- client/windows/CTradeWindow.cpp | 8 ++-- client/windows/GUIClasses.cpp | 8 ++-- .../windows/settings/SettingsMainWindow.cpp | 2 +- 30 files changed, 171 insertions(+), 115 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index 0c2d37a11..591869bae 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -178,7 +178,7 @@ void CPlayerInterface::playerStartsTurn(PlayerColor player) } // remove all dialogs that do not expect query answer - while (GH.windows().topWindow() != adventureInt && !dynamic_cast(GH.windows().topWindow().get())) + while (!GH.windows().topWindow() && !GH.windows().topWindow()) GH.windows().popWindows(1); if (player != playerID && LOCPLINT == this) @@ -247,7 +247,7 @@ void CPlayerInterface::acceptTurn() { if (settings["session"]["autoSkip"].Bool()) { - while(CInfoWindow *iw = dynamic_cast(GH.windows().topWindow().get())) + while(auto iw = GH.windows().topWindow()) iw->close(); } @@ -449,7 +449,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int EVENT_HANDLER_CALLED_BY_CLIENT; if (which == 4) { - if (CAltarWindow *ctw = dynamic_cast(GH.windows().topWindow().get())) + for (auto ctw : GH.windows().findWindows()) ctw->setExpToLevel(); } else @@ -459,11 +459,8 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int void CPlayerInterface::heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) { EVENT_HANDLER_CALLED_BY_CLIENT; - CUniversityWindow* cuw = dynamic_cast(GH.windows().topWindow().get()); - if (cuw) //university window is open - { - GH.windows().totalRedraw(); - } + for (auto cuw : GH.windows().findWindows()) + cuw->redraw(); } void CPlayerInterface::heroManaPointsChanged(const CGHeroInstance * hero) @@ -482,7 +479,7 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero) void CPlayerInterface::receivedResource() { EVENT_HANDLER_CALLED_BY_CLIENT; - if (CMarketplaceWindow *mw = dynamic_cast(GH.windows().topWindow().get())) + for (auto mw : GH.windows().findWindows()) mw->resourceChanged(); GH.windows().totalRedraw(); @@ -1193,12 +1190,10 @@ void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town ) EVENT_HANDLER_CALLED_BY_CLIENT; if (const CGTownInstance * townObj = dynamic_cast(town)) { - CFortScreen * fortScreen = dynamic_cast(GH.windows().topWindow().get()); - CCastleInterface * castleInterface = dynamic_cast(GH.windows().topWindow().get()); - - if (fortScreen) + for (auto fortScreen : GH.windows().findWindows()) fortScreen->creaturesChangedEventHandler(); - else if(castleInterface) + + for (auto castleInterface : GH.windows().findWindows()) castleInterface->creaturesChangedEventHandler(); if (townObj) @@ -1208,9 +1203,9 @@ void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town ) else if(town && GH.windows().count() > 0 && (town->ID == Obj::CREATURE_GENERATOR1 || town->ID == Obj::CREATURE_GENERATOR4 || town->ID == Obj::WAR_MACHINE_FACTORY)) { - CRecruitmentWindow *crw = dynamic_cast(GH.windows().topWindow().get()); - if (crw && crw->dwelling == town) - crw->availableCreaturesChanged(); + for (auto crw : GH.windows().findWindows()) + if (crw->dwelling == town) + crw->availableCreaturesChanged(); } } @@ -1644,7 +1639,7 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI { EVENT_HANDLER_CALLED_BY_CLIENT; - if(dynamic_cast(GH.windows().topWindow().get())) + if(GH.windows().topWindow()) GH.windows().popWindows(1); if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK) @@ -1731,7 +1726,7 @@ void CPlayerInterface::showHillFortWindow(const CGObjectInstance *object, const void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket * bm) { EVENT_HANDLER_CALLED_BY_CLIENT; - if (CMarketplaceWindow *cmw = dynamic_cast(GH.windows().topWindow().get())) + for (auto cmw : GH.windows().findWindows()) cmw->artifactsChanged(false); } diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index 616c4c9b1..32d5d6f41 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -750,8 +750,9 @@ void CServerHandler::debugStartTest(std::string filename, bool save) boost::this_thread::sleep(boost::posix_time::milliseconds(100)); - while(!settings["session"]["headless"].Bool() && !dynamic_cast(GH.windows().topWindow().get())) + while(!settings["session"]["headless"].Bool() && !GH.windows().topWindow()) boost::this_thread::sleep(boost::posix_time::milliseconds(50)); + while(!mi || mapInfo->fileURI != CSH->mi->fileURI) { setMapInfo(mapInfo); diff --git a/client/Client.cpp b/client/Client.cpp index 59be570da..a6f359070 100644 --- a/client/Client.cpp +++ b/client/Client.cpp @@ -767,11 +767,8 @@ void CClient::removeGUI() { // CClient::endGame GH.curInt = nullptr; - if(GH.windows().topWindow()) - GH.windows().topWindow()->deactivate(); - adventureInt.reset(); GH.windows().clear(); - GH.statusbar.reset(); + adventureInt.reset(); logGlobal->info("Removed GUI."); LOCPLINT = nullptr; diff --git a/client/adventureMap/AdventureMapInterface.cpp b/client/adventureMap/AdventureMapInterface.cpp index 8be66a0a9..7ba8c1fce 100644 --- a/client/adventureMap/AdventureMapInterface.cpp +++ b/client/adventureMap/AdventureMapInterface.cpp @@ -396,7 +396,7 @@ void AdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID) if(settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown()) { - if(CInfoWindow *iw = dynamic_cast(GH.windows().topWindow().get())) + if(auto iw = GH.windows().topWindow()) iw->close(); hotkeyEndingTurn(); @@ -528,7 +528,7 @@ void AdventureMapInterface::onTileHovered(const int3 &mapPos) if(!LOCPLINT->cb->isVisible(mapPos)) { CCS->curh->set(Cursor::Map::POINTER); - GH.statusbar->clear(); + GH.statusbar()->clear(); return; } auto objRelations = PlayerRelations::ALLIES; @@ -538,12 +538,12 @@ void AdventureMapInterface::onTileHovered(const int3 &mapPos) objRelations = LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner); std::string text = LOCPLINT->localState->getCurrentHero() ? objAtTile->getHoverText(LOCPLINT->localState->getCurrentHero()) : objAtTile->getHoverText(LOCPLINT->playerID); boost::replace_all(text,"\n"," "); - GH.statusbar->write(text); + GH.statusbar()->write(text); } else { std::string hlp = CGI->mh->getTerrainDescr(mapPos, false); - GH.statusbar->write(hlp); + GH.statusbar()->write(hlp); } if(spellBeingCasted) @@ -680,7 +680,7 @@ void AdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & he boost::replace_first(result, "%POINTS", std::to_string(movementPointsLastTurnCost)); boost::replace_first(result, "%REMAINING", std::to_string(remainingPointsAfterMove)); - GH.statusbar->write(result); + GH.statusbar()->write(result); } void AdventureMapInterface::onTileRightClicked(const int3 &mapPos) diff --git a/client/adventureMap/CInGameConsole.cpp b/client/adventureMap/CInGameConsole.cpp index 18a2b61bd..755e41760 100644 --- a/client/adventureMap/CInGameConsole.cpp +++ b/client/adventureMap/CInGameConsole.cpp @@ -217,16 +217,15 @@ void CInGameConsole::startEnteringText() if (captureAllKeys) return; - assert(GH.statusbar); assert(currentStatusBar.expired());//effectively, nullptr check - currentStatusBar = GH.statusbar; + currentStatusBar = GH.statusbar(); captureAllKeys = true; enteredText = "_"; - GH.statusbar->setEnteringMode(true); - GH.statusbar->setEnteredText(enteredText); + GH.statusbar()->setEnteringMode(true); + GH.statusbar()->setEnteredText(enteredText); } void CInGameConsole::endEnteringText(bool processEnteredText) diff --git a/client/adventureMap/CInfoBar.cpp b/client/adventureMap/CInfoBar.cpp index 6db026249..a86a368b7 100644 --- a/client/adventureMap/CInfoBar.cpp +++ b/client/adventureMap/CInfoBar.cpp @@ -262,7 +262,7 @@ void CInfoBar::tick(uint32_t msPassed) { timerCounter = 0; removeUsedEvents(TIME); - if(GH.windows().topWindow() == adventureInt) + if(GH.windows().isTopWindow(adventureInt)) popComponents(true); } else @@ -293,9 +293,9 @@ void CInfoBar::clickRight(tribool down, bool previousState) void CInfoBar::hover(bool on) { if(on) - GH.statusbar->write(CGI->generaltexth->zelp[292].first); + GH.statusbar()->write(CGI->generaltexth->zelp[292].first); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } CInfoBar::CInfoBar(const Rect & position) diff --git a/client/adventureMap/CList.cpp b/client/adventureMap/CList.cpp index 1923895c2..3a44a8f83 100644 --- a/client/adventureMap/CList.cpp +++ b/client/adventureMap/CList.cpp @@ -68,9 +68,9 @@ void CList::CListItem::clickLeft(tribool down, bool previousState) void CList::CListItem::hover(bool on) { if (on) - GH.statusbar->write(getHoverText()); + GH.statusbar()->write(getHoverText()); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } void CList::CListItem::onSelect(bool on) diff --git a/client/adventureMap/CMinimap.cpp b/client/adventureMap/CMinimap.cpp index 064d7d525..1813626d8 100644 --- a/client/adventureMap/CMinimap.cpp +++ b/client/adventureMap/CMinimap.cpp @@ -152,9 +152,9 @@ void CMinimap::clickRight(tribool down, bool previousState) void CMinimap::hover(bool on) { if(on) - GH.statusbar->write(CGI->generaltexth->zelp[291].first); + GH.statusbar()->write(CGI->generaltexth->zelp[291].first); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } void CMinimap::mouseMoved(const Point & cursorPosition) diff --git a/client/battle/BattleActionsController.cpp b/client/battle/BattleActionsController.cpp index 5820390fb..9bfa50a09 100644 --- a/client/battle/BattleActionsController.cpp +++ b/client/battle/BattleActionsController.cpp @@ -773,7 +773,7 @@ void BattleActionsController::onHexHovered(BattleHex hoveredHex) if (owner.openingPlaying()) { currentConsoleMsg = VLC->generaltexth->translate("vcmi.battleWindow.pressKeyToSkipIntro"); - GH.statusbar->write(currentConsoleMsg); + GH.statusbar()->write(currentConsoleMsg); return; } @@ -783,7 +783,7 @@ void BattleActionsController::onHexHovered(BattleHex hoveredHex) if (hoveredHex == BattleHex::INVALID) { if (!currentConsoleMsg.empty()) - GH.statusbar->clearIfMatching(currentConsoleMsg); + GH.statusbar()->clearIfMatching(currentConsoleMsg); currentConsoleMsg.clear(); CCS->curh->set(Cursor::Combat::BLOCKED); @@ -806,10 +806,10 @@ void BattleActionsController::onHexHovered(BattleHex hoveredHex) } if (!currentConsoleMsg.empty()) - GH.statusbar->clearIfMatching(currentConsoleMsg); + GH.statusbar()->clearIfMatching(currentConsoleMsg); if (!newConsoleMsg.empty()) - GH.statusbar->write(newConsoleMsg); + GH.statusbar()->write(newConsoleMsg); currentConsoleMsg = newConsoleMsg; } @@ -819,7 +819,7 @@ void BattleActionsController::onHoverEnded() CCS->curh->set(Cursor::Combat::POINTER); if (!currentConsoleMsg.empty()) - GH.statusbar->clearIfMatching(currentConsoleMsg); + GH.statusbar()->clearIfMatching(currentConsoleMsg); currentConsoleMsg.clear(); } @@ -850,7 +850,7 @@ void BattleActionsController::onHexLeftClicked(BattleHex clickedHex) { actionRealize(action, clickedHex); - GH.statusbar->clear(); + GH.statusbar()->clear(); } else { diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 6e0af1edf..ca6f01230 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -592,7 +592,7 @@ void BattleResultWindow::buttonPressed(int button) close(); - if(dynamic_cast(GH.windows().topWindow().get())) + if(GH.windows().topWindow()) GH.windows().popWindows(1); //pop battle interface if present //Result window and battle interface are gone. We requested all dialogs to be closed before opening the battle, diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index d3ae49844..a86463bf2 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -176,13 +176,14 @@ void BattleWindow::updateQueue() void BattleWindow::activate() { - GH.statusbar = console; + GH.setStatusbar(console); CIntObject::activate(); LOCPLINT->cingconsole->activate(); } void BattleWindow::deactivate() { + GH.setStatusbar(nullptr); CIntObject::deactivate(); LOCPLINT->cingconsole->deactivate(); } @@ -570,7 +571,7 @@ void BattleWindow::show(SDL_Surface *to) void BattleWindow::close() { - if(GH.windows().topWindow().get() != this) + if(!GH.windows().isTopWindow(this)) logGlobal->error("Only top interface must be closed"); GH.windows().popWindows(1); } diff --git a/client/gui/CGuiHandler.cpp b/client/gui/CGuiHandler.cpp index 3bfc97905..e71673e68 100644 --- a/client/gui/CGuiHandler.cpp +++ b/client/gui/CGuiHandler.cpp @@ -631,7 +631,7 @@ CGuiHandler::CGuiHandler() , mouseButtonsMask(0) , continueEventHandling(true) , curInt(nullptr) - , statusbar(nullptr) + , fakeStatusBar(std::make_shared()) , terminate_cond (new CondSh(false)) { } @@ -748,6 +748,21 @@ WindowHandler & CGuiHandler::windows() return *windowHandlerInstance; } +std::shared_ptr CGuiHandler::statusbar() +{ + auto locked = currentStatusBar.lock(); + + if (!locked) + return fakeStatusBar; + + return locked; +} + +void CGuiHandler::setStatusbar(std::shared_ptr newStatusBar) +{ + currentStatusBar = newStatusBar; +} + void CGuiHandler::onScreenResize() { screenHandler().onScreenResize(); diff --git a/client/gui/CGuiHandler.h b/client/gui/CGuiHandler.h index eb0a638b4..a7e296f46 100644 --- a/client/gui/CGuiHandler.h +++ b/client/gui/CGuiHandler.h @@ -50,9 +50,14 @@ class CGuiHandler { public: - std::shared_ptr statusbar; private: + /// Fake no-op version status bar, for use in windows that have no status bar + std::shared_ptr fakeStatusBar; + + /// Status bar of current window, if any. Uses weak_ptr to allow potential hanging reference after owned window has been deleted + std::weak_ptr currentStatusBar; + Point cursorPosition; uint32_t mouseButtonsMask; @@ -122,6 +127,12 @@ public: WindowHandler & windows(); + /// Returns currently active status bar. Guaranteed to be non-null + std::shared_ptr statusbar(); + + /// Set currently active status bar + void setStatusbar(std::shared_ptr); + IUpdateable *curInt; Point lastClick; diff --git a/client/gui/CIntObject.cpp b/client/gui/CIntObject.cpp index 660a2f289..6dfc3f804 100644 --- a/client/gui/CIntObject.cpp +++ b/client/gui/CIntObject.cpp @@ -357,7 +357,7 @@ WindowBase::WindowBase(int used_, Point pos_) void WindowBase::close() { - if(GH.windows().topWindow().get() != this) + if(!GH.windows().isTopWindow(this)) logGlobal->error("Only top interface must be closed"); GH.windows().popWindows(1); } diff --git a/client/gui/CIntObject.h b/client/gui/CIntObject.h index d92eee609..f95b73f92 100644 --- a/client/gui/CIntObject.h +++ b/client/gui/CIntObject.h @@ -231,3 +231,12 @@ public: virtual void setEnteredText(const std::string & text) = 0; }; + +class EmptyStatusBar : public IStatusBar +{ + virtual void write(const std::string & text){}; + virtual void clear(){}; + virtual void clearIfMatching(const std::string & testedText){}; + virtual void setEnteringMode(bool on){}; + virtual void setEnteredText(const std::string & text){}; +}; diff --git a/client/gui/WindowHandler.cpp b/client/gui/WindowHandler.cpp index 5d80a6e9c..6f021ed03 100644 --- a/client/gui/WindowHandler.cpp +++ b/client/gui/WindowHandler.cpp @@ -68,7 +68,7 @@ void WindowHandler::popWindows(int howMany) GH.fakeMouseMove(); } -std::shared_ptr WindowHandler::topWindow() const +std::shared_ptr WindowHandler::topWindowImpl() const { if(windowsStack.empty()) return nullptr; @@ -76,6 +76,18 @@ std::shared_ptr WindowHandler::topWindow() const return windowsStack.back(); } +bool WindowHandler::isTopWindow(std::shared_ptr window) const +{ + assert(window != nullptr); + return !windowsStack.empty() && windowsStack.back() == window; +} + +bool WindowHandler::isTopWindow(IShowActivatable * window) const +{ + assert(window != nullptr); + return !windowsStack.empty() && windowsStack.back().get() == window; +} + void WindowHandler::totalRedraw() { CSDL_Ext::fillSurface(screen2, Colors::BLACK); @@ -118,6 +130,9 @@ size_t WindowHandler::count() const void WindowHandler::clear() { + if(!windowsStack.empty()) + windowsStack.back()->deactivate(); + windowsStack.clear(); disposed.clear(); } diff --git a/client/gui/WindowHandler.h b/client/gui/WindowHandler.h index feab2a165..56810740e 100644 --- a/client/gui/WindowHandler.h +++ b/client/gui/WindowHandler.h @@ -20,6 +20,9 @@ class WindowHandler /// Temporary list of recently popped windows std::vector> disposed; + /// returns top windows + std::shared_ptr topWindowImpl() const; + public: /// forces total redraw (using showAll), sets a flag, method gets called at the end of the rendering void totalRedraw(); @@ -43,8 +46,13 @@ public: /// removes given windows from the top and activates next void popWindow(std::shared_ptr top); - /// returns top windows - std::shared_ptr topWindow() const; + /// returns true if selected interface is on top + bool isTopWindow(std::shared_ptr window) const; + bool isTopWindow(IShowActivatable * window) const; + + /// returns top window if it matches requested class + template + std::shared_ptr topWindow() const; /// should be called after frame has been rendered to screen void onFrameRendered(); @@ -72,7 +80,7 @@ std::vector> WindowHandler::findWindows() const { std::vector> result; - for (auto const & window : windowsStack) + for(const auto & window : windowsStack) { std::shared_ptr casted = std::dynamic_pointer_cast(window); @@ -81,3 +89,9 @@ std::vector> WindowHandler::findWindows() const } return result; } + +template +std::shared_ptr WindowHandler::topWindow() const +{ + return std::dynamic_pointer_cast(topWindowImpl()); +} diff --git a/client/lobby/RandomMapTab.cpp b/client/lobby/RandomMapTab.cpp index 87538ab03..02b3daa6b 100644 --- a/client/lobby/RandomMapTab.cpp +++ b/client/lobby/RandomMapTab.cpp @@ -483,8 +483,8 @@ void TemplatesDropBox::clickLeft(tribool down, bool previousState) // pop the interface only if the mouse is not clicking on the slider if (!w || !w->mouseState(MouseButton::LEFT)) { - assert(GH.windows().topWindow().get() == this); - GH.windows().popWindow(GH.windows().topWindow()); + assert(GH.windows().isTopWindow(this)); + GH.windows().popWindows(1); } } } @@ -512,8 +512,8 @@ void TemplatesDropBox::updateListItems() void TemplatesDropBox::setTemplate(const CRmgTemplate * tmpl) { randomMapTab.setTemplate(tmpl); - assert(GH.windows().topWindow().get() == this); - GH.windows().popWindow(GH.windows().topWindow()); + assert(GH.windows().isTopWindow(this)); + GH.windows().popWindows(1); } TeamAlignmentsWidget::TeamAlignmentsWidget(RandomMapTab & randomMapTab): @@ -548,14 +548,14 @@ TeamAlignmentsWidget::TeamAlignmentsWidget(RandomMapTab & randomMapTab): randomMapTab.obtainMapGenOptions().setPlayerTeam(PlayerColor(plId), TeamID(players[plId]->getSelected())); } randomMapTab.updateMapInfoByHost(); - assert(GH.windows().topWindow().get() == this); - GH.windows().popWindow(GH.windows().topWindow()); + assert(GH.windows().isTopWindow(this)); + GH.windows().popWindows(1); }); addCallback("cancel", [&](int) { - assert(GH.windows().topWindow().get() == this); - GH.windows().popWindow(GH.windows().topWindow()); + assert(GH.windows().isTopWindow(this)); + GH.windows().popWindows(1); }); build(config); diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index 4b0d353c8..4aae6ca67 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -338,8 +338,8 @@ void CMainMenu::update() // check for null othervice crash on finishing a campaign // /FIXME: find out why GH.windows().listInt is empty to begin with - if(GH.windows().topWindow()) - GH.windows().topWindow()->show(screen); + if(GH.windows().topWindow()) + GH.windows().topWindow()->show(screen); } void CMainMenu::openLobby(ESelectionScreen screenType, bool host, const std::vector * names, ELoadMode loadMode) @@ -523,7 +523,7 @@ void CSimpleJoinScreen::leaveScreen() textTitle->setText("Closing..."); CSH->state = EClientState::CONNECTION_CANCELLED; } - else if(GH.windows().topWindow().get() == this) + else if(GH.windows().isTopWindow(this)) { close(); } @@ -553,7 +553,7 @@ void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port) else CSH->justConnectToServer(addr, port); - if(GH.windows().topWindow().get() == this) + if(GH.windows().isTopWindow(this)) { close(); } diff --git a/client/mapView/MapViewActions.cpp b/client/mapView/MapViewActions.cpp index 5b44b7a80..024cd3588 100644 --- a/client/mapView/MapViewActions.cpp +++ b/client/mapView/MapViewActions.cpp @@ -154,7 +154,7 @@ void MapViewActions::hover(bool on) { if(!on) { - GH.statusbar->clear(); + GH.statusbar()->clear(); CCS->curh->set(Cursor::Map::POINTER); } } diff --git a/client/mapView/MapViewController.cpp b/client/mapView/MapViewController.cpp index e648de3b6..0e34f87ab 100644 --- a/client/mapView/MapViewController.cpp +++ b/client/mapView/MapViewController.cpp @@ -209,7 +209,7 @@ bool MapViewController::isEventVisible(const CGObjectInstance * obj) if(!LOCPLINT->makingTurn && settings["adventure"]["enemyMoveTime"].Float() < 0) return false; // enemy move speed set to "hidden/none" - if(GH.windows().topWindow() != adventureInt) + if(!GH.windows().isTopWindow(adventureInt)) return false; if(obj->isVisitable()) @@ -226,7 +226,7 @@ bool MapViewController::isEventVisible(const CGHeroInstance * obj, const int3 & if(!LOCPLINT->makingTurn && settings["adventure"]["enemyMoveTime"].Float() < 0) return false; // enemy move speed set to "hidden/none" - if(GH.windows().topWindow() != adventureInt) + if(!GH.windows().isTopWindow(adventureInt)) return false; if(context->isVisible(obj->convertToVisitablePos(from))) diff --git a/client/renderSDL/ScreenHandler.cpp b/client/renderSDL/ScreenHandler.cpp index d1e62cff9..9709575eb 100644 --- a/client/renderSDL/ScreenHandler.cpp +++ b/client/renderSDL/ScreenHandler.cpp @@ -330,7 +330,6 @@ SDL_Window * ScreenHandler::createWindow() void ScreenHandler::onScreenResize() { recreateWindowAndScreenBuffers(); - GH.onScreenResize(); } void ScreenHandler::validateSettings() diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 395f13d71..3413996fd 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -218,9 +218,9 @@ void CButton::hover (bool on) if(!name.empty() && !isBlocked()) //if there is no name, there is nothing to display also { if (on) - GH.statusbar->write(name); + GH.statusbar()->write(name); else - GH.statusbar->clearIfMatching(name); + GH.statusbar()->clearIfMatching(name); } } @@ -532,8 +532,8 @@ void CVolumeSlider::clickRight(tribool down, bool previousState) if(!helpBox.empty()) CRClickPopup::createAndPush(helpBox); - if(GH.statusbar) - GH.statusbar->write(helpBox); + + GH.statusbar()->write(helpBox); } } diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 9c7ce8147..91eeca254 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -116,11 +116,11 @@ void CGarrisonSlot::hover (bool on) temp = CGI->generaltexth->tcommands[11]; //Empty } } - GH.statusbar->write(temp); + GH.statusbar()->write(temp); } else { - GH.statusbar->clear(); + GH.statusbar()->clear(); } } @@ -184,7 +184,7 @@ bool CGarrisonSlot::viewInfo() bool CGarrisonSlot::highlightOrDropArtifact() { bool artSelected = false; - if (CWindowWithArtifacts* chw = dynamic_cast(GH.windows().topWindow().get())) //dirty solution + if (auto chw = GH.windows().topWindow()) //dirty solution { const auto pickedArtInst = chw->getPickedArtifact(); diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index 6961dee07..4d36908c0 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/client/widgets/MiscWidgets.cpp @@ -36,9 +36,9 @@ void CHoverableArea::hover (bool on) { if (on) - GH.statusbar->write(hoverText); + GH.statusbar()->write(hoverText); else - GH.statusbar->clearIfMatching(hoverText); + GH.statusbar()->clearIfMatching(hoverText); } CHoverableArea::CHoverableArea() @@ -152,9 +152,9 @@ void CHeroArea::clickRight(tribool down, bool previousState) void CHeroArea::hover(bool on) { if (on && hero) - GH.statusbar->write(hero->getObjectName()); + GH.statusbar()->write(hero->getObjectName()); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } void LRClickableAreaOpenTown::clickLeft(tribool down, bool previousState) diff --git a/client/widgets/TextControls.cpp b/client/widgets/TextControls.cpp index 2cd828319..7270ea5cf 100644 --- a/client/widgets/TextControls.cpp +++ b/client/widgets/TextControls.cpp @@ -434,9 +434,7 @@ CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw) CGStatusBar::~CGStatusBar() { - assert(GH.statusbar.get() != this || GH.statusbar == nullptr); - if (GH.statusbar.get() == this) - GH.statusbar = nullptr; + assert(GH.statusbar().get() != this); } void CGStatusBar::show(SDL_Surface * to) @@ -455,13 +453,14 @@ void CGStatusBar::clickLeft(tribool down, bool previousState) void CGStatusBar::activate() { - GH.statusbar = shared_from_this(); + GH.setStatusbar(shared_from_this()); CIntObject::activate(); } void CGStatusBar::deactivate() { - assert(GH.statusbar.get() == this); + assert(GH.statusbar().get() == this); + GH.setStatusbar(nullptr); if (enteringText) LOCPLINT->cingconsole->endEnteringText(false); diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 751e42cbe..1271392ea 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -126,7 +126,7 @@ void CBuildingRect::hover(bool on) if(parent->selectedBuilding == this) { parent->selectedBuilding = nullptr; - GH.statusbar->clear(); + GH.statusbar()->clear(); } } } @@ -256,7 +256,7 @@ void CBuildingRect::mouseMoved (const Point & cursorPosition) if(parent->selectedBuilding == this) { parent->selectedBuilding = nullptr; - GH.statusbar->clear(); + GH.statusbar()->clear(); } } else //inside the area of this building @@ -265,7 +265,7 @@ void CBuildingRect::mouseMoved (const Point & cursorPosition) || (*parent->selectedBuilding)<(*this)) //or we are on top { parent->selectedBuilding = this; - GH.statusbar->write(getSubtitle()); + GH.statusbar()->write(getSubtitle()); } } } @@ -339,7 +339,7 @@ void CHeroGSlot::hover(bool on) { if(!on) { - GH.statusbar->clear(); + GH.statusbar()->clear(); return; } std::shared_ptr other = upg ? owner->garrisonedHero : owner->visitingHero; @@ -384,7 +384,7 @@ void CHeroGSlot::hover(bool on) } } if(temp.size()) - GH.statusbar->write(temp); + GH.statusbar()->write(temp); } void CHeroGSlot::clickLeft(tribool down, bool previousState) @@ -974,7 +974,8 @@ void CCastleBuildings::enterTownHall() else { LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[673]); - dynamic_cast(GH.windows().topWindow().get())->buttons[0]->addCallback(std::bind(&CCastleBuildings::openTownHall, this)); + assert(GH.windows().topWindow() != nullptr); + GH.windows().topWindow()->buttons[0]->addCallback(std::bind(&CCastleBuildings::openTownHall, this)); } } else @@ -1058,11 +1059,11 @@ void CCreaInfo::hover(bool on) if(on) { - GH.statusbar->write(message); + GH.statusbar()->write(message); } else { - GH.statusbar->clearIfMatching(message); + GH.statusbar()->clearIfMatching(message); } } @@ -1137,11 +1138,11 @@ void CTownInfo::hover(bool on) if(on) { if(building ) - GH.statusbar->write(building->getNameTranslated()); + GH.statusbar()->write(building->getNameTranslated()); } else { - GH.statusbar->clear(); + GH.statusbar()->clear(); } } @@ -1383,11 +1384,11 @@ void CHallInterface::CBuildingBox::hover(bool on) else toPrint = CGI->generaltexth->hcommands[state]; boost::algorithm::replace_first(toPrint,"%s",building->getNameTranslated()); - GH.statusbar->write(toPrint); + GH.statusbar()->write(toPrint); } else { - GH.statusbar->clear(); + GH.statusbar()->clear(); } } @@ -1571,11 +1572,11 @@ void LabeledValue::hover(bool on) { if(on) { - GH.statusbar->write(hoverText); + GH.statusbar()->write(hoverText); } else { - GH.statusbar->clear(); + GH.statusbar()->clear(); parent->hovered = false; } } @@ -1740,9 +1741,9 @@ const CBuilding * CFortScreen::RecruitArea::getMyBuilding() void CFortScreen::RecruitArea::hover(bool on) { if(on) - GH.statusbar->write(hoverText); + GH.statusbar()->write(hoverText); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } void CFortScreen::RecruitArea::creaturesChangedEventHandler() @@ -1830,9 +1831,9 @@ void CMageGuildScreen::Scroll::clickRight(tribool down, bool previousState) void CMageGuildScreen::Scroll::hover(bool on) { if(on) - GH.statusbar->write(spell->getNameTranslated()); + GH.statusbar()->write(spell->getNameTranslated()); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index 1dc6a887c..6c1dbdc54 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -243,7 +243,7 @@ void CTradeWindow::CTradeableItem::hover(bool on) { if(!on) { - GH.statusbar->clear(); + GH.statusbar()->clear(); return; } @@ -251,13 +251,13 @@ void CTradeWindow::CTradeableItem::hover(bool on) { case CREATURE: case CREATURE_PLACEHOLDER: - GH.statusbar->write(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->objects[id]->getNamePluralTranslated())); + GH.statusbar()->write(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->objects[id]->getNamePluralTranslated())); break; case ARTIFACT_PLACEHOLDER: if(id < 0) - GH.statusbar->write(CGI->generaltexth->zelp[582].first); + GH.statusbar()->write(CGI->generaltexth->zelp[582].first); else - GH.statusbar->write(CGI->artifacts()->getByIndex(id)->getNameTranslated()); + GH.statusbar()->write(CGI->artifacts()->getByIndex(id)->getNameTranslated()); break; } } diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index e7208459c..150db8728 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -586,9 +586,9 @@ void CTavernWindow::HeroPortrait::hover(bool on) { //Hoverable::hover(on); if(on) - GH.statusbar->write(hoverName); + GH.statusbar()->write(hoverName); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } static const std::string QUICK_EXCHANGE_MOD_PREFIX = "quick-exchange"; @@ -1256,9 +1256,9 @@ void CUniversityWindow::CItem::clickRight(tribool down, bool previousState) void CUniversityWindow::CItem::hover(bool on) { if(on) - GH.statusbar->write(CGI->skillh->getByIndex(ID)->getNameTranslated()); + GH.statusbar()->write(CGI->skillh->getByIndex(ID)->getNameTranslated()); else - GH.statusbar->clear(); + GH.statusbar()->clear(); } int CUniversityWindow::CItem::state() diff --git a/client/windows/settings/SettingsMainWindow.cpp b/client/windows/settings/SettingsMainWindow.cpp index d4df6dc19..2235bcb89 100644 --- a/client/windows/settings/SettingsMainWindow.cpp +++ b/client/windows/settings/SettingsMainWindow.cpp @@ -104,7 +104,7 @@ void SettingsMainWindow::openTab(size_t index) void SettingsMainWindow::close() { - if(GH.windows().topWindow().get() != this) + if(!GH.windows().isTopWindow(this)) logGlobal->error("Only top interface must be closed"); GH.windows().popWindows(1); }