- attempt to further improve pathfinder performance when MANY units are on the map

This commit is contained in:
Mark Vejvoda 2010-10-26 06:43:42 +00:00
parent 8bbbe403ad
commit c47b6c676c
5 changed files with 193 additions and 39 deletions

View File

@ -38,43 +38,34 @@ namespace Glest{ namespace Game{
const int PathFinder::maxFreeSearchRadius= 10; const int PathFinder::maxFreeSearchRadius= 10;
//const int PathFinder::pathFindNodesMax= 400; //const int PathFinder::pathFindNodesMax= 400;
const int PathFinder::pathFindNodesMax= 500; const int PathFinder::pathFindNodesMax= 300;
//const int PathFinder::pathFindRefresh= 10; const int PathFinder::pathFindRefresh= 10;
const int PathFinder::pathFindRefresh= 5;
PathFinder::PathFinder() { PathFinder::PathFinder() {
//nodePool= NULL;
nodePool.clear(); nodePool.clear();
map=NULL; map=NULL;
} }
PathFinder::PathFinder(const Map *map) { PathFinder::PathFinder(const Map *map) {
//nodePool= NULL;
nodePool.clear(); nodePool.clear();
map=NULL; map=NULL;
init(map); init(map);
} }
void PathFinder::init(const Map *map) { void PathFinder::init(const Map *map) {
//if(nodePool != NULL) {
// delete [] nodePool;
// nodePool = NULL;
//}
//nodePool= new Node[pathFindNodesMax];
nodePool.resize(pathFindNodesMax); nodePool.resize(pathFindNodesMax);
this->map= map; this->map= map;
} }
PathFinder::~PathFinder(){ PathFinder::~PathFinder(){
//delete [] nodePool;
//nodePool = NULL;
nodePool.clear(); nodePool.clear();
map=NULL; map=NULL;
} }
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) { TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) {
Chrono chrono;
chrono.start();
if(map == NULL) { if(map == NULL) {
throw runtime_error("map == NULL"); throw runtime_error("map == NULL");
@ -85,6 +76,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
//if arrived //if arrived
unit->setCurrSkill(scStop); unit->setCurrSkill(scStop);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
string commandDesc = "none"; string commandDesc = "none";
Command *command= unit->getCurrCommand(); Command *command= unit->getCurrCommand();
@ -96,7 +89,12 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
unit->setCurrentUnitTitle(szBuf); unit->setCurrentUnitTitle(szBuf);
} }
//unit->getFaction()->addCachedPath(finalPos,unit); if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
unit->getFaction()->addCachedPath(finalPos,unit);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
return tsArrived; return tsArrived;
} }
else { else {
@ -105,9 +103,18 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
//route cache //route cache
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path); UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
Vec2i pos= basicPath->pop(); Vec2i pos= basicPath->pop();
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
if(map->canMove(unit, unit->getPos(), pos)) { if(map->canMove(unit, unit->getPos(), pos)) {
unit->setTargetPos(pos); unit->setTargetPos(pos);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
unit->addCurrentTargetPathTakenCell(finalPos,pos); unit->addCurrentTargetPathTakenCell(finalPos,pos);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
return tsMoving; return tsMoving;
} }
} }
@ -128,12 +135,31 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
} }
TravelState ts = tsImpossible; TravelState ts = tsImpossible;
//route cache miss
ts = aStar(unit, finalPos, false);
/* if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
if(cachedPath.size() > 0) {
}
else {
//route cache miss
ts = aStar(unit, finalPos, false);
}
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
if(ts == tsBlocked) { if(ts == tsBlocked) {
std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
//if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
if(cachedPath.size() > 0) { if(cachedPath.size() > 0) {
path->clear(); path->clear();
@ -142,19 +168,26 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
} }
ts = tsMoving; ts = tsMoving;
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1)); unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1));
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, ts = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),ts, unit->getFullName().c_str(),unit->getType()->getSize());
} }
} }
*/
//post actions //post actions
switch(ts) { switch(ts) {
case tsBlocked: case tsBlocked:
case tsArrived: case tsArrived:
//if(ts == tsArrived) { if(ts == tsArrived) {
// unit->getFaction()->addCachedPath(finalPos,unit); if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
//}
unit->getFaction()->addCachedPath(finalPos,unit);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
}
// The unit is stuck (not only blocked but unable to go anywhere for a while) // The unit is stuck (not only blocked but unable to go anywhere for a while)
// We will try to bail out of the immediate area // We will try to bail out of the immediate area
@ -165,6 +198,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
} }
unit->setInBailOutAttempt(true); unit->setInBailOutAttempt(true);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
// Try to bail out up to 20 cells away // Try to bail out up to 20 cells away
for(int bailoutX = -20; bailoutX <= 20 && ts == tsBlocked; ++bailoutX) { for(int bailoutX = -20; bailoutX <= 20 && ts == tsBlocked; ++bailoutX) {
for(int bailoutY = -20; bailoutY <= 20 && ts == tsBlocked; ++bailoutY) { for(int bailoutY = -20; bailoutY <= 20 && ts == tsBlocked; ++bailoutY) {
@ -213,6 +248,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
} }
} }
unit->setInBailOutAttempt(false); unit->setInBailOutAttempt(false);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
//if(ts == tsArrived) { //if(ts == tsArrived) {
// ts = tsBlocked; // ts = tsBlocked;
@ -227,9 +263,17 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(dynamic_cast<UnitPathBasic *>(path) != NULL) { if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path); UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
Vec2i pos= basicPath->pop(); Vec2i pos= basicPath->pop();
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
if(map->canMove(unit, unit->getPos(), pos)) { if(map->canMove(unit, unit->getPos(), pos)) {
unit->setTargetPos(pos); unit->setTargetPos(pos);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
unit->addCurrentTargetPathTakenCell(finalPos,pos); unit->addCurrentTargetPathTakenCell(finalPos,pos);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),unit->getFullName().c_str(),unit->getType()->getSize());
} }
else { else {
unit->setCurrSkill(scStop); unit->setCurrSkill(scStop);
@ -269,6 +313,11 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
} }
nodePoolCount= 0; nodePoolCount= 0;
openNodesList.clear();
//closedNodes.clear();
openPosList.clear();
closedNodesList.clear();
const Vec2i finalPos= computeNearestFreePos(unit, targetPos); const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
//if arrived //if arrived
@ -306,7 +355,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
firstNode->pos= unitPos; firstNode->pos= unitPos;
firstNode->heuristic= heuristic(unitPos, finalPos); firstNode->heuristic= heuristic(unitPos, finalPos);
firstNode->exploredCell= true; firstNode->exploredCell= true;
openNodes.push_back(firstNode); //openNodes.push_back(firstNode);
openNodesList[firstNode->heuristic].push_back(firstNode);
openPosList[firstNode->pos] = true;
//b) loop //b) loop
bool pathFound= true; bool pathFound= true;
@ -315,17 +366,23 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); //if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
// This cache stores the units free cell movement calcs during the looping below
std::map<Vec2i,std::map<Vec2i, bool> > localCacheForUnitCellMovement;
int whileLoopCount = 0;
while(nodeLimitReached == false) { while(nodeLimitReached == false) {
whileLoopCount++;
//b1) is open nodes is empty => failed to find the path //b1) is open nodes is empty => failed to find the path
if(openNodes.empty() == true) { //if(openNodes.empty() == true) {
if(openNodesList.empty() == true) {
pathFound= false; pathFound= false;
break; break;
} }
//b2) get the minimum heuristic node //b2) get the minimum heuristic node
Nodes::iterator it = minHeuristic(); //Nodes::iterator it = minHeuristic();
node= *it; //node= *it;
node = minHeuristicFastLookup();
//b3) if minHeuristic is the finalNode, or the path is no more explored => path was found //b3) if minHeuristic is the finalNode, or the path is no more explored => path was found
if(node->pos == finalPos || node->exploredCell == false) { if(node->pos == finalPos || node->exploredCell == false) {
@ -335,12 +392,27 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
//b4) move this node from closedNodes to openNodes //b4) move this node from closedNodes to openNodes
//add all succesors that are not in closedNodes or openNodes to openNodes //add all succesors that are not in closedNodes or openNodes to openNodes
closedNodes.push_back(node); //closedNodes.push_back(node);
openNodes.erase(it); closedNodesList[node->heuristic].push_back(node);
openPosList[node->pos] = true;
//openNodes.erase(it);
for(int i = -1; i <= 1 && nodeLimitReached == false; ++i) { for(int i = -1; i <= 1 && nodeLimitReached == false; ++i) {
for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) { for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) {
Vec2i sucPos= node->pos + Vec2i(i, j); Vec2i sucPos= node->pos + Vec2i(i, j);
if(openPos(sucPos) == false && map->aproxCanMove(unit, node->pos, sucPos)) {
bool canUnitMoveToCell = false;
std::map<Vec2i,std::map<Vec2i, bool> >::iterator iterFind = localCacheForUnitCellMovement.find(node->pos);
if(iterFind != localCacheForUnitCellMovement.end() &&
iterFind->second.find(sucPos) != iterFind->second.end()) {
canUnitMoveToCell = iterFind->second.find(sucPos)->second;
}
else {
canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
localCacheForUnitCellMovement[node->pos][sucPos] = canUnitMoveToCell;
}
if(openPos(sucPos) == false && canUnitMoveToCell == true) {
//if node is not open and canMove then generate another node //if node is not open and canMove then generate another node
Node *sucNode= newNode(); Node *sucNode= newNode();
if(sucNode != NULL) { if(sucNode != NULL) {
@ -349,7 +421,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
sucNode->prev= node; sucNode->prev= node;
sucNode->next= NULL; sucNode->next= NULL;
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam()); sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
openNodes.push_back(sucNode); //openNodes.push_back(sucNode);
openNodesList[sucNode->heuristic].push_back(sucNode);
openPosList[sucNode->pos] = true;
} }
else { else {
nodeLimitReached= true; nodeLimitReached= true;
@ -357,19 +431,30 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
} }
} }
} }
}//while } //while
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, openNodes.size() = %d, pathFound = %d, nodeLimitReached = %d, unit = %s\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),openNodes.size(),pathFound,nodeLimitReached,unit->getFullName().c_str()); //if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, openNodes.size() = %d, closedNodes.size() = %d, pathFound = %d, nodeLimitReached = %d, whileLoopCount = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),openNodes.size(),closedNodes.size(),pathFound,nodeLimitReached,whileLoopCount,unit->getFullName().c_str(),unit->getType()->getSize());
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld, openNodesList.size() = %d, closedNodesList.size() = %d, pathFound = %d, nodeLimitReached = %d, whileLoopCount = %d, unit = %s [size = %d]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),openNodesList.size(),closedNodesList.size(),pathFound,nodeLimitReached,whileLoopCount,unit->getFullName().c_str(),unit->getType()->getSize());
Node *lastNode= node; Node *lastNode= node;
//if consumed all nodes find best node (to avoid strange behaviour) //if consumed all nodes find best node (to avoid strange behaviour)
if(nodeLimitReached == true) { if(nodeLimitReached == true) {
if(closedNodesList.size() > 0) {
float bestHeuristic = closedNodesList.begin()->first;
if(bestHeuristic < lastNode->heuristic) {
lastNode= closedNodesList.begin()->second[0];
}
}
/*
for(Nodes::iterator it= closedNodes.begin(); it != closedNodes.end(); ++it) { for(Nodes::iterator it= closedNodes.begin(); it != closedNodes.end(); ++it) {
if((*it)->heuristic < lastNode->heuristic) { if((*it)->heuristic < lastNode->heuristic) {
lastNode= *it; lastNode= *it;
} }
} }
*/
} }
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); //if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -430,8 +515,11 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(chrono.getMillis() > 2) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); if(chrono.getMillis() > 2) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//clean nodes //clean nodes
openNodes.clear(); //openNodes.clear();
closedNodes.clear(); openNodesList.clear();
//closedNodes.clear();
openPosList.clear();
closedNodesList.clear();
return ts; return ts;
} }
@ -491,7 +579,23 @@ float PathFinder::heuristic(const Vec2i &pos, const Vec2i &finalPos) {
return pos.dist(finalPos); return pos.dist(finalPos);
} }
PathFinder::Node * PathFinder::minHeuristicFastLookup() {
assert(openNodesList.empty() == false);
if(openNodesList.empty() == true) {
throw runtime_error("openNodesList.empty() == true");
}
Node *result = openNodesList.begin()->second[0];
openNodesList.begin()->second.erase(openNodesList.begin()->second.begin());
if(openNodesList.begin()->second.size() == 0) {
openNodesList.erase(openNodesList.begin());
}
return result;
}
//returns an iterator to the lowest heuristic node //returns an iterator to the lowest heuristic node
/*
PathFinder::Nodes::iterator PathFinder::minHeuristic() { PathFinder::Nodes::iterator PathFinder::minHeuristic() {
assert(openNodes.empty() == false); assert(openNodes.empty() == false);
@ -509,9 +613,15 @@ PathFinder::Nodes::iterator PathFinder::minHeuristic() {
return minNodeIt; return minNodeIt;
} }
*/
bool PathFinder::openPos(const Vec2i &sucPos) { bool PathFinder::openPos(const Vec2i &sucPos) {
if(openPosList.find(sucPos) == openPosList.end()) {
return false;
}
return true;
/*
for(Nodes::reverse_iterator it= closedNodes.rbegin(); it != closedNodes.rend(); ++it) { for(Nodes::reverse_iterator it= closedNodes.rbegin(); it != closedNodes.rend(); ++it) {
if(sucPos == (*it)->pos) { if(sucPos == (*it)->pos) {
return true; return true;
@ -526,6 +636,7 @@ bool PathFinder::openPos(const Vec2i &sucPos) {
} }
return false; return false;
*/
} }
}} //end namespace }} //end namespace

View File

@ -15,6 +15,7 @@
#include "vec.h" #include "vec.h"
#include <vector> #include <vector>
#include <map>
#include "game_constants.h" #include "game_constants.h"
#include "leak_dumper.h" #include "leak_dumper.h"
@ -56,8 +57,12 @@ public:
static const int pathFindRefresh; static const int pathFindRefresh;
private: private:
Nodes openNodes; //Nodes openNodes;
Nodes closedNodes; //Nodes closedNodes;
std::map<Vec2i, bool> openPosList;
std::map<float, Nodes> openNodesList;
std::map<float, Nodes> closedNodesList;
//Node *nodePool; //Node *nodePool;
std::vector<Node> nodePool; std::vector<Node> nodePool;
int nodePoolCount; int nodePoolCount;
@ -75,8 +80,10 @@ private:
Node *newNode(); Node *newNode();
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos); Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
float heuristic(const Vec2i &pos, const Vec2i &finalPos); float heuristic(const Vec2i &pos, const Vec2i &finalPos);
Nodes::iterator minHeuristic(); //Nodes::iterator minHeuristic();
bool openPos(const Vec2i &sucPos); bool openPos(const Vec2i &sucPos);
Node * minHeuristicFastLookup();
}; };
}}//end namespace }}//end namespace

View File

@ -376,8 +376,13 @@ void Commander::giveNetworkCommandSpecial(const NetworkCommand* networkCommand)
*/ */
void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const { void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const {
Chrono chrono;
chrono.start();
networkCommand->preprocessNetworkCommand(this->world); networkCommand->preprocessNetworkCommand(this->world);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
/* /*
if(networkCommand->getNetworkCommandType() == nctNetworkCommand) { if(networkCommand->getNetworkCommandType() == nctNetworkCommand) {
giveNetworkCommandSpecial(networkCommand); giveNetworkCommandSpecial(networkCommand);
@ -387,6 +392,8 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const {
{ {
Unit* unit= world->findUnitById(networkCommand->getUnitId()); Unit* unit= world->findUnitById(networkCommand->getUnitId());
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
//execute command, if unit is still alive //execute command, if unit is still alive
if(unit != NULL) { if(unit != NULL) {
switch(networkCommand->getNetworkCommandType()) { switch(networkCommand->getNetworkCommandType()) {
@ -397,22 +404,32 @@ void Commander::giveNetworkCommand(NetworkCommand* networkCommand) const {
Command* command= buildCommand(networkCommand); Command* command= buildCommand(networkCommand);
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] command = %p\n",__FILE__,__FUNCTION__,__LINE__,command); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] command = %p\n",__FILE__,__FUNCTION__,__LINE__,command);
unit->giveCommand(command, (networkCommand->getWantQueue() != 0)); unit->giveCommand(command, (networkCommand->getWantQueue() != 0));
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkCommand->getUnitId());
} }
break; break;
case nctCancelCommand: { case nctCancelCommand: {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctCancelCommand\n",__FILE__,__FUNCTION__,__LINE__); if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
unit->cancelCommand(); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctCancelCommand\n",__FILE__,__FUNCTION__,__LINE__);
unit->cancelCommand();
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctCancelCommand\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctCancelCommand\n",__FILE__,__FUNCTION__,__LINE__);
} }
break; break;
case nctSetMeetingPoint: { case nctSetMeetingPoint: {
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
unit->setMeetingPos(networkCommand->getPosition()); unit->setMeetingPos(networkCommand->getPosition());
if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),networkCommand->toString().c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found nctSetMeetingPoint\n",__FILE__,__FUNCTION__,__LINE__);
} }
break; break;

View File

@ -88,6 +88,10 @@ private:
std::map<Vec2i,bool> cachedCloseResourceTargetLookupList; std::map<Vec2i,bool> cachedCloseResourceTargetLookupList;
time_t lastResourceTargettListPurge; time_t lastResourceTargettListPurge;
// This cache stores the units free cell movement calcs during a world
// update of the faction
//std::map<int,std::map<Field, std::map<Vec2i,std::map<Vec2i, > > > localCacheForUnitCellMovement;
public: public:
Faction(); Faction();
~Faction(); ~Faction();

View File

@ -610,6 +610,8 @@ void UnitUpdater::updateHarvest(Unit *unit) {
throw runtime_error("detected unsupported pathfinder type!"); throw runtime_error("detected unsupported pathfinder type!");
} }
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if (canHarvestDestPos == true) { if (canHarvestDestPos == true) {
unit->setLastHarvestResourceTarget(NULL); unit->setLastHarvestResourceTarget(NULL);
@ -633,8 +635,12 @@ void UnitUpdater::updateHarvest(Unit *unit) {
throw runtime_error("detected unsupported pathfinder type!"); throw runtime_error("detected unsupported pathfinder type!");
} }
} }
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
} }
if(canHarvestDestPos == false) { if(canHarvestDestPos == false) {
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
unit->setLastHarvestResourceTarget(&targetPos); unit->setLastHarvestResourceTarget(&targetPos);
//if not continue walking //if not continue walking
@ -657,6 +663,8 @@ void UnitUpdater::updateHarvest(Unit *unit) {
throw runtime_error("detected unsupported pathfinder type!"); throw runtime_error("detected unsupported pathfinder type!");
} }
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
// If the unit is blocked or Even worse 'stuck' then try to // If the unit is blocked or Even worse 'stuck' then try to
// find the same resource type elsewhere, but close by // find the same resource type elsewhere, but close by
if((wasStuck == true || tsValue == tsBlocked) && unit->isAlive() == true) { if((wasStuck == true || tsValue == tsBlocked) && unit->isAlive() == true) {
@ -678,6 +686,8 @@ void UnitUpdater::updateHarvest(Unit *unit) {
throw runtime_error("detected unsupported pathfinder type!"); throw runtime_error("detected unsupported pathfinder type!");
} }
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if (canHarvestDestPos == true) { if (canHarvestDestPos == true) {
unit->setLastHarvestResourceTarget(NULL); unit->setLastHarvestResourceTarget(NULL);
@ -702,6 +712,9 @@ void UnitUpdater::updateHarvest(Unit *unit) {
} }
} }
} }
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(canHarvestDestPos == false) { if(canHarvestDestPos == false) {
unit->setLastHarvestResourceTarget(&targetPos); unit->setLastHarvestResourceTarget(&targetPos);
@ -729,6 +742,8 @@ void UnitUpdater::updateHarvest(Unit *unit) {
} }
} }
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(wasStuck == true) { if(wasStuck == true) {
//if can't harvest, search for another resource //if can't harvest, search for another resource
unit->setCurrSkill(scStop); unit->setCurrSkill(scStop);