Browse Source

AI: pathfinder api supports configuration

Andrii Danylchenko 7 years ago
parent
commit
7150fc9f71
8 changed files with 41 additions and 13 deletions
  1. 5 0
      CCallback.cpp
  2. 2 0
      CCallback.h
  3. 7 0
      client/Client.cpp
  4. 1 0
      client/Client.h
  5. 6 0
      lib/CGameState.cpp
  6. 1 0
      lib/CGameState.h
  7. 15 10
      lib/CPathfinder.cpp
  8. 4 3
      lib/CPathfinder.h

+ 5 - 0
CCallback.cpp

@@ -291,6 +291,11 @@ const CPathsInfo * CCallback::getPathsInfo(const CGHeroInstance *h)
 	return cl->getPathsInfo(h);
 }
 
+void CCallback::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
+{
+	cl->calculatePaths(config, hero);
+}
+
 int3 CCallback::getGuardingCreaturePosition(int3 tile)
 {
 	if (!gs->map->isInTheMap(tile))

+ 2 - 0
CCallback.h

@@ -25,6 +25,7 @@ class IShipyard;
 struct CGPathNode;
 struct CGPath;
 struct CPathsInfo;
+class CPathfinderConfig;
 struct CPack;
 class IBattleEventsReceiver;
 class IGameEventsReceiver;
@@ -106,6 +107,7 @@ public:
 	virtual bool canMoveBetween(const int3 &a, const int3 &b);
 	virtual int3 getGuardingCreaturePosition(int3 tile);
 	virtual const CPathsInfo * getPathsInfo(const CGHeroInstance *h);
+	virtual void calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero);
 
 	virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out);
 

+ 7 - 0
client/Client.cpp

@@ -628,6 +628,13 @@ const CPathsInfo * CClient::getPathsInfo(const CGHeroInstance * h)
 	return pathInfo.get();
 }
 
+void CClient::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
+{
+	boost::unique_lock<boost::mutex> pathLock(config->nodeStorage->getMutex());
+	
+	gs->calculatePaths(config, hero);
+}
+
 PlayerColor CClient::getLocalPlayer() const
 {
 	if(LOCPLINT)

+ 1 - 0
client/Client.h

@@ -151,6 +151,7 @@ public:
 
 	void invalidatePaths();
 	const CPathsInfo * getPathsInfo(const CGHeroInstance * h);
+	void calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero);
 	virtual PlayerColor getLocalPlayer() const override;
 
 	friend class CCallback; //handling players actions

+ 6 - 0
lib/CGameState.cpp

@@ -1979,6 +1979,12 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out)
 	pathfinder.calculatePaths();
 }
 
+void CGameState::calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero)
+{
+	CPathfinder pathfinder(this, hero, config);
+	pathfinder.calculatePaths();
+}
+
 /**
  * Tells if the tile is guarded by a monster as well as the position
  * of the monster that will attack on it.

+ 1 - 0
lib/CGameState.h

@@ -178,6 +178,7 @@ public:
 	PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2);
 	bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if src tile is visitable from dst tile
 	void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
+	void calculatePaths(std::shared_ptr<CPathfinderConfig> config, const CGHeroInstance * hero);
 	int3 guardingCreaturePosition (int3 pos) const;
 	std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
 	void updateRumor();

+ 15 - 10
lib/CPathfinder.cpp

@@ -41,7 +41,7 @@ std::vector<CGPathNode *> CNeighbourFinder::calculateNeighbours(
 	{
 		for(EPathfindingLayer i = EPathfindingLayer::LAND; i <= EPathfindingLayer::AIR; i.advance(1))
 		{
-			auto node = pathfinderConfig->nodeHelper->getNode(neighbour, i);
+			auto node = pathfinderConfig->nodeStorage->getNode(neighbour, i);
 
 			if(node->accessible == CGPathNode::NOT_SET)
 				continue;
@@ -63,7 +63,7 @@ std::vector<CGPathNode *> CNeighbourFinder::calculateTeleportations(
 
 	for(auto & neighbour : accessibleExits)
 	{
-		auto node = pathfinderConfig->nodeHelper->getNode(neighbour, source.node->layer);
+		auto node = pathfinderConfig->nodeStorage->getNode(neighbour, source.node->layer);
 
 		neighbours.push_back(node);
 	}
@@ -96,19 +96,24 @@ std::vector<int3> CNeighbourFinder::getNeighbourTiles(
 	return neighbourTiles;
 }
 
-class CPathfinderNodeHelper : public CNodeHelper
+class CPathfinderNodeStorage : public CNodeStorage
 {
 private:
 	CPathsInfo & out;
 
 public:
-	CPathfinderNodeHelper(CPathsInfo & pathsInfo, const CGHeroInstance * hero)
+	CPathfinderNodeStorage(CPathsInfo & pathsInfo, const CGHeroInstance * hero)
 		:out(pathsInfo)
 	{
 		out.hero = hero;
 		out.hpos = hero->getPosition(false);
 	}
 
+	virtual boost::mutex & getMutex()
+	{
+		return out.pathMx;
+	}
+
 	virtual CGPathNode * getNode(const int3 & coord, const EPathfindingLayer layer)
 	{
 		return out.getNode(coord, layer);
@@ -189,10 +194,10 @@ public:
 };
 
 CPathfinderConfig::CPathfinderConfig(
-	std::shared_ptr<CNodeHelper> nodeHelper,
+	std::shared_ptr<CNodeStorage> nodeStorage,
 	std::shared_ptr<CNeighbourFinder> neighbourFinder,
 	std::vector<std::shared_ptr<IPathfindingRule>> rules)
-	: nodeHelper(nodeHelper), neighbourFinder(neighbourFinder), rules(rules), options()
+	: nodeStorage(nodeStorage), neighbourFinder(neighbourFinder), rules(rules), options()
 {
 }
 
@@ -204,7 +209,7 @@ CPathfinder::CPathfinder(
 		_gs,
 		_hero,
 		std::make_shared<CPathfinderConfig>(
-			std::make_shared<CPathfinderNodeHelper>(_out, _hero),
+			std::make_shared<CPathfinderNodeStorage>(_out, _hero),
 			std::make_shared<CNeighbourFinder>(),
 			std::vector<std::shared_ptr<IPathfindingRule>>{
 				std::make_shared<CMovementCostRule>(),
@@ -238,7 +243,7 @@ void CPathfinder::calculatePaths()
 	//logGlobal->info("Calculating paths for hero %s (adress  %d) of player %d", hero->name, hero , hero->tempOwner);
 
 	//initial tile - set cost on 0 and add to the queue
-	CGPathNode * initialNode = config->nodeHelper->getInitialNode();
+	CGPathNode * initialNode = config->nodeStorage->getInitialNode();
 
 	if(!isInTheMap(initialNode->coord)/* || !gs->map->isInTheMap(dest)*/) //check input
 	{
@@ -759,7 +764,7 @@ CGPathNode::ENodeAction CPathfinder::getTeleportDestAction() const
 
 bool CPathfinder::isSourceInitialPosition() const
 {
-	return source.node->coord == config->nodeHelper->getInitialNode()->coord;
+	return source.node->coord == config->nodeStorage->getInitialNode()->coord;
 }
 
 bool CPathfinder::isSourceGuarded() const
@@ -810,7 +815,7 @@ void CPathfinder::initializeGraph()
 {
 	auto updateNode = [&](int3 pos, ELayer layer, const TerrainTile * tinfo)
 	{
-		auto node = config->nodeHelper->getNode(pos, layer);
+		auto node = config->nodeStorage->getNode(pos, layer);
 		auto accessibility = evaluateAccessibility(pos, tinfo, layer);
 		node->update(pos, layer, accessibility);
 	};

+ 4 - 3
lib/CPathfinder.h

@@ -127,11 +127,12 @@ struct DLL_LINKAGE CDestinationNodeInfo : public CPathNodeInfo
 	virtual bool isBetterWay();
 };
 
-class CNodeHelper
+class CNodeStorage
 {
 public:
 	virtual CGPathNode * getNode(const int3 & coord, const EPathfindingLayer layer) = 0;
 	virtual CGPathNode * getInitialNode() = 0;
+	virtual boost::mutex & getMutex() = 0;
 };
 
 class CPathfinderHelper;
@@ -237,13 +238,13 @@ struct DLL_LINKAGE PathfinderOptions
 class CPathfinderConfig
 {
 public:
-	std::shared_ptr<CNodeHelper> nodeHelper;
+	std::shared_ptr<CNodeStorage> nodeStorage;
 	std::shared_ptr<CNeighbourFinder> neighbourFinder;
 	std::vector<std::shared_ptr<IPathfindingRule>> rules;
 	PathfinderOptions options;
 
 	CPathfinderConfig(
-		std::shared_ptr<CNodeHelper> nodeHelper,
+		std::shared_ptr<CNodeStorage> nodeStorage,
 		std::shared_ptr<CNeighbourFinder> neighbourFinder,
 		std::vector<std::shared_ptr<IPathfindingRule>> rules);
 };