Bladeren bron

Fixed several assertion failures on shutting down game

Ivan Savenko 2 jaren geleden
bovenliggende
commit
4d628a8ba1
3 gewijzigde bestanden met toevoegingen van 43 en 40 verwijderingen
  1. 22 13
      client/CMT.cpp
  2. 12 20
      client/Client.cpp
  3. 9 7
      client/battle/BattleInterface.cpp

+ 22 - 13
client/CMT.cpp

@@ -582,12 +582,13 @@ void printInfoAboutIntObject(const CIntObject *obj, int level)
 void removeGUI()
 void removeGUI()
 {
 {
 	// CClient::endGame
 	// CClient::endGame
-	GH.curInt = nullptr;
-	if(GH.topInt())
-		GH.topInt()->deactivate();
-	GH.listInt.clear();
-	GH.objsToBlit.clear();
-	GH.statusbar = nullptr;
+	GH.curInt = nullptr;
+	if(GH.topInt())
+		GH.topInt()->deactivate();
+	adventureInt = nullptr;
+	GH.listInt.clear();
+	GH.objsToBlit.clear();
+	GH.statusbar = nullptr;
 	logGlobal->info("Removed GUI.");
 	logGlobal->info("Removed GUI.");
 
 
 	LOCPLINT = nullptr;
 	LOCPLINT = nullptr;
@@ -1570,13 +1571,21 @@ void handleQuit(bool ask)
 		{
 		{
 			logConfig->deconfigure();
 			logConfig->deconfigure();
 			delete logConfig;
 			delete logConfig;
-			logConfig = nullptr;
-		}
-
-		std::cout << "Ending...\n";
-		exit(0);
-	};
-
+			logConfig = nullptr;
+		}
+
+
+		std::cout << "Ending...\n";
+
+		// Workaround for assertion failure on exit:
+		// handleQuit() is alway called during SDL event processing
+		// during which, eventsM is kept locked
+		// this leads to assertion failure if boost::mutex is in locked state
+		eventsM.unlock();
+
+		exit(0);
+	};
+
 	if(CSH->client && LOCPLINT && ask)
 	if(CSH->client && LOCPLINT && ask)
 	{
 	{
 		CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);
 		CCS->curh->changeGraphic(ECursor::ADVENTURE, 0);

+ 12 - 20
client/Client.cpp

@@ -377,26 +377,18 @@ void CClient::endGame()
 		i.second->finish();
 		i.second->finish();
 
 
 	GH.curInt = nullptr;
 	GH.curInt = nullptr;
-	{
-		boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
-		logNetwork->info("Ending current game!");
-		if(GH.topInt())
-		{
-			GH.topInt()->deactivate();
-		}
-		GH.listInt.clear();
-		GH.objsToBlit.clear();
-		GH.statusbar = nullptr;
-		logNetwork->info("Removed GUI.");
-
-		vstd::clear_pointer(const_cast<CGameInfo *>(CGI)->mh);
-		vstd::clear_pointer(gs);
-
-		logNetwork->info("Deleted mapHandler and gameState.");
-		LOCPLINT = nullptr;
-	}
-
-	playerint.clear();
+	{
+		boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
+		logNetwork->info("Ending current game!");
+		removeGUI();
+
+		vstd::clear_pointer(const_cast<CGameInfo *>(CGI)->mh);
+		vstd::clear_pointer(gs);
+
+		logNetwork->info("Deleted mapHandler and gameState.");
+	}
+
+	playerint.clear();
 	battleints.clear();
 	battleints.clear();
 	battleCallbacks.clear();
 	battleCallbacks.clear();
 	playerEnvironments.clear();
 	playerEnvironments.clear();

+ 9 - 7
client/battle/BattleInterface.cpp

@@ -202,13 +202,15 @@ BattleInterface::~BattleInterface()
 	{
 	{
 		//FIXME: this should be moved to adventureInt which should restore correct track based on selection/active player
 		//FIXME: this should be moved to adventureInt which should restore correct track based on selection/active player
 		const auto & terrain = *(LOCPLINT->cb->getTile(adventureInt->selection->visitablePos())->terType);
 		const auto & terrain = *(LOCPLINT->cb->getTile(adventureInt->selection->visitablePos())->terType);
-		CCS->musich->playMusicFromSet("terrain", terrain.name, true, false);
-	}
-
-	assert(getAnimationCondition(EAnimationEvents::ACTION) == false);
-	setAnimationCondition(EAnimationEvents::ACTION, false);
-}
-
+		CCS->musich->playMusicFromSet("terrain", terrain.name, true, false);
+	}
+
+	// may happen if user decided to close game while in battle
+	if (getAnimationCondition(EAnimationEvents::ACTION) == true)
+		logGlobal->error("Shutting down BattleInterface during animation playback!");
+	setAnimationCondition(EAnimationEvents::ACTION, false);
+}
+
 void BattleInterface::setPrintCellBorders(bool set)
 void BattleInterface::setPrintCellBorders(bool set)
 {
 {
 	Settings cellBorders = settings.write["battle"]["cellBorders"];
 	Settings cellBorders = settings.write["battle"]["cellBorders"];