瀏覽代碼

* CThreadHelper.cpp now belongs to VCMI_lib project
* fixed console on Windows (restored old code)
* GeniusAI won't get blocked when it has a hero with tactics in battle
* fixed an issue with switching turns in hot-seat mode when there is Cover of Darkness active
* suppressed bonus system console output: it goes only to the logfile
* [win32] setting thread names (debug purposes)
* minor fixes

Michał W. Urbańczyk 14 年之前
父節點
當前提交
1afcaf2817

+ 7 - 0
AI/GeniusAI/CGeniusAI.cpp

@@ -1262,6 +1262,13 @@ void CGeniusAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2
 	m_battleLogic = new BattleAI::CBattleLogic(m_cb, army1, army2, tile, hero1,
     hero2, side);
 
+	if(m_cb->battleGetTacticDist())
+	{
+		m_cb->waitTillRealize = false;
+		BattleAction endt = BattleAction::makeEndOFTacticPhase(m_cb->battleGetMySide());
+		m_cb->battleMakeTacticAction(&endt);
+		m_cb->waitTillRealize = true;
+	}
 	DbgBox("** CGeniusAI::battleStart **");
 }
 

+ 14 - 1
CConsoleHandler.cpp

@@ -4,6 +4,7 @@
 #include <boost/function.hpp>
 #include <boost/thread.hpp>
 #include <iomanip>
+#include "CThreadHelper.h"
 
 /*
 * CConsoleHandler.cpp, part of VCMI engine
@@ -182,12 +183,14 @@ void CConsoleHandler::setColor(int level)
 
 int CConsoleHandler::run()
 {
+	setThreadName(-1, "CConsoleHandler::run");
 	//disabling sync to make in_avail() work (othervice always returns 0)
 	std::ios::sync_with_stdio(false);
 	std::string buffer;
 
 	while ( std::cin.good() )
 	{
+#ifndef _WIN32
 		//check if we have some unreaded symbols
 		if (std::cin.rdbuf()->in_avail())
 		{
@@ -199,6 +202,11 @@ int CConsoleHandler::run()
 			boost::this_thread::sleep(boost::posix_time::millisec(100));
 
 		boost::this_thread::interruption_point();
+#else
+		std::getline(std::cin, buffer);
+		if ( cb && *cb )
+			(*cb)(buffer);
+#endif
 	}
 	return -1;
 }
@@ -228,8 +236,13 @@ CConsoleHandler::~CConsoleHandler()
 }
 void CConsoleHandler::end()
 {
-	if (thread) {
+	if (thread) 
+	{
+#ifndef _WIN32
 		thread->interrupt();
+#else
+		TerminateThread(thread->native_handle(),0);
+#endif
 		thread->join();
 		delete thread;
 		thread = NULL;

+ 37 - 1
CThreadHelper.cpp

@@ -1,7 +1,11 @@
+#define VCMI_DLL
+
 #include "CThreadHelper.h"
 #include <boost/thread.hpp>
 #include <boost/bind.hpp>
-
+#ifdef _WIN32
+	#include <windows.h>
+#endif
 /*
  * CThreadHelper.cpp, part of VCMI engine
  *
@@ -43,4 +47,36 @@ void CThreadHelper::processTasks()
 			(*tasks)[pom]();
 		}
 	}
+}
+
+void setThreadName(long threadID, const std::string &name)
+{
+#ifdef _WIN32
+	//follows http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+	const DWORD MS_VC_EXCEPTION=0x406D1388;
+#pragma pack(push,8)
+	typedef struct tagTHREADNAME_INFO
+	{
+		DWORD dwType; // Must be 0x1000.
+		LPCSTR szName; // Pointer to name (in user addr space).
+		DWORD dwThreadID; // Thread ID (-1=caller thread).
+		DWORD dwFlags; // Reserved for future use, must be zero.
+	} THREADNAME_INFO;
+#pragma pack(pop)
+	THREADNAME_INFO info;
+	info.dwType = 0x1000;
+	info.szName = name.c_str();
+	info.dwThreadID = threadID;
+	info.dwFlags = 0;
+
+	__try
+	{
+		RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
+	}
+	__except(EXCEPTION_EXECUTE_HANDLER)
+	{
+	}
+#else
+	//*nix counterpart?
+#endif
 }

+ 2 - 1
CThreadHelper.h

@@ -19,7 +19,7 @@
 typedef boost::function<void()> Task;
 
 /// Can assign CPU work to other threads/cores
-class CThreadHelper
+class DLL_EXPORT CThreadHelper
 {
 	boost::mutex rtinm;
 	int currentTask, amount, threads;
@@ -37,6 +37,7 @@ template <typename T> inline void setData(T * data, boost::function<T()> func)
 	*data = func();
 }
 
+void DLL_EXPORT setThreadName(long threadID, const std::string &name);
 
 #define GET_DATA(TYPE,DESTINATION,FUNCTION_TO_GET) \
 	(boost::bind(&setData<TYPE>,&DESTINATION,FUNCTION_TO_GET))

+ 13 - 4
client/CBattleInterface.cpp

@@ -3376,10 +3376,13 @@ void CBattleInterface::startAction(const BattleAction* action)
 		if(active)
 		{
 			tacticsMode = false;
-			btactEnd->deactivate();
-			btactNext->deactivate();
-			bConsoleDown->activate();
-			bConsoleUp->activate();
+			if(btactEnd && btactNext) //if the other side had tactics, there are no buttons
+			{
+				btactEnd->deactivate();
+				btactNext->deactivate();
+				bConsoleDown->activate();
+				bConsoleUp->activate();
+			}
 		}
 		redraw();
 
@@ -3473,9 +3476,15 @@ void CBattleInterface::bEndTacticPhase()
 	curInt->cb->battleMakeTacticAction(&endt);
 }
 
+static bool immobile(const CStack *s)
+{
+	return !s->Speed();
+}
+
 void CBattleInterface::bTacticNextStack()
 {
 	TStacks stacksOfMine = curInt->cb->battleGetStacks(IBattleCallback::ONLY_MINE);
+	stacksOfMine.erase(std::remove_if(stacksOfMine.begin(), stacksOfMine.end(), &immobile));
 	TStacks::iterator it = vstd::find(stacksOfMine, activeStack);
 	if(it != stacksOfMine.end() && ++it != stacksOfMine.end())
 		stackActivated(*it);

+ 5 - 2
client/CPlayerInterface.cpp

@@ -105,7 +105,7 @@ CPlayerInterface::CPlayerInterface(int Player)
 	human=true;
 	castleInt = NULL;
 	battleInt = NULL;
-	pim = new boost::recursive_mutex;
+	//pim = new boost::recursive_mutex;
 	makingTurn = false;
 	showingDialog = new CondSh<bool>(false);
 	sysOpts = GDefaultOptions;
@@ -122,7 +122,8 @@ CPlayerInterface::CPlayerInterface(int Player)
 CPlayerInterface::~CPlayerInterface()
 {
 	howManyPeople--;
-	delete pim;
+	//delete pim;
+	delNull(pim);
 	delete showingDialog;
 	delete mainFPSmng;
 	if(adventureInt)
@@ -2211,6 +2212,8 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
 				aoh->artifactDisassembled(al);
 }
 
+boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex;
+
 CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
 {
 	spellbookLastPageBattle = spellbokLastPageAdvmap = 0;

+ 1 - 1
client/CPlayerInterface.h

@@ -119,7 +119,7 @@ public:
 	//minor interfaces
 	CondSh<bool> *showingDialog; //indicates if dialog box is displayed
 
-	boost::recursive_mutex *pim;
+	static boost::recursive_mutex *pim;
 	bool makingTurn; //if player is already making his turn
 	int firstCall; // -1 - just loaded game; 1 - just started game; 0 otherwise
 	int autosaveCount;

+ 2 - 0
client/CPreGame.cpp

@@ -44,6 +44,7 @@
 #include "../lib/NetPacks.h"
 #include "../lib/RegisterTypes.cpp"
 #include <boost/thread/recursive_mutex.hpp>
+#include "../CThreadHelper.h"
 
 /*
  * CPreGame.cpp, part of VCMI engine
@@ -681,6 +682,7 @@ void CSelectionScreen::difficultyChange( int to )
 
 void CSelectionScreen::handleConnection()
 {
+	setThreadName(-1, "CSelectionScreen::handleConnection");
 	try
 	{
 		assert(serv);

+ 4 - 1
client/Client.cpp

@@ -31,10 +31,11 @@
 #include <boost/lexical_cast.hpp>
 #include <sstream>
 #include "CPreGame.h"
+#include "CBattleInterface.h"
+#include "../CThreadHelper.h"
 
 #define NOT_LIB
 #include "../lib/RegisterTypes.cpp"
-#include "CBattleInterface.h"
 extern std::string NAME;
 namespace intpr = boost::interprocess;
 
@@ -127,6 +128,7 @@ void CClient::waitForMoveAndSend(int color)
 
 void CClient::run()
 {
+	setThreadName(-1, "CClient::run");
 	try
 	{
 		CPack *pack = NULL;
@@ -648,6 +650,7 @@ CServerHandler::~CServerHandler()
 
 void CServerHandler::callServer()
 {
+	setThreadName(-1, "CServerHandler::callServer");
 	std::string comm = std::string(BIN_DIR PATH_SEPARATOR SERVER_NAME " ") + port + " > server_log.txt";
 	std::system(comm.c_str());
 	tlog0 << "Server finished\n";

+ 2 - 0
client/GUIBase.cpp

@@ -8,6 +8,7 @@
 #include "CCursorHandler.h"
 #include "CBitmapHandler.h"
 #include "Graphics.h"
+#include "../CThreadHelper.h"
 /*
  * GUIBase.cpp, part of VCMI engine
  *
@@ -373,6 +374,7 @@ void CGuiHandler::fakeMouseMove()
 
 void CGuiHandler::run()
 {
+	setThreadName(-1, "CGuiHandler::run");
 	try
 	{
 		while(!terminate)

+ 3 - 3
client/GUIClasses.cpp

@@ -5401,14 +5401,14 @@ void CExchangeWindow::show(SDL_Surface * to)
 	artifs[0]->showAll(to);
 	artifs[1]->showAll(to);
 
-	ourBar->show(to);
+	ourBar->showAll(to);
 
 	for(int g=0; g<ARRAY_COUNT(secSkillAreas); g++)
 	{
-		questlogButton[g]->show(to);//FIXME: for array count(secondary skill) show quest log button? WTF?
+		questlogButton[g]->showAll(to);//FIXME: for array count(secondary skill) show quest log button? WTF?
 	}
 
-	garr->show(to);
+	garr->showAll(to);
 }
 
 void CExchangeWindow::questlog(int whichHero)

+ 1 - 1
client/Graphics.cpp

@@ -65,7 +65,7 @@ SDL_Surface * Graphics::drawHeroInfoWin(const InfoAboutHero &curh)
 		}
 		else
 		{
-			printAtMiddle(VLC->generaltexth->arraytxt[174 + 3*(i->second.count-1)],slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+41,FONT_TINY,zwykly,ret);
+			printAtMiddle(VLC->generaltexth->arraytxt[174 + 3*(i->second.count)],slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+41,FONT_TINY,zwykly,ret);
 		}
 	}
 

+ 1 - 1
lib/HeroBonus.cpp

@@ -23,7 +23,7 @@
 	DLL_EXPORT const std::map<std::string, int> bonusNameMap = boost::assign::map_list_of BONUS_LIST;
 #undef BONUS_NAME
 
-#define BONUS_LOG_LINE(x) tlog0 << x << std::endl
+#define BONUS_LOG_LINE(x) tlog5 << x << std::endl
 
 int DLL_EXPORT BonusList::totalValue() const
 {

+ 1 - 2
server/CGameHandler.cpp

@@ -20,8 +20,6 @@
 #include "../lib/VCMIDirs.h"
 #include "../client/CSoundBase.h"
 #include "CGameHandler.h"
-#include <boost/format.hpp>
-#include <sstream>
 
 /*
  * CGameHandler.cpp, part of VCMI engine
@@ -571,6 +569,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
 }
 void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 {
+	setThreadName(-1, "CGameHandler::handleConnection");
 	srand(time(NULL));
 	CPack *pack = NULL;
 	try

+ 5 - 0
server/stdafx.h

@@ -23,3 +23,8 @@
 #include <boost/thread.hpp>
 #include <boost/foreach.hpp>
 
+#include <boost/format.hpp>
+#include <sstream>
+#include <boost/format.hpp>
+#include <sstream>
+#include "../CThreadHelper.h"