Bläddra i källkod

Pathfinding: do path calculation in separate thread

ArseniyShestakov 10 år sedan
förälder
incheckning
f376b27999
4 ändrade filer med 28 tillägg och 1 borttagningar
  1. 4 1
      lib/CGameState.cpp
  2. 2 0
      lib/CGameState.h
  3. 21 0
      lib/CPathfinder.cpp
  4. 1 0
      lib/CPathfinder.h

+ 4 - 1
lib/CGameState.cpp

@@ -2164,8 +2164,11 @@ void CGameState::apply(CPack *pack)
 
 void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out)
 {
+	if(pathfinderWorking)
+		pathfinderWorking->interrupt();
+
 	CPathfinder pathfinder(out, this, hero);
-	pathfinder.calculatePaths();
+	pathfinderWorking = make_unique<boost::thread>(&CPathfinder::startPathfinder, pathfinder);
 }
 
 /**

+ 2 - 0
lib/CGameState.h

@@ -314,6 +314,8 @@ public:
 
 	boost::shared_mutex *mx;
 
+	unique_ptr<boost::thread> pathfinderWorking;
+
 	void giveHeroArtifact(CGHeroInstance *h, ArtifactID aid);
 
 	void apply(CPack *pack);

+ 21 - 0
lib/CPathfinder.cpp

@@ -7,6 +7,7 @@
 #include "mapObjects/CGHeroInstance.h"
 #include "GameConstants.h"
 #include "CStopWatch.h"
+#include "CThreadHelper.h"
 
 /*
  * CPathfinder.cpp, part of VCMI engine
@@ -59,6 +60,24 @@ CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance
 	neighbours.reserve(16);
 }
 
+void CPathfinder::startPathfinder()
+{
+	try
+	{
+		setThreadName("CPathfinder::startPathfinder");
+
+		calculatePaths();
+	}
+	catch(boost::thread_interrupted &e)
+	{
+		gs->pathfinderWorking.reset();
+		return;
+	}
+
+	gs->pathfinderWorking.reset();
+}
+
+
 void CPathfinder::calculatePaths()
 {
 	int maxMovePointsLand = hero->maxMovePoints(true);
@@ -192,6 +211,8 @@ void CPathfinder::calculatePaths()
 				}
 			}
 		}
+
+		boost::this_thread::interruption_point();
 	} //queue loop
 }
 

+ 1 - 0
lib/CPathfinder.h

@@ -91,6 +91,7 @@ class CPathfinder : private CGameInfoCallback
 {
 public:
 	CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance *_hero);
+	void startPathfinder();
 	void calculatePaths(); //calculates possible paths for hero, uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
 
 private: