Browse Source

Possible fix for https://bugs.vcmi.eu/view.php?id=2692

AlexVinS 8 years ago
parent
commit
0af9aa382c

+ 7 - 7
client/CPlayerInterface.cpp

@@ -821,10 +821,10 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
 
 
 	CBattleInterface *b = battleInt;
 	CBattleInterface *b = battleInt;
 
 
-	if (b->givenCommand->get())
+	if(CBattleInterface::givenCommand.get())
 	{
 	{
 		logGlobal->errorStream() << "Command buffer must be clean! (we don't want to use old command)";
 		logGlobal->errorStream() << "Command buffer must be clean! (we don't want to use old command)";
-		vstd::clear_pointer(b->givenCommand->data);
+		vstd::clear_pointer(CBattleInterface::givenCommand.data);
 	}
 	}
 
 
 	{
 	{
@@ -833,17 +833,17 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
 		//Regeneration & mana drain go there
 		//Regeneration & mana drain go there
 	}
 	}
 	//wait till BattleInterface sets its command
 	//wait till BattleInterface sets its command
-	boost::unique_lock<boost::mutex> lock(b->givenCommand->mx);
-	while(!b->givenCommand->data)
+	boost::unique_lock<boost::mutex> lock(CBattleInterface::givenCommand.mx);
+	while(!CBattleInterface::givenCommand.data)
 	{
 	{
-		b->givenCommand->cond.wait(lock);
+		CBattleInterface::givenCommand.cond.wait(lock);
 		if (!battleInt) //battle ended while we were waiting for movement (eg. because of spell)
 		if (!battleInt) //battle ended while we were waiting for movement (eg. because of spell)
 			throw boost::thread_interrupted(); //will shut the thread peacefully
 			throw boost::thread_interrupted(); //will shut the thread peacefully
 	}
 	}
 
 
 	//tidy up
 	//tidy up
-	BattleAction ret = *(b->givenCommand->data);
-	vstd::clear_pointer(b->givenCommand->data);
+	BattleAction ret = *(CBattleInterface::givenCommand.data);
+	vstd::clear_pointer(CBattleInterface::givenCommand.data);
 
 
 	if (ret.actionType == Battle::CANCEL)
 	if (ret.actionType == Battle::CANCEL)
 	{
 	{

+ 7 - 8
client/battle/CBattleInterface.cpp

@@ -47,6 +47,7 @@
  */
  */
 
 
 CondSh<bool> CBattleInterface::animsAreDisplayed(false);
 CondSh<bool> CBattleInterface::animsAreDisplayed(false);
+CondSh<BattleAction *> CBattleInterface::givenCommand(nullptr);
 
 
 static void onAnimationFinished(const CStack *stack, CCreatureAnimation *anim)
 static void onAnimationFinished(const CStack *stack, CCreatureAnimation *anim)
 {
 {
@@ -101,7 +102,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
 	  currentlyHoveredHex(-1), attackingHex(-1), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellToCast(nullptr), sp(nullptr),
 	  currentlyHoveredHex(-1), attackingHex(-1), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellToCast(nullptr), sp(nullptr),
 	  creatureSpellToCast(-1),
 	  creatureSpellToCast(-1),
 	  siegeH(nullptr), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0),
 	  siegeH(nullptr), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0),
-	  givenCommand(nullptr), myTurn(false), resWindow(nullptr), moveStarted(false), moveSoundHander(-1), bresult(nullptr)
+	  myTurn(false), resWindow(nullptr), moveStarted(false), moveSoundHander(-1), bresult(nullptr)
 {
 {
 	OBJ_CONSTRUCTION;
 	OBJ_CONSTRUCTION;
 
 
@@ -117,7 +118,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
 	animsAreDisplayed.setn(false);
 	animsAreDisplayed.setn(false);
 	pos = myRect;
 	pos = myRect;
 	strongInterest = true;
 	strongInterest = true;
-	givenCommand = new CondSh<BattleAction *>(nullptr);
+	givenCommand.setn(nullptr);
 
 
 	//hot-seat -> check tactics for both players (defender may be local human)
 	//hot-seat -> check tactics for both players (defender may be local human)
 	if (attackerInt && attackerInt->cb->battleGetTacticDist())
 	if (attackerInt && attackerInt->cb->battleGetTacticDist())
@@ -387,8 +388,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet
 CBattleInterface::~CBattleInterface()
 CBattleInterface::~CBattleInterface()
 {
 {
 	curInt->battleInt = nullptr;
 	curInt->battleInt = nullptr;
-	givenCommand->cond.notify_all(); //that two lines should make any activeStack waiting thread to finish
-
+	givenCommand.cond.notify_all(); //that two lines should make any activeStack waiting thread to finish
 
 
 	if (active) //dirty fix for #485
 	if (active) //dirty fix for #485
 	{
 	{
@@ -416,7 +416,6 @@ CBattleInterface::~CBattleInterface()
 	delete bConsoleUp;
 	delete bConsoleUp;
 	delete bConsoleDown;
 	delete bConsoleDown;
 	delete console;
 	delete console;
-	delete givenCommand;
 
 
 	delete attackingHero;
 	delete attackingHero;
 	delete defendingHero;
 	delete defendingHero;
@@ -1028,7 +1027,7 @@ void CBattleInterface::stackRemoved(int stackID)
 			action->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
 			action->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
 			action->actionType = Battle::CANCEL;
 			action->actionType = Battle::CANCEL;
 			action->stackNumber = activeStack->ID;
 			action->stackNumber = activeStack->ID;
-			givenCommand->setn(action);
+			givenCommand.setn(action);
 			setActiveStack(nullptr);
 			setActiveStack(nullptr);
 		}
 		}
 	}
 	}
@@ -1149,7 +1148,7 @@ void CBattleInterface::giveCommand(Battle::ActionType action, BattleHex tile, ui
 		logGlobal->traceStream() << "Setting command for " << (stack ? stack->nodeName() : "hero");
 		logGlobal->traceStream() << "Setting command for " << (stack ? stack->nodeName() : "hero");
 		myTurn = false;
 		myTurn = false;
 		setActiveStack(nullptr);
 		setActiveStack(nullptr);
-		givenCommand->setn(ba);
+		givenCommand.setn(ba);
 	}
 	}
 	else
 	else
 	{
 	{
@@ -2840,7 +2839,7 @@ void CBattleInterface::requestAutofightingAIToTakeAction()
 			}
 			}
 			else
 			else
 			{
 			{
-				givenCommand->setn(ba.release());
+				givenCommand.setn(ba.release());
 			}
 			}
 		}
 		}
 		else
 		else

+ 5 - 2
client/battle/CBattleInterface.h

@@ -264,10 +264,13 @@ private:
 
 
 	PossibleActions getCasterAction(const CSpell *spell, const ISpellCaster *caster, ECastingMode::ECastingMode mode) const;
 	PossibleActions getCasterAction(const CSpell *spell, const ISpellCaster *caster, ECastingMode::ECastingMode mode) const;
 public:
 public:
+	static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
+	static CondSh<BattleAction *> givenCommand; //data != nullptr if we have i.e. moved current unit
+
 	std::list<std::pair<CBattleAnimation *, bool>> pendingAnims; //currently displayed animations <anim, initialized>
 	std::list<std::pair<CBattleAnimation *, bool>> pendingAnims; //currently displayed animations <anim, initialized>
 	void addNewAnim(CBattleAnimation *anim); //adds new anim to pendingAnims
 	void addNewAnim(CBattleAnimation *anim); //adds new anim to pendingAnims
 	ui32 animIDhelper; //for giving IDs for animations
 	ui32 animIDhelper; //for giving IDs for animations
-	static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims
+
 
 
 	CBattleInterface(const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, const SDL_Rect & myRect, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr); //c-tor
 	CBattleInterface(const CCreatureSet *army1, const CCreatureSet *army2, const CGHeroInstance *hero1, const CGHeroInstance *hero2, const SDL_Rect & myRect, std::shared_ptr<CPlayerInterface> att, std::shared_ptr<CPlayerInterface> defen, std::shared_ptr<CPlayerInterface> spectatorInt = nullptr); //c-tor
 	virtual ~CBattleInterface(); //d-tor
 	virtual ~CBattleInterface(); //d-tor
@@ -282,7 +285,7 @@ public:
 
 
 	std::vector<CClickableHex*> bfield; //11 lines, 17 hexes on each
 	std::vector<CClickableHex*> bfield; //11 lines, 17 hexes on each
 	SDL_Surface *cellBorder, *cellShade;
 	SDL_Surface *cellBorder, *cellShade;
-	CondSh<BattleAction *> *givenCommand; //data != nullptr if we have i.e. moved current unit
+
 	bool myTurn; //if true, interface is active (commands can be ordered)
 	bool myTurn; //if true, interface is active (commands can be ordered)
 	CBattleResultWindow *resWindow; //window of end of battle
 	CBattleResultWindow *resWindow; //window of end of battle