- attempt to see if threaded pathfinding will work and if it improves performance

This commit is contained in:
Mark Vejvoda 2011-03-18 03:53:06 +00:00
parent e65f588045
commit 07f56669b7
12 changed files with 1054 additions and 524 deletions

View File

@ -45,12 +45,19 @@ const int PathFinder::pathFindBailoutRadius = 20;
PathFinder::PathFinder() {
nodePool.clear();
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions.push_back(FactionState());
}
//nodePool.clear();
map=NULL;
}
PathFinder::PathFinder(const Map *map) {
nodePool.clear();
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions.push_back(FactionState());
}
//nodePool.clear();
map=NULL;
init(map);
@ -58,22 +65,35 @@ PathFinder::PathFinder(const Map *map) {
void PathFinder::init(const Map *map) {
PathFinder::pathFindNodesMax = Config::getInstance().getInt("MaxPathfinderNodeCount",intToStr(PathFinder::pathFindNodesMax).c_str());
nodePool.resize(pathFindNodesMax);
useMaxNodeCount = PathFinder::pathFindNodesMax;
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions[i].nodePool.resize(pathFindNodesMax);
factions[i].useMaxNodeCount = PathFinder::pathFindNodesMax;
}
this->map= map;
}
PathFinder::~PathFinder() {
nodePool.clear();
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions[i].nodePool.clear();
}
map=NULL;
}
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) {
void PathFinder::clearUnitPrecache(Unit *unit) {
factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] = tsImpossible;
factions[unit->getFactionIndex()].precachedPath[unit->getId()].clear();
}
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck, int frameIndex) {
//printf("PathFinder::findPath...\n");
if(map == NULL) {
throw runtime_error("map == NULL");
}
if(frameIndex >= 0) {
clearUnitPrecache(unit);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
@ -83,11 +103,11 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
}
//route cache
UnitPathInterface *path= unit->getPath();
if(finalPos == unit->getPos()) {
if(frameIndex < 0) {
//if arrived
unit->setCurrSkill(scStop);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
string commandDesc = "none";
Command *command= unit->getCurrCommand();
@ -102,17 +122,19 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
//unit->getFaction()->addCachedPath(finalPos,unit);
return tsArrived;
}
else {
UnitPathInterface *path= unit->getPath();
if(path->isEmpty() == false) {
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
//route cache
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
Vec2i pos= basicPath->pop();
Vec2i pos= basicPath->pop(frameIndex < 0);
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
unit->setTargetPos(pos);
unit->addCurrentTargetPathTakenCell(finalPos,pos);
}
return tsMoving;
}
}
@ -120,10 +142,11 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
//route cache
Vec2i pos= advPath->peek();
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
advPath->pop();
unit->setTargetPos(pos);
}
return tsMoving;
}
}
@ -131,7 +154,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
throw runtime_error("unsupported or missing path finder detected!");
}
}
}
TravelState ts = tsImpossible;
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
@ -144,10 +167,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
//}
//else {
//route cache miss
ts = aStar(unit, finalPos, false);
ts = aStar(unit, finalPos, false, frameIndex);
//}
if(ts == tsBlocked) {
//if(ts == tsBlocked) {
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
//if(cachedPath.size() > 0) {
// path->clear();
@ -158,16 +181,16 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
// ts = tsMoving;
// unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1));
//}
}
//}
//post actions
switch(ts) {
case tsBlocked:
case tsArrived:
if(ts == tsArrived) {
//if(ts == tsArrived) {
//unit->getFaction()->addCachedPath(finalPos,unit);
}
//}
// 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
@ -224,7 +247,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(useBailoutRadius == true) {
//int tryRadius = random.randRange(-PathFinder::pathFindBailoutRadius, PathFinder::pathFindBailoutRadius);
int tryRadius = random.randRange(0,1);
int tryRadius = factions[unit->getFactionIndex()].random.randRange(0,1);
//printf("#4 BAILOUT test unitid [%d] useBailoutRadius [%d] tryRadius [%d]\n",unit->getId(),useBailoutRadius,tryRadius);
@ -243,7 +266,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
}
if(canUnitMove) {
ts= aStar(unit, newFinalPos, true);
ts= aStar(unit, newFinalPos, true, frameIndex);
}
}
}
@ -262,7 +285,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
}
if(canUnitMove) {
ts= aStar(unit, newFinalPos, true);
ts= aStar(unit, newFinalPos, true, frameIndex);
}
}
}
@ -271,35 +294,50 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
unit->setInBailOutAttempt(false);
}
if(ts == tsArrived || ts == tsBlocked) {
if(frameIndex < 0) {
unit->setCurrSkill(scStop);
}
}
break;
case tsMoving:
{
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
Vec2i pos= basicPath->pop();
Vec2i pos;
if(frameIndex < 0) {
pos = basicPath->pop(frameIndex < 0);
}
else {
pos = factions[unit->getFactionIndex()].precachedPath[unit->getId()][0];
}
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
unit->setTargetPos(pos);
unit->addCurrentTargetPathTakenCell(finalPos,pos);
}
}
else {
if(frameIndex < 0) {
unit->setCurrSkill(scStop);
}
return tsBlocked;
}
}
else if(dynamic_cast<UnitPath *>(path) != NULL) {
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
Vec2i pos= advPath->peek();
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
advPath->pop();
unit->setTargetPos(pos);
}
}
else {
if(frameIndex < 0) {
unit->setCurrSkill(scStop);
}
return tsBlocked;
}
}
@ -319,20 +357,20 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
bool result = false;
Vec2i sucPos= node->pos + Vec2i(i, j);
bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
if(openPos(sucPos) == false && canUnitMoveToCell == true) {
if(openPos(sucPos, factions[unit->getFactionIndex()]) == false && canUnitMoveToCell == true) {
//if node is not open and canMove then generate another node
Node *sucNode= newNode();
Node *sucNode= newNode(factions[unit->getFactionIndex()]);
if(sucNode != NULL) {
sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
sucNode->prev= node;
sucNode->next= NULL;
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
if(openNodesList.find(sucNode->heuristic) == openNodesList.end()) {
openNodesList[sucNode->heuristic].clear();
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
}
openNodesList[sucNode->heuristic].push_back(sucNode);
openPosList[sucNode->pos] = true;
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
result = true;
}
@ -344,7 +382,8 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
}
//route a unit using A* algorithm
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout) {
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout,
int frameIndex) {
//printf("PathFinder::aStar...\n");
Chrono chrono;
@ -354,18 +393,78 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
throw runtime_error("map == NULL");
}
nodePoolCount= 0;
openNodesList.clear();
openPosList.clear();
closedNodesList.clear();
UnitPathInterface *path= unit->getPath();
factions[unit->getFactionIndex()].nodePoolCount= 0;
factions[unit->getFactionIndex()].openNodesList.clear();
factions[unit->getFactionIndex()].openPosList.clear();
factions[unit->getFactionIndex()].closedNodesList.clear();
TravelState ts = tsImpossible;
if(frameIndex < 0) {
if(factions[unit->getFactionIndex()].precachedTravelState.find(unit->getId()) != factions[unit->getFactionIndex()].precachedTravelState.end()) {
if(factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] == tsMoving) {
bool canMoveToCells = true;
Vec2i lastPos = unit->getPos();
for(int i=0; i < factions[unit->getFactionIndex()].precachedPath[unit->getId()].size(); i++) {
Vec2i nodePos = factions[unit->getFactionIndex()].precachedPath[unit->getId()][i];
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
}
if(i < pathFindRefresh) {
if(map->aproxCanMove(unit, lastPos, nodePos) == false) {
canMoveToCells = false;
break;
}
lastPos = nodePos;
}
else {
break;
}
}
if(canMoveToCells == true) {
path->clear();
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
for(int i=0; i < factions[unit->getFactionIndex()].precachedPath[unit->getId()].size(); i++) {
Vec2i nodePos = factions[unit->getFactionIndex()].precachedPath[unit->getId()][i];
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
}
if(i < pathFindRefresh) {
path->add(nodePos);
}
else {
break;
}
}
return factions[unit->getFactionIndex()].precachedTravelState[unit->getId()];
}
else {
clearUnitPrecache(unit);
}
}
else if(factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] == tsBlocked) {
path->incBlockCount();
return factions[unit->getFactionIndex()].precachedTravelState[unit->getId()];
}
}
}
else {
clearUnitPrecache(unit);
}
const Vec2i unitPos = unit->getPos();
const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
float dist= unitPos.dist(finalPos);
useMaxNodeCount = PathFinder::pathFindNodesMax;
factions[unit->getFactionIndex()].useMaxNodeCount = PathFinder::pathFindNodesMax;
// if(dist <= 10) {
// useMaxNodeCount = (int)dist * 20;
// if(useMaxNodeCount <= 0) {
@ -375,7 +474,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
UnitPathInterface *path= unit->getPath();
// Check the previous path find cache for the unit to see if its good to
// use
const bool showConsoleDebugInfo = Config::getInstance().getBool("EnablePathfinderDistanceOutput","false");
@ -422,7 +520,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
@ -470,7 +568,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
@ -506,7 +604,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
//path find algorithm
//a) push starting pos into openNodes
Node *firstNode= newNode();
Node *firstNode= newNode(factions[unit->getFactionIndex()]);
assert(firstNode != NULL);
if(firstNode == NULL) {
throw runtime_error("firstNode == NULL");
@ -517,11 +615,11 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
firstNode->pos= unitPos;
firstNode->heuristic= heuristic(unitPos, finalPos);
firstNode->exploredCell= true;
if(openNodesList.find(firstNode->heuristic) == openNodesList.end()) {
openNodesList[firstNode->heuristic].clear();
if(factions[unit->getFactionIndex()].openNodesList.find(firstNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
factions[unit->getFactionIndex()].openNodesList[firstNode->heuristic].clear();
}
openNodesList[firstNode->heuristic].push_back(firstNode);
openPosList[firstNode->pos] = true;
factions[unit->getFactionIndex()].openNodesList[firstNode->heuristic].push_back(firstNode);
factions[unit->getFactionIndex()].openPosList[firstNode->pos] = true;
//b) loop
bool pathFound = true;
@ -592,14 +690,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
whileLoopCount++;
//b1) is open nodes is empty => failed to find the path
if(openNodesList.empty() == true) {
if(factions[unit->getFactionIndex()].openNodesList.empty() == true) {
pathFound= false;
break;
}
//b2) get the minimum heuristic node
//Nodes::iterator it = minHeuristic();
node = minHeuristicFastLookup();
node = minHeuristicFastLookup(factions[unit->getFactionIndex()]);
//b3) if minHeuristic is the finalNode, or the path is no more explored => path was found
if(node->pos == finalPos || node->exploredCell == false) {
@ -609,16 +707,16 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
//b4) move this node from closedNodes to openNodes
//add all succesors that are not in closedNodes or openNodes to openNodes
if(closedNodesList.find(node->heuristic) == closedNodesList.end()) {
closedNodesList[node->heuristic].clear();
if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
factions[unit->getFactionIndex()].closedNodesList[node->heuristic].clear();
}
closedNodesList[node->heuristic].push_back(node);
openPosList[node->pos] = true;
factions[unit->getFactionIndex()].closedNodesList[node->heuristic].push_back(node);
factions[unit->getFactionIndex()].openPosList[node->pos] = true;
int failureCount = 0;
int cellCount = 0;
int tryDirection = random.randRange(0,3);
int tryDirection = factions[unit->getFactionIndex()].random.randRange(0,3);
if(tryDirection == 3) {
for(int i = 1; i >= -1 && nodeLimitReached == false; --i) {
for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) {
@ -673,19 +771,19 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
}
} //while
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),nodeLimitReached,whileLoopCount,nodePoolCount);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),nodeLimitReached,whileLoopCount,factions[unit->getFactionIndex()].nodePoolCount);
if(showConsoleDebugInfo && chrono.getMillis() > 2) {
printf("Distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,nodePoolCount);
printf("Distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,factions[unit->getFactionIndex()].nodePoolCount);
}
Node *lastNode= node;
//if consumed all nodes find best node (to avoid strange behaviour)
if(nodeLimitReached == true) {
if(closedNodesList.size() > 0) {
float bestHeuristic = closedNodesList.begin()->first;
if(factions[unit->getFactionIndex()].closedNodesList.size() > 0) {
float bestHeuristic = factions[unit->getFactionIndex()].closedNodesList.begin()->first;
if(bestHeuristic < lastNode->heuristic) {
lastNode= closedNodesList.begin()->second[0];
lastNode= factions[unit->getFactionIndex()].closedNodesList.begin()->second[0];
}
}
}
@ -712,12 +810,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
}
ts= tsBlocked;
if(frameIndex < 0) {
path->incBlockCount();
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
sprintf(szBuf,"[path for unit BLOCKED] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
@ -737,7 +837,10 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//store path
if(frameIndex < 0) {
path->clear();
}
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
currNode= firstNode;
@ -747,6 +850,10 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
}
if(frameIndex >= 0) {
factions[unit->getFactionIndex()].precachedPath[unit->getId()].push_back(nodePos);
}
else {
if(i < pathFindRefresh) {
path->add(nodePos);
}
@ -758,13 +865,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
basicPathFinder->addToLastPathCache(nodePos);
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
unit->logSynchData(__FILE__,__LINE__,szBuf);
string pathToTake = "";
@ -794,20 +902,27 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
openNodesList.clear();
openPosList.clear();
closedNodesList.clear();
factions[unit->getFactionIndex()].openNodesList.clear();
factions[unit->getFactionIndex()].openPosList.clear();
factions[unit->getFactionIndex()].closedNodesList.clear();
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(frameIndex >= 0) {
factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] = ts;
}
else {
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 5) printf("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts);
}
return ts;
}
PathFinder::Node *PathFinder::newNode() {
if(nodePoolCount < nodePool.size() && nodePoolCount < useMaxNodeCount) {
Node *node= &nodePool[nodePoolCount];
PathFinder::Node *PathFinder::newNode(FactionState &faction) {
if( faction.nodePoolCount < faction.nodePool.size() &&
faction.nodePoolCount < faction.useMaxNodeCount) {
Node *node= &(faction.nodePool[faction.nodePoolCount]);
node->clear();
nodePoolCount++;
faction.nodePoolCount++;
return node;
}
return NULL;
@ -864,22 +979,22 @@ float PathFinder::heuristic(const Vec2i &pos, const Vec2i &finalPos) {
return pos.dist(finalPos);
}
PathFinder::Node * PathFinder::minHeuristicFastLookup() {
assert(openNodesList.empty() == false);
if(openNodesList.empty() == true) {
PathFinder::Node * PathFinder::minHeuristicFastLookup(FactionState &faction) {
assert(faction.openNodesList.empty() == false);
if(faction.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());
Node *result = faction.openNodesList.begin()->second[0];
faction.openNodesList.begin()->second.erase(faction.openNodesList.begin()->second.begin());
if(faction.openNodesList.begin()->second.size() == 0) {
faction.openNodesList.erase(faction.openNodesList.begin());
}
return result;
}
bool PathFinder::openPos(const Vec2i &sucPos) {
if(openPosList.find(sucPos) == openPosList.end()) {
bool PathFinder::openPos(const Vec2i &sucPos, FactionState &faction) {
if(faction.openPosList.find(sucPos) == faction.openPosList.end()) {
return false;
}
return true;

View File

@ -57,38 +57,59 @@ public:
};
typedef vector<Node*> Nodes;
class FactionState {
public:
FactionState() {
openPosList.clear();
openNodesList.clear();
closedNodesList.clear();
nodePool.clear();
nodePoolCount = 0;
useMaxNodeCount = 0;
precachedTravelState.clear();
precachedPath.clear();
}
std::map<Vec2i, bool> openPosList;
std::map<float, Nodes> openNodesList;
std::map<float, Nodes> closedNodesList;
std::vector<Node> nodePool;
int nodePoolCount;
RandomGen random;
int useMaxNodeCount;
std::map<int,TravelState> precachedTravelState;
std::map<int,std::vector<Vec2i> > precachedPath;
};
typedef vector<FactionState> FactionStateList;
public:
static const int maxFreeSearchRadius;
static int pathFindNodesMax;
static const int pathFindRefresh;
static const int pathFindBailoutRadius;
private:
std::map<Vec2i, bool> openPosList;
std::map<float, Nodes> openNodesList;
std::map<float, Nodes> closedNodesList;
std::vector<Node> nodePool;
int nodePoolCount;
static int pathFindNodesMax;
FactionStateList factions;
const Map *map;
RandomGen random;
int useMaxNodeCount;
public:
PathFinder();
PathFinder(const Map *map);
~PathFinder();
void init(const Map *map);
TravelState findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck=NULL);
TravelState findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck=NULL,int frameIndex=-1);
void clearUnitPrecache(Unit *unit);
private:
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout);
Node *newNode();
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex);
Node *newNode(FactionState &faction);
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
float heuristic(const Vec2i &pos, const Vec2i &finalPos);
bool openPos(const Vec2i &sucPos);
bool openPos(const Vec2i &sucPos,FactionState &faction);
Node * minHeuristicFastLookup();
Node * minHeuristicFastLookup(FactionState &faction);
bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached);
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);

View File

@ -28,6 +28,163 @@ using namespace Shared::Util;
namespace Glest { namespace Game {
// =====================================================
// class FactionThread
// =====================================================
FactionThread::FactionThread(Faction *faction) : BaseThread() {
this->faction = faction;
}
void FactionThread::setQuitStatus(bool value) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
BaseThread::setQuitStatus(value);
if(value == true) {
signalPathfinder(-1);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
void FactionThread::signalPathfinder(int frameIndex) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] event = %p\n",__FILE__,__FUNCTION__,__LINE__,event);
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p\n",__FILE__,__FUNCTION__,__LINE__,frameIndex, this);
if(frameIndex >= 0) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
this->frameIndex.first = frameIndex;
this->frameIndex.second = false;
safeMutex.ReleaseLock();
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
semTaskSignalled.signal();
}
void FactionThread::setTaskCompleted(int frameIndex) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p\n",__FILE__,__FUNCTION__,__LINE__,frameIndex, this);
if(frameIndex >= 0) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
if(this->frameIndex.first == frameIndex) {
this->frameIndex.second = true;
}
safeMutex.ReleaseLock();
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
bool FactionThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
bool ret = (getExecutingTask() == false);
if(ret == false && deleteSelfIfShutdownDelayed == true) {
setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed);
signalQuit();
}
return ret;
}
bool FactionThread::isSignalPathfinderCompleted(int frameIndex) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
if(getRunningStatus() == false) {
return true;
}
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
//bool result = (event != NULL ? event->eventCompleted : true);
bool result = (this->frameIndex.first == frameIndex && this->frameIndex.second == true);
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second);
safeMutex.ReleaseLock();
//if(result == false) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, result = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,result);
return result;
}
void FactionThread::execute() {
RunningStatusSafeWrapper runningStatus(this);
try {
//setRunningStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n",__FILE__,__FUNCTION__,__LINE__,this);
unsigned int idx = 0;
for(;this->faction != NULL;) {
if(getQuitStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
semTaskSignalled.waitTillSignalled();
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
if(getQuitStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
bool executeTask = (frameIndex.first >= 0);
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask);
safeMutex.ReleaseLock();
if(executeTask == true) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
//this->slotInterface->slotUpdateTask(&eventCopy);
World *world = faction->getWorld();
int unitCount = faction->getUnitCount();
for(int j = 0; j < unitCount; ++j) {
Unit *unit = faction->getUnit(j);
if(unit == NULL) {
throw runtime_error("unit == NULL");
}
bool update = unit->needToUpdate();
if(update == true) {
world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first);
}
}
setTaskCompleted(frameIndex.first);
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
if(getQuitStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n",__FILE__,__FUNCTION__,__LINE__,this);
}
catch(const exception &ex) {
//setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
throw runtime_error(ex.what());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
//setRunningStatus(false);
}
// =====================================================
// class Faction
// =====================================================
@ -37,6 +194,7 @@ Faction::Faction() {
//lastResourceTargettListPurge = 0;
cachingDisabled=false;
factionDisconnectHandled=false;
workerThread = NULL;
}
Faction::~Faction() {
@ -50,11 +208,33 @@ Faction::~Faction() {
//texture->end();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(workerThread != NULL) {
workerThread->signalQuit();
if(workerThread->shutdownAndWait() == true) {
delete workerThread;
}
workerThread = NULL;
}
//delete texture;
texture = NULL;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Faction::signalWorkerThread(int frameIndex) {
if(workerThread != NULL) {
workerThread->signalPathfinder(frameIndex);
}
}
bool Faction::isWorkerThreadSignalCompleted(int frameIndex) {
if(workerThread != NULL) {
return workerThread->isSignalPathfinderCompleted(frameIndex);
}
return true;
}
void Faction::init(
FactionType *factionType, ControlType control, TechTree *techTree, Game *game,
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources)
@ -84,11 +264,33 @@ void Faction::init(
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
texture->load(data_path + "data/core/faction_textures/faction"+intToStr(startLocationIndex)+".tga");
if(Config::getInstance().getBool("EnableFactionWorkerThreads","true") == true) {
if(workerThread != NULL) {
workerThread->signalQuit();
if(workerThread->shutdownAndWait() == true) {
delete workerThread;
}
workerThread = NULL;
}
this->workerThread = new FactionThread(this);
this->workerThread->setUniqueID(__FILE__);
this->workerThread->start();
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
void Faction::end() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(workerThread != NULL) {
workerThread->signalQuit();
if(workerThread->shutdownAndWait() == true) {
delete workerThread;
}
workerThread = NULL;
}
deleteValues(units.begin(), units.end());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}

View File

@ -20,12 +20,14 @@
#include "resource.h"
#include "game_constants.h"
#include "command_type.h"
#include "base_thread.h"
#include "leak_dumper.h"
using std::map;
using std::vector;
using Shared::Graphics::Texture2D;
using namespace Shared::PlatformCommon;
namespace Glest{ namespace Game{
@ -39,6 +41,7 @@ class UnitType;
class Game;
class ScriptManager;
class World;
class Faction;
// =====================================================
// class Faction
@ -54,6 +57,25 @@ public:
vector<std::pair<vector<Vec2i>, int> > pathQueue;
};
class FactionThread : public BaseThread {
protected:
Faction *faction;
Semaphore semTaskSignalled;
Mutex triggerIdMutex;
std::pair<int,bool> frameIndex;
virtual void setQuitStatus(bool value);
virtual void setTaskCompleted(int frameIndex);
virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false);
public:
FactionThread(Faction *faction);
virtual void execute();
void signalPathfinder(int frameIndex);
bool isSignalPathfinderCompleted(int frameIndex);
};
class Faction {
private:
typedef vector<Resource> Resources;
@ -98,6 +120,8 @@ private:
// update of the faction
//std::map<int,std::map<Field, std::map<Vec2i,std::map<Vec2i, > > > localCacheForUnitCellMovement;
FactionThread *workerThread;
public:
Faction();
~Faction();
@ -186,7 +210,11 @@ public:
void deletePixels();
World * getWorld() { return world; }
int getFrameCount();
void signalWorkerThread(int frameIndex);
bool isWorkerThreadSignalCompleted(int frameIndex);
std::string toString() const;
private:

View File

@ -101,12 +101,14 @@ void UnitPathBasic::addToLastPathCache(const Vec2i &path) {
lastPathCacheQueue.push_back(path);
}
Vec2i UnitPathBasic::pop() {
Vec2i UnitPathBasic::pop(bool removeFrontPos) {
if(pathQueue.size() <= 0) {
throw runtime_error("pathQueue.size() = " + intToStr(pathQueue.size()));
}
Vec2i p= pathQueue.front();
if(removeFrontPos == true) {
pathQueue.erase(pathQueue.begin());
}
return p;
}
std::string UnitPathBasic::toString() const {
@ -1105,6 +1107,60 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
return commandType;
}
bool Unit::needToUpdate() {
assert(progress <= 1.f);
if(currSkill == NULL) {
char szBuf[4096]="";
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str());
throw runtime_error(szBuf);
}
//speed
int speed = currSkill->getTotalSpeed(&totalUpgrade);
//speed modifier
float diagonalFactor= 1.f;
float heightFactor= 1.f;
if(currSkill->getClass() == scMove) {
//if moving in diagonal move slower
Vec2i dest= pos-lastPos;
if(abs(dest.x) + abs(dest.y) == 2) {
diagonalFactor= 0.71f;
}
//if movig to an higher cell move slower else move faster
float heightDiff= map->getCell(pos)->getHeight() - map->getCell(targetPos)->getHeight();
heightFactor= clamp(1.f + heightDiff / 5.f, 0.2f, 5.f);
}
//update progresses
float newProgress = progress;
const Game *game = Renderer::getInstance().getGame();
newProgress += (speed * diagonalFactor * heightFactor) / (speedDivider * game->getWorld()->getUpdateFps(this->getFactionIndex()));
//checks
bool return_value = false;
//checks
if(newProgress >= 1.f) {
if(currSkill->getClass() != scDie) {
newProgress= 0.f;
return_value = true;
}
else {
newProgress= 1.f;
int newDeadCount = deadCount;
newDeadCount++;
if(newDeadCount >= maxDeadCount) {
return_value = false;
}
}
}
return return_value;
}
bool Unit::update() {
assert(progress<=1.f);

View File

@ -147,7 +147,7 @@ public:
virtual void incBlockCount();
virtual void add(const Vec2i &path);
void addToLastPathCache(const Vec2i &path);
Vec2i pop();
Vec2i pop(bool removeFrontPos=true);
virtual int getBlockCount() const { return blockCount; }
virtual int getQueueCount() const { return pathQueue.size(); }
@ -494,6 +494,7 @@ public:
void logSynchData(string file,int line,string source="");
std::string toString() const;
bool needToUpdate();
private:
float computeHeight(const Vec2i &pos) const;

View File

@ -88,8 +88,8 @@ StopCommandType::StopCommandType(){
clicks= cOne;
}
void StopCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateStop(unit);
void StopCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateStop(unit, frameIndex);
}
string StopCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
@ -131,8 +131,8 @@ MoveCommandType::MoveCommandType(){
clicks= cTwo;
}
void MoveCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateMove(unit);
void MoveCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateMove(unit, frameIndex);
}
void MoveCommandType::load(int id, const XmlNode *n, const string &dir,
@ -180,8 +180,8 @@ AttackCommandType::AttackCommandType(){
clicks= cTwo;
}
void AttackCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateAttack(unit);
void AttackCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateAttack(unit, frameIndex);
}
void AttackCommandType::load(int id, const XmlNode *n, const string &dir,
@ -272,8 +272,8 @@ AttackStoppedCommandType::AttackStoppedCommandType(){
clicks= cOne;
}
void AttackStoppedCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateAttackStopped(unit);
void AttackStoppedCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateAttackStopped(unit, frameIndex);
}
void AttackStoppedCommandType::load(int id, const XmlNode *n, const string &dir,
@ -359,8 +359,8 @@ BuildCommandType::~BuildCommandType() {
deleteValues(startSounds.getSounds().begin(), startSounds.getSounds().end());
}
void BuildCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateBuild(unit);
void BuildCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateBuild(unit, frameIndex);
}
void BuildCommandType::load(int id, const XmlNode *n, const string &dir,
@ -457,8 +457,8 @@ HarvestCommandType::HarvestCommandType(){
clicks= cTwo;
}
void HarvestCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateHarvest(unit);
void HarvestCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateHarvest(unit, frameIndex);
}
void HarvestCommandType::load(int id, const XmlNode *n, const string &dir,
@ -538,8 +538,8 @@ RepairCommandType::RepairCommandType(){
RepairCommandType::~RepairCommandType(){
}
void RepairCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateRepair(unit);
void RepairCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateRepair(unit, frameIndex);
}
void RepairCommandType::load(int id, const XmlNode *n, const string &dir,
@ -615,8 +615,8 @@ ProduceCommandType::ProduceCommandType(){
clicks= cOne;
}
void ProduceCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateProduce(unit);
void ProduceCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateProduce(unit, frameIndex);
}
void ProduceCommandType::load(int id, const XmlNode *n, const string &dir,
@ -680,8 +680,8 @@ UpgradeCommandType::UpgradeCommandType(){
clicks= cOne;
}
void UpgradeCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateUpgrade(unit);
void UpgradeCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateUpgrade(unit, frameIndex);
}
void UpgradeCommandType::load(int id, const XmlNode *n, const string &dir,
@ -737,8 +737,8 @@ MorphCommandType::MorphCommandType(){
clicks= cOne;
}
void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
unitUpdater->updateMorph(unit);
void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
unitUpdater->updateMorph(unit, frameIndex);
}
void MorphCommandType::load(int id, const XmlNode *n, const string &dir,

View File

@ -80,7 +80,7 @@ public:
clicks = cOne;
id = -1;
}
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const= 0;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const= 0;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -115,7 +115,7 @@ private:
public:
StopCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt,
const FactionType *ft, const UnitType &ut, std::map<string,int> &loadedFileList);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
@ -137,7 +137,7 @@ private:
public:
MoveCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -160,7 +160,7 @@ private:
public:
AttackCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -184,7 +184,7 @@ private:
public:
AttackStoppedCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -212,7 +212,7 @@ private:
public:
BuildCommandType();
~BuildCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -245,7 +245,7 @@ private:
public:
HarvestCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -279,7 +279,7 @@ private:
public:
RepairCommandType();
~RepairCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -308,7 +308,7 @@ private:
public:
ProduceCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -335,7 +335,7 @@ private:
public:
UpgradeCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);
@ -362,7 +362,7 @@ private:
public:
MorphCommandType();
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList);

View File

@ -83,6 +83,12 @@ void UnitUpdater::init(Game *game){
}
}
void UnitUpdater::clearUnitPrecache(Unit *unit) {
if(pathFinder != NULL) {
pathFinder->clearUnitPrecache(unit);
}
}
UnitUpdater::~UnitUpdater() {
//UnitRangeCellsLookupItemCache.clear();
@ -139,7 +145,7 @@ void UnitUpdater::updateUnit(Unit *unit) {
if(update == true) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
updateUnitCommand(unit);
updateUnitCommand(unit,-1);
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after updateUnitCommand()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -236,7 +242,12 @@ void UnitUpdater::updateUnit(Unit *unit) {
// ==================== progress commands ====================
//VERY IMPORTANT: compute next state depending on the first order of the list
void UnitUpdater::updateUnitCommand(Unit *unit) {
void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) {
// Clear previous cached unit data
if(frameIndex >= 0) {
clearUnitPrecache(unit);
}
Chrono chrono;
chrono.start();
@ -245,11 +256,12 @@ void UnitUpdater::updateUnitCommand(Unit *unit) {
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit [%s] has command [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str(), unit->getCurrCommand()->toString().c_str());
CommandClass cc = unit->getCurrCommand()->getCommandType()->commandTypeClass;
unit->getCurrCommand()->getCommandType()->update(this, unit);
unit->getCurrCommand()->getCommandType()->update(this, unit, frameIndex);
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
if(frameIndex < 0) {
//if no commands stop and add stop command
if(unit->anyCommand() == false && unit->isOperative()) {
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -260,13 +272,19 @@ void UnitUpdater::updateUnitCommand(Unit *unit) {
unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccStop)));
}
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
// ==================== updateStop ====================
void UnitUpdater::updateStop(Unit *unit) {
void UnitUpdater::updateStop(Unit *unit, int frameIndex) {
// Nothing to do
if(frameIndex >= 0) {
clearUnitPrecache(unit);
return;
}
Chrono chrono;
chrono.start();
@ -329,7 +347,7 @@ void UnitUpdater::updateStop(Unit *unit) {
// ==================== updateMove ====================
void UnitUpdater::updateMove(Unit *unit) {
void UnitUpdater::updateMove(Unit *unit, int frameIndex) {
Chrono chrono;
chrono.start();
@ -349,7 +367,7 @@ void UnitUpdater::updateMove(Unit *unit) {
TravelState tsValue = tsImpossible;
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, pos);
tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
break;
case pfRoutePlanner:
tsValue = routePlanner->findPath(unit, pos);
@ -360,6 +378,7 @@ void UnitUpdater::updateMove(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(frameIndex < 0) {
switch (tsValue) {
case tsMoving:
unit->setCurrSkill(mct->getMoveSkillType());
@ -375,14 +394,14 @@ void UnitUpdater::updateMove(Unit *unit) {
default:
unit->finishCommand();
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
// ==================== updateAttack ====================
void UnitUpdater::updateAttack(Unit *unit) {
void UnitUpdater::updateAttack(Unit *unit, int frameIndex) {
Chrono chrono;
chrono.start();
@ -392,14 +411,17 @@ void UnitUpdater::updateAttack(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( (command->getUnit()==NULL || !(command->getUnit()->isAlive()) ) && unit->getCommandSize()>1)
{
if( (command->getUnit() == NULL || !(command->getUnit()->isAlive()) ) && unit->getCommandSize() > 1) {
if(frameIndex < 0) {
unit->finishCommand(); // all queued "ground attacks" are skipped if somthing else is queued after them.
}
return;
}
//if found
if(attackableOnRange(unit, &target, act->getAttackSkillType())) {
if(frameIndex < 0) {
if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) {
unit->setCurrSkill(act->getAttackSkillType());
unit->setTarget(target);
@ -407,7 +429,7 @@ void UnitUpdater::updateAttack(Unit *unit) {
else {
unit->setCurrSkill(scStop);
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
else {
@ -435,7 +457,7 @@ void UnitUpdater::updateAttack(Unit *unit) {
TravelState tsValue = tsImpossible;
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, pos);
tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex);
break;
case pfRoutePlanner:
tsValue = routePlanner->findPath(unit, pos);
@ -446,9 +468,9 @@ void UnitUpdater::updateAttack(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(command->getUnit()!=NULL && !command->getUnit()->isAlive() && unit->getCommandSize()>1)
{// don't run over to dead body if there is still something to do in the queue
if(frameIndex < 0) {
if(command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) {
// don't run over to dead body if there is still something to do in the queue
unit->finishCommand();
}
else {
@ -466,6 +488,7 @@ void UnitUpdater::updateAttack(Unit *unit) {
unit->finishCommand();
}
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
@ -475,7 +498,13 @@ void UnitUpdater::updateAttack(Unit *unit) {
// ==================== updateAttackStopped ====================
void UnitUpdater::updateAttackStopped(Unit *unit) {
void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) {
// Nothing to do
if(frameIndex >= 0) {
clearUnitPrecache(unit);
return;
}
Chrono chrono;
chrono.start();
@ -503,7 +532,7 @@ void UnitUpdater::updateAttackStopped(Unit *unit) {
// ==================== updateBuild ====================
void UnitUpdater::updateBuild(Unit *unit) {
void UnitUpdater::updateBuild(Unit *unit, int frameIndex) {
Chrono chrono;
chrono.start();
@ -540,7 +569,7 @@ void UnitUpdater::updateBuild(Unit *unit) {
unit->logSynchData(__FILE__,__LINE__,szBuf);
}
tsValue = pathFinder->findPath(unit, buildPos);
tsValue = pathFinder->findPath(unit, buildPos, NULL, frameIndex);
}
break;
case pfRoutePlanner:
@ -553,6 +582,7 @@ void UnitUpdater::updateBuild(Unit *unit) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsValue = %d\n",__FILE__,__FUNCTION__,__LINE__,tsValue);
if(frameIndex < 0) {
switch (tsValue) {
case tsMoving:
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsMoving\n",__FILE__,__FUNCTION__,__LINE__);
@ -666,12 +696,13 @@ void UnitUpdater::updateBuild(Unit *unit) {
}
break;
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
else {
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsArrived unit = %s\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
if(frameIndex < 0) {
//if building
Unit *builtUnit = map->getCell(unit->getTargetPos())->getUnit(fLand);
if(builtUnit == NULL) {
@ -712,7 +743,7 @@ void UnitUpdater::updateBuild(Unit *unit) {
gameCamera->getPos());
}
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
@ -722,7 +753,7 @@ void UnitUpdater::updateBuild(Unit *unit) {
// ==================== updateHarvest ====================
void UnitUpdater::updateHarvest(Unit *unit) {
void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) {
Chrono chrono;
chrono.start();
@ -767,10 +798,14 @@ 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 == true ) {
if(frameIndex < 0) {
unit->setLastHarvestResourceTarget(NULL);
}
canHarvestDestPos = (map->getSurfaceCell(Map::toSurfCoords(targetPos)) != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()->getType() != NULL);
if(canHarvestDestPos == true) {
if(frameIndex < 0) {
//if it finds resources it starts harvesting
unit->setCurrSkill(hct->getHarvestSkillType());
unit->setTargetPos(targetPos);
@ -788,12 +823,14 @@ void UnitUpdater::updateHarvest(Unit *unit) {
default:
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(frameIndex < 0) {
unit->setLastHarvestResourceTarget(&targetPos);
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
@ -809,14 +846,14 @@ void UnitUpdater::updateHarvest(Unit *unit) {
TravelState tsValue = tsImpossible;
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, command->getPos(), &wasStuck);
if (tsValue == tsMoving) {
tsValue = pathFinder->findPath(unit, command->getPos(), &wasStuck, frameIndex);
if (tsValue == tsMoving && frameIndex < 0) {
unit->setCurrSkill(hct->getMoveSkillType());
}
break;
case pfRoutePlanner:
tsValue = routePlanner->findPathToResource(unit, command->getPos(), r->getType());
if (tsValue == tsMoving) {
if (tsValue == tsMoving && frameIndex < 0) {
unit->setCurrSkill(hct->getMoveSkillType());
}
break;
@ -848,10 +885,13 @@ void UnitUpdater::updateHarvest(Unit *unit) {
}
if (canHarvestDestPos == true) {
if(frameIndex < 0) {
unit->setLastHarvestResourceTarget(NULL);
}
canHarvestDestPos = (map->getSurfaceCell(Map::toSurfCoords(targetPos)) != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()->getType() != NULL);
if(canHarvestDestPos == true) {
if(frameIndex < 0) {
//if it finds resources it starts harvesting
unit->setCurrSkill(hct->getHarvestSkillType());
unit->setTargetPos(targetPos);
@ -870,12 +910,15 @@ void UnitUpdater::updateHarvest(Unit *unit) {
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(frameIndex < 0) {
unit->setLastHarvestResourceTarget(&targetPos);
}
if(targetPos.x >= 0) {
//if not continue walking
@ -891,15 +934,15 @@ void UnitUpdater::updateHarvest(Unit *unit) {
TravelState tsValue = tsImpossible;
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, targetPos, &wasStuck);
if (tsValue == tsMoving) {
tsValue = pathFinder->findPath(unit, targetPos, &wasStuck, frameIndex);
if (tsValue == tsMoving && frameIndex < 0) {
unit->setCurrSkill(hct->getMoveSkillType());
command->setPos(targetPos);
}
break;
case pfRoutePlanner:
tsValue = routePlanner->findPathToResource(unit, targetPos, r->getType());
if (tsValue == tsMoving) {
if (tsValue == tsMoving && frameIndex < 0) {
unit->setCurrSkill(hct->getMoveSkillType());
command->setPos(targetPos);
}
@ -911,7 +954,7 @@ 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 && frameIndex < 0) {
//if can't harvest, search for another resource
unit->setCurrSkill(scStop);
if(searchForResource(unit, hct) == false) {
@ -923,25 +966,24 @@ void UnitUpdater::updateHarvest(Unit *unit) {
}
}
else {
if(frameIndex < 0) {
//if can't harvest, search for another resource
unit->setCurrSkill(scStop);
if(searchForResource(unit, hct) == false) {
unit->finishCommand();
}
}
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());
}
else {
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
//if loaded, return to store
Unit *store= world->nearestStore(unit->getPos(), unit->getFaction()->getIndex(), unit->getLoadType());
if(store != NULL) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]="";
sprintf(szBuf,"[updateHarvest #3] unit->getPos() [%s] store->getCenteredPos() [%s]",
@ -952,7 +994,7 @@ void UnitUpdater::updateHarvest(Unit *unit) {
TravelState tsValue = tsImpossible;
switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic:
tsValue = pathFinder->findPath(unit, store->getCenteredPos());
tsValue = pathFinder->findPath(unit, store->getCenteredPos(), NULL, frameIndex);
break;
case pfRoutePlanner:
tsValue = routePlanner->findPathToStore(unit, store);
@ -963,6 +1005,7 @@ 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(frameIndex < 0) {
switch(tsValue) {
case tsMoving:
unit->setCurrSkill(hct->getMoveLoadedSkillType());
@ -990,15 +1033,18 @@ void UnitUpdater::updateHarvest(Unit *unit) {
unit->setCurrSkill(scStop);
unit->setLoadCount(0);
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
else {
if(frameIndex < 0) {
unit->finishCommand();
}
}
}
}
else {
if(frameIndex < 0) {
//if working
//unit->setLastHarvestResourceTarget(NULL);
@ -1060,6 +1106,7 @@ void UnitUpdater::updateHarvest(Unit *unit) {
unit->setCurrSkill(hct->getStopLoadedSkillType());
}
}
}
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
@ -1181,7 +1228,13 @@ Unit * UnitUpdater::findPeerUnitBuilder(Unit *unit) {
// ==================== updateRepair ====================
void UnitUpdater::updateRepair(Unit *unit) {
void UnitUpdater::updateRepair(Unit *unit, int frameIndex) {
// Nothing to do
if(frameIndex >= 0) {
clearUnitPrecache(unit);
return;
}
Chrono chrono;
chrono.start();
@ -1296,8 +1349,7 @@ void UnitUpdater::updateRepair(Unit *unit) {
// were or are about to be blocked
peerUnitBuilder->getPath()->clear();
peerUnitBuilder->setRetryCurrCommandCount(1);
updateUnitCommand(unit);
//updateUnitCommand(peerUnitBuilder);
updateUnitCommand(unit,-1);
}
return;
}
@ -1358,7 +1410,7 @@ void UnitUpdater::updateRepair(Unit *unit) {
case pfBasic:
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ts = pathFinder->findPath(unit, repairPos);
ts = pathFinder->findPath(unit, repairPos, NULL, frameIndex);
break;
case pfRoutePlanner:
SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1394,7 +1446,7 @@ void UnitUpdater::updateRepair(Unit *unit) {
unit->setRetryCurrCommandCount(0);
unit->getPath()->clear();
updateUnitCommand(unit);
updateUnitCommand(unit,-1);
}
else {
unit->finishCommand();
@ -1411,7 +1463,6 @@ void UnitUpdater::updateRepair(Unit *unit) {
unit->setCurrSkill(scStop);
unit->finishCommand();
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
}
@ -1450,10 +1501,14 @@ void UnitUpdater::updateRepair(Unit *unit) {
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
}
// ==================== updateProduce ====================
void UnitUpdater::updateProduce(Unit *unit) {
void UnitUpdater::updateProduce(Unit *unit, int frameIndex) {
// Nothing to do
if(frameIndex >= 0) {
clearUnitPrecache(unit);
return;
}
Chrono chrono;
chrono.start();
@ -1520,7 +1575,13 @@ void UnitUpdater::updateProduce(Unit *unit) {
// ==================== updateUpgrade ====================
void UnitUpdater::updateUpgrade(Unit *unit) {
void UnitUpdater::updateUpgrade(Unit *unit, int frameIndex) {
// Nothing to do
if(frameIndex >= 0) {
clearUnitPrecache(unit);
return;
}
Chrono chrono;
chrono.start();
@ -1547,7 +1608,13 @@ void UnitUpdater::updateUpgrade(Unit *unit) {
// ==================== updateMorph ====================
void UnitUpdater::updateMorph(Unit *unit){
void UnitUpdater::updateMorph(Unit *unit, int frameIndex) {
// Nothing to do
if(frameIndex >= 0) {
clearUnitPrecache(unit);
return;
}
Chrono chrono;
chrono.start();
@ -2007,7 +2074,6 @@ void ParticleDamager::update(ParticleSystem *particleSystem){
Unit *attacker= attackerRef.getUnit();
if(attacker != NULL) {
unitUpdater->hit(attacker, ast, targetPos, targetField);
//play sound

View File

@ -100,17 +100,17 @@ public:
void updateUnit(Unit *unit);
//update commands
void updateUnitCommand(Unit *unit);
void updateStop(Unit *unit);
void updateMove(Unit *unit);
void updateAttack(Unit *unit);
void updateAttackStopped(Unit *unit);
void updateBuild(Unit *unit);
void updateHarvest(Unit *unit);
void updateRepair(Unit *unit);
void updateProduce(Unit *unit);
void updateUpgrade(Unit *unit);
void updateMorph(Unit *unit);
void updateUnitCommand(Unit *unit, int frameIndex);
void updateStop(Unit *unit, int frameIndex);
void updateMove(Unit *unit, int frameIndex);
void updateAttack(Unit *unit, int frameIndex);
void updateAttackStopped(Unit *unit, int frameIndex);
void updateBuild(Unit *unit, int frameIndex);
void updateHarvest(Unit *unit, int frameIndex);
void updateRepair(Unit *unit, int frameIndex);
void updateProduce(Unit *unit, int frameIndex);
void updateUpgrade(Unit *unit, int frameIndex);
void updateMorph(Unit *unit, int frameIndex);
private:
//attack
@ -133,6 +133,7 @@ private:
const CommandType *commandType,
int originalValue,int newValue);
void clearUnitPrecache(Unit *unit);
};
// =====================================================

View File

@ -271,8 +271,44 @@ Checksum World::loadScenario(const string &path, Checksum *checksum) {
void World::updateAllFactionUnits() {
scriptManager->onTimerTriggerEvent();
//units
// Signal the faction threads to do any pre-processing
int factionCount = getFactionCount();
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
faction->signalWorkerThread(frameCount);
}
bool workThreadsFinished = false;
Chrono chrono;
chrono.start();
for(;chrono.getMillis() < 10000;) {
workThreadsFinished = true;
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
throw runtime_error("faction == NULL");
}
if(faction->isWorkerThreadSignalCompleted(frameCount) == false) {
workThreadsFinished = false;
break;
}
}
if(workThreadsFinished == false) {
sleep(0);
}
else {
break;
}
}
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);
//units
for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i);
if(faction == NULL) {
@ -290,6 +326,8 @@ void World::updateAllFactionUnits() {
unitUpdater.updateUnit(unit);
}
}
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);
}
void World::underTakeDeadFactionUnits() {

View File

@ -231,6 +231,8 @@ public:
void exploreCells(const Vec2i &newPos, int sightRange, int teamIndex);
bool showWorldForPlayer(int factionIndex) const;
UnitUpdater * getUnitUpdater() { return &unitUpdater; }
private:
void initCells(bool fogOfWar);