- 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() { PathFinder::PathFinder() {
nodePool.clear(); for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions.push_back(FactionState());
}
//nodePool.clear();
map=NULL; map=NULL;
} }
PathFinder::PathFinder(const Map *map) { PathFinder::PathFinder(const Map *map) {
nodePool.clear(); for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions.push_back(FactionState());
}
//nodePool.clear();
map=NULL; map=NULL;
init(map); init(map);
@ -58,22 +65,35 @@ PathFinder::PathFinder(const Map *map) {
void PathFinder::init(const Map *map) { void PathFinder::init(const Map *map) {
PathFinder::pathFindNodesMax = Config::getInstance().getInt("MaxPathfinderNodeCount",intToStr(PathFinder::pathFindNodesMax).c_str()); 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; this->map= map;
} }
PathFinder::~PathFinder(){ PathFinder::~PathFinder() {
nodePool.clear(); for(int i = 0; i < GameConstants::maxPlayers; ++i) {
factions[i].nodePool.clear();
}
map=NULL; 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"); //printf("PathFinder::findPath...\n");
if(map == NULL) { if(map == NULL) {
throw runtime_error("map == NULL"); throw runtime_error("map == NULL");
} }
if(frameIndex >= 0) {
clearUnitPrecache(unit);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]=""; char szBuf[4096]="";
@ -83,11 +103,11 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
} }
//route cache //route cache
UnitPathInterface *path= unit->getPath();
if(finalPos == unit->getPos()) { if(finalPos == unit->getPos()) {
//if arrived if(frameIndex < 0) {
unit->setCurrSkill(scStop); //if arrived
unit->setCurrSkill(scStop);
}
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();
@ -102,36 +122,39 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
//unit->getFaction()->addCachedPath(finalPos,unit); //unit->getFaction()->addCachedPath(finalPos,unit);
return tsArrived; return tsArrived;
} }
else {
if(path->isEmpty() == false) {
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
//route cache
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
Vec2i pos= basicPath->pop();
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) { UnitPathInterface *path= unit->getPath();
if(map->canMove(unit, unit->getPos(), pos)) { if(path->isEmpty() == false) {
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
//route cache
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
Vec2i pos= basicPath->pop(frameIndex < 0);
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
unit->setTargetPos(pos); unit->setTargetPos(pos);
unit->addCurrentTargetPathTakenCell(finalPos,pos); unit->addCurrentTargetPathTakenCell(finalPos,pos);
return tsMoving;
} }
} return tsMoving;
else if(dynamic_cast<UnitPath *>(path) != NULL) {
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)) {
advPath->pop();
unit->setTargetPos(pos);
return tsMoving;
}
}
else {
throw runtime_error("unsupported or missing path finder detected!");
} }
} }
else if(dynamic_cast<UnitPath *>(path) != NULL) {
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
//route cache
Vec2i pos= advPath->peek();
if(map->canMove(unit, unit->getPos(), pos)) {
if(frameIndex < 0) {
advPath->pop();
unit->setTargetPos(pos);
}
return tsMoving;
}
}
else {
throw runtime_error("unsupported or missing path finder detected!");
}
} }
TravelState ts = tsImpossible; TravelState ts = tsImpossible;
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit); //std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
@ -144,10 +167,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
//} //}
//else { //else {
//route cache miss //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); //std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
//if(cachedPath.size() > 0) { //if(cachedPath.size() > 0) {
// path->clear(); // path->clear();
@ -158,16 +181,16 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
// ts = tsMoving; // ts = tsMoving;
// unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1)); // unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1));
//} //}
} //}
//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); //unit->getFaction()->addCachedPath(finalPos,unit);
} //}
// 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
@ -224,7 +247,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
if(useBailoutRadius == true) { if(useBailoutRadius == true) {
//int tryRadius = random.randRange(-PathFinder::pathFindBailoutRadius, PathFinder::pathFindBailoutRadius); //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); //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) { 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) { 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); unit->setInBailOutAttempt(false);
} }
if(ts == tsArrived || ts == tsBlocked) { if(ts == tsArrived || ts == tsBlocked) {
unit->setCurrSkill(scStop); if(frameIndex < 0) {
unit->setCurrSkill(scStop);
}
} }
break; break;
case tsMoving: case tsMoving:
{ {
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;
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, &lookupCacheCanMove)) {
if(map->canMove(unit, unit->getPos(), pos)) { if(map->canMove(unit, unit->getPos(), pos)) {
unit->setTargetPos(pos); if(frameIndex < 0) {
unit->addCurrentTargetPathTakenCell(finalPos,pos); unit->setTargetPos(pos);
unit->addCurrentTargetPathTakenCell(finalPos,pos);
}
} }
else { else {
unit->setCurrSkill(scStop); if(frameIndex < 0) {
unit->setCurrSkill(scStop);
}
return tsBlocked; return tsBlocked;
} }
} }
else if(dynamic_cast<UnitPath *>(path) != NULL) { else if(dynamic_cast<UnitPath *>(path) != NULL) {
UnitPath *advPath = dynamic_cast<UnitPath *>(path); UnitPath *advPath = dynamic_cast<UnitPath *>(path);
Vec2i pos= advPath->peek(); Vec2i pos= advPath->peek();
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
if(map->canMove(unit, unit->getPos(), pos)) { if(map->canMove(unit, unit->getPos(), pos)) {
advPath->pop(); if(frameIndex < 0) {
unit->setTargetPos(pos); advPath->pop();
unit->setTargetPos(pos);
}
} }
else { else {
unit->setCurrSkill(scStop); if(frameIndex < 0) {
unit->setCurrSkill(scStop);
}
return tsBlocked; return tsBlocked;
} }
} }
@ -319,20 +357,20 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
bool result = false; bool result = false;
Vec2i sucPos= node->pos + Vec2i(i, j); Vec2i sucPos= node->pos + Vec2i(i, j);
bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos); 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 //if node is not open and canMove then generate another node
Node *sucNode= newNode(); Node *sucNode= newNode(factions[unit->getFactionIndex()]);
if(sucNode != NULL) { if(sucNode != NULL) {
sucNode->pos= sucPos; sucNode->pos= sucPos;
sucNode->heuristic= heuristic(sucNode->pos, finalPos); sucNode->heuristic= heuristic(sucNode->pos, finalPos);
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());
if(openNodesList.find(sucNode->heuristic) == openNodesList.end()) { if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
openNodesList[sucNode->heuristic].clear(); factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
} }
openNodesList[sucNode->heuristic].push_back(sucNode); factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
openPosList[sucNode->pos] = true; factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
result = 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 //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"); //printf("PathFinder::aStar...\n");
Chrono chrono; Chrono chrono;
@ -354,18 +393,78 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
throw runtime_error("map == NULL"); throw runtime_error("map == NULL");
} }
nodePoolCount= 0; UnitPathInterface *path= unit->getPath();
openNodesList.clear();
openPosList.clear(); factions[unit->getFactionIndex()].nodePoolCount= 0;
closedNodesList.clear(); factions[unit->getFactionIndex()].openNodesList.clear();
factions[unit->getFactionIndex()].openPosList.clear();
factions[unit->getFactionIndex()].closedNodesList.clear();
TravelState ts = tsImpossible; 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 unitPos = unit->getPos();
const Vec2i finalPos= computeNearestFreePos(unit, targetPos); const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
float dist= unitPos.dist(finalPos); float dist= unitPos.dist(finalPos);
useMaxNodeCount = PathFinder::pathFindNodesMax; factions[unit->getFactionIndex()].useMaxNodeCount = PathFinder::pathFindNodesMax;
// if(dist <= 10) { // if(dist <= 10) {
// useMaxNodeCount = (int)dist * 20; // useMaxNodeCount = (int)dist * 20;
// if(useMaxNodeCount <= 0) { // 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()); 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 // Check the previous path find cache for the unit to see if its good to
// use // use
const bool showConsoleDebugInfo = Config::getInstance().getBool("EnablePathfinderDistanceOutput","false"); 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) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]", 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); 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) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]", 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); unit->logSynchData(__FILE__,__LINE__,szBuf);
} }
@ -506,7 +604,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
//path find algorithm //path find algorithm
//a) push starting pos into openNodes //a) push starting pos into openNodes
Node *firstNode= newNode(); Node *firstNode= newNode(factions[unit->getFactionIndex()]);
assert(firstNode != NULL); assert(firstNode != NULL);
if(firstNode == NULL) { if(firstNode == NULL) {
throw runtime_error("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->pos= unitPos;
firstNode->heuristic= heuristic(unitPos, finalPos); firstNode->heuristic= heuristic(unitPos, finalPos);
firstNode->exploredCell= true; firstNode->exploredCell= true;
if(openNodesList.find(firstNode->heuristic) == openNodesList.end()) { if(factions[unit->getFactionIndex()].openNodesList.find(firstNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
openNodesList[firstNode->heuristic].clear(); factions[unit->getFactionIndex()].openNodesList[firstNode->heuristic].clear();
} }
openNodesList[firstNode->heuristic].push_back(firstNode); factions[unit->getFactionIndex()].openNodesList[firstNode->heuristic].push_back(firstNode);
openPosList[firstNode->pos] = true; factions[unit->getFactionIndex()].openPosList[firstNode->pos] = true;
//b) loop //b) loop
bool pathFound = true; bool pathFound = true;
@ -592,14 +690,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
whileLoopCount++; whileLoopCount++;
//b1) is open nodes is empty => failed to find the path //b1) is open nodes is empty => failed to find the path
if(openNodesList.empty() == true) { if(factions[unit->getFactionIndex()].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 = minHeuristicFastLookup(); node = minHeuristicFastLookup(factions[unit->getFactionIndex()]);
//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) {
@ -609,16 +707,16 @@ 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
if(closedNodesList.find(node->heuristic) == closedNodesList.end()) { if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
closedNodesList[node->heuristic].clear(); factions[unit->getFactionIndex()].closedNodesList[node->heuristic].clear();
} }
closedNodesList[node->heuristic].push_back(node); factions[unit->getFactionIndex()].closedNodesList[node->heuristic].push_back(node);
openPosList[node->pos] = true; factions[unit->getFactionIndex()].openPosList[node->pos] = true;
int failureCount = 0; int failureCount = 0;
int cellCount = 0; int cellCount = 0;
int tryDirection = random.randRange(0,3); int tryDirection = factions[unit->getFactionIndex()].random.randRange(0,3);
if(tryDirection == 3) { if(tryDirection == 3) {
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) {
@ -673,19 +771,19 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
} }
} //while } //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) { 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; 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) { if(factions[unit->getFactionIndex()].closedNodesList.size() > 0) {
float bestHeuristic = closedNodesList.begin()->first; float bestHeuristic = factions[unit->getFactionIndex()].closedNodesList.begin()->first;
if(bestHeuristic < lastNode->heuristic) { 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; ts= tsBlocked;
path->incBlockCount(); if(frameIndex < 0) {
path->incBlockCount();
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"[path for unit BLOCKED] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]", 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); 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()); 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 //store path
path->clear(); if(frameIndex < 0) {
path->clear();
}
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path); UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
currNode= firstNode; currNode= firstNode;
@ -747,15 +850,20 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i)); throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
} }
if(i < pathFindRefresh) { if(frameIndex >= 0) {
path->add(nodePos); factions[unit->getFactionIndex()].precachedPath[unit->getId()].push_back(nodePos);
}
else if(tryLastPathCache == false) {
break;
} }
else {
if(i < pathFindRefresh) {
path->add(nodePos);
}
else if(tryLastPathCache == false) {
break;
}
if(tryLastPathCache == true && basicPathFinder) { if(tryLastPathCache == true && basicPathFinder) {
basicPathFinder->addToLastPathCache(nodePos); basicPathFinder->addToLastPathCache(nodePos);
}
} }
} }
@ -764,7 +872,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
char szBuf[4096]=""; char szBuf[4096]="";
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]", 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); unit->logSynchData(__FILE__,__LINE__,szBuf);
string pathToTake = ""; 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()); 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(); factions[unit->getFactionIndex()].openNodesList.clear();
openPosList.clear(); factions[unit->getFactionIndex()].openPosList.clear();
closedNodesList.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(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; return ts;
} }
PathFinder::Node *PathFinder::newNode() { PathFinder::Node *PathFinder::newNode(FactionState &faction) {
if(nodePoolCount < nodePool.size() && nodePoolCount < useMaxNodeCount) { if( faction.nodePoolCount < faction.nodePool.size() &&
Node *node= &nodePool[nodePoolCount]; faction.nodePoolCount < faction.useMaxNodeCount) {
Node *node= &(faction.nodePool[faction.nodePoolCount]);
node->clear(); node->clear();
nodePoolCount++; faction.nodePoolCount++;
return node; return node;
} }
return NULL; return NULL;
@ -864,22 +979,22 @@ float PathFinder::heuristic(const Vec2i &pos, const Vec2i &finalPos) {
return pos.dist(finalPos); return pos.dist(finalPos);
} }
PathFinder::Node * PathFinder::minHeuristicFastLookup() { PathFinder::Node * PathFinder::minHeuristicFastLookup(FactionState &faction) {
assert(openNodesList.empty() == false); assert(faction.openNodesList.empty() == false);
if(openNodesList.empty() == true) { if(faction.openNodesList.empty() == true) {
throw runtime_error("openNodesList.empty() == true"); throw runtime_error("openNodesList.empty() == true");
} }
Node *result = openNodesList.begin()->second[0]; Node *result = faction.openNodesList.begin()->second[0];
openNodesList.begin()->second.erase(openNodesList.begin()->second.begin()); faction.openNodesList.begin()->second.erase(faction.openNodesList.begin()->second.begin());
if(openNodesList.begin()->second.size() == 0) { if(faction.openNodesList.begin()->second.size() == 0) {
openNodesList.erase(openNodesList.begin()); faction.openNodesList.erase(faction.openNodesList.begin());
} }
return result; return result;
} }
bool PathFinder::openPos(const Vec2i &sucPos) { bool PathFinder::openPos(const Vec2i &sucPos, FactionState &faction) {
if(openPosList.find(sucPos) == openPosList.end()) { if(faction.openPosList.find(sucPos) == faction.openPosList.end()) {
return false; return false;
} }
return true; return true;

View File

@ -57,38 +57,59 @@ public:
}; };
typedef vector<Node*> Nodes; 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: public:
static const int maxFreeSearchRadius; static const int maxFreeSearchRadius;
static int pathFindNodesMax;
static const int pathFindRefresh; static const int pathFindRefresh;
static const int pathFindBailoutRadius; static const int pathFindBailoutRadius;
private: private:
std::map<Vec2i, bool> openPosList;
std::map<float, Nodes> openNodesList;
std::map<float, Nodes> closedNodesList;
std::vector<Node> nodePool; static int pathFindNodesMax;
int nodePoolCount;
FactionStateList factions;
const Map *map; const Map *map;
RandomGen random;
int useMaxNodeCount;
public: public:
PathFinder(); PathFinder();
PathFinder(const Map *map); PathFinder(const Map *map);
~PathFinder(); ~PathFinder();
void init(const Map *map); 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: private:
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout); TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex);
Node *newNode(); Node *newNode(FactionState &faction);
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);
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); 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); void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);

View File

@ -26,7 +26,164 @@
using namespace Shared::Util; using namespace Shared::Util;
namespace Glest{ namespace Game{ 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 // class Faction
@ -37,6 +194,7 @@ Faction::Faction() {
//lastResourceTargettListPurge = 0; //lastResourceTargettListPurge = 0;
cachingDisabled=false; cachingDisabled=false;
factionDisconnectHandled=false; factionDisconnectHandled=false;
workerThread = NULL;
} }
Faction::~Faction() { Faction::~Faction() {
@ -50,11 +208,33 @@ Faction::~Faction() {
//texture->end(); //texture->end();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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; //delete texture;
texture = NULL; texture = NULL;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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( void Faction::init(
FactionType *factionType, ControlType control, TechTree *techTree, Game *game, FactionType *factionType, ControlType control, TechTree *techTree, Game *game,
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources) 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); string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
texture->load(data_path + "data/core/faction_textures/faction"+intToStr(startLocationIndex)+".tga"); 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__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }
void Faction::end(){ void Faction::end() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); 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()); deleteValues(units.begin(), units.end());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
} }

View File

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

View File

@ -101,12 +101,14 @@ void UnitPathBasic::addToLastPathCache(const Vec2i &path) {
lastPathCacheQueue.push_back(path); lastPathCacheQueue.push_back(path);
} }
Vec2i UnitPathBasic::pop() { Vec2i UnitPathBasic::pop(bool removeFrontPos) {
if(pathQueue.size() <= 0) { if(pathQueue.size() <= 0) {
throw runtime_error("pathQueue.size() = " + intToStr(pathQueue.size())); throw runtime_error("pathQueue.size() = " + intToStr(pathQueue.size()));
} }
Vec2i p= pathQueue.front(); Vec2i p= pathQueue.front();
pathQueue.erase(pathQueue.begin()); if(removeFrontPos == true) {
pathQueue.erase(pathQueue.begin());
}
return p; return p;
} }
std::string UnitPathBasic::toString() const { std::string UnitPathBasic::toString() const {
@ -1105,6 +1107,60 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
return commandType; 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() { bool Unit::update() {
assert(progress<=1.f); assert(progress<=1.f);

View File

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

View File

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

View File

@ -21,7 +21,7 @@
#include "sound_container.h" #include "sound_container.h"
#include "leak_dumper.h" #include "leak_dumper.h"
namespace Glest{ namespace Game{ namespace Glest { namespace Game {
using Shared::Util::MultiFactory; using Shared::Util::MultiFactory;
@ -31,7 +31,7 @@ class UnitType;
class TechTree; class TechTree;
class FactionType; class FactionType;
enum CommandClass{ enum CommandClass {
ccStop, ccStop,
ccMove, ccMove,
ccAttack, ccAttack,
@ -47,7 +47,7 @@ enum CommandClass{
ccNull ccNull
}; };
enum Clicks{ enum Clicks {
cOne, cOne,
cTwo cTwo
}; };
@ -80,7 +80,7 @@ public:
clicks = cOne; clicks = cOne;
id = -1; 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -109,13 +109,13 @@ public:
// class StopCommandType // class StopCommandType
// =============================== // ===============================
class StopCommandType: public CommandType{ class StopCommandType: public CommandType {
private: private:
const StopSkillType* stopSkillType; const StopSkillType* stopSkillType;
public: public:
StopCommandType(); 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, 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); const FactionType *ft, const UnitType &ut, std::map<string,int> &loadedFileList);
virtual string getDesc(const TotalUpgrade *totalUpgrade) const; virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
@ -131,13 +131,13 @@ public:
// class MoveCommandType // class MoveCommandType
// =============================== // ===============================
class MoveCommandType: public CommandType{ class MoveCommandType: public CommandType {
private: private:
const MoveSkillType *moveSkillType; const MoveSkillType *moveSkillType;
public: public:
MoveCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -153,14 +153,14 @@ public:
// class AttackCommandType // class AttackCommandType
// =============================== // ===============================
class AttackCommandType: public CommandType{ class AttackCommandType: public CommandType {
private: private:
const MoveSkillType* moveSkillType; const MoveSkillType* moveSkillType;
const AttackSkillType* attackSkillType; const AttackSkillType* attackSkillType;
public: public:
AttackCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -177,14 +177,14 @@ public:
// class AttackStoppedCommandType // class AttackStoppedCommandType
// ======================================= // =======================================
class AttackStoppedCommandType: public CommandType{ class AttackStoppedCommandType: public CommandType {
private: private:
const StopSkillType* stopSkillType; const StopSkillType* stopSkillType;
const AttackSkillType* attackSkillType; const AttackSkillType* attackSkillType;
public: public:
AttackStoppedCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -201,7 +201,7 @@ public:
// class BuildCommandType // class BuildCommandType
// =============================== // ===============================
class BuildCommandType: public CommandType{ class BuildCommandType: public CommandType {
private: private:
const MoveSkillType* moveSkillType; const MoveSkillType* moveSkillType;
const BuildSkillType* buildSkillType; const BuildSkillType* buildSkillType;
@ -212,7 +212,7 @@ private:
public: public:
BuildCommandType(); BuildCommandType();
~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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -233,7 +233,7 @@ public:
// class HarvestCommandType // class HarvestCommandType
// =============================== // ===============================
class HarvestCommandType: public CommandType{ class HarvestCommandType: public CommandType {
private: private:
const MoveSkillType *moveSkillType; const MoveSkillType *moveSkillType;
const MoveSkillType *moveLoadedSkillType; const MoveSkillType *moveLoadedSkillType;
@ -245,7 +245,7 @@ private:
public: public:
HarvestCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -270,7 +270,7 @@ public:
// class RepairCommandType // class RepairCommandType
// =============================== // ===============================
class RepairCommandType: public CommandType{ class RepairCommandType: public CommandType {
private: private:
const MoveSkillType* moveSkillType; const MoveSkillType* moveSkillType;
const RepairSkillType* repairSkillType; const RepairSkillType* repairSkillType;
@ -279,7 +279,7 @@ private:
public: public:
RepairCommandType(); RepairCommandType();
~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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -301,14 +301,14 @@ public:
// class ProduceCommandType // class ProduceCommandType
// =============================== // ===============================
class ProduceCommandType: public CommandType{ class ProduceCommandType: public CommandType {
private: private:
const ProduceSkillType* produceSkillType; const ProduceSkillType* produceSkillType;
const UnitType *producedUnit; const UnitType *producedUnit;
public: public:
ProduceCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -328,14 +328,14 @@ public:
// class UpgradeCommandType // class UpgradeCommandType
// =============================== // ===============================
class UpgradeCommandType: public CommandType{ class UpgradeCommandType: public CommandType {
private: private:
const UpgradeSkillType* upgradeSkillType; const UpgradeSkillType* upgradeSkillType;
const UpgradeType* producedUpgrade; const UpgradeType* producedUpgrade;
public: public:
UpgradeCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);
@ -354,7 +354,7 @@ public:
// class MorphCommandType // class MorphCommandType
// =============================== // ===============================
class MorphCommandType: public CommandType{ class MorphCommandType: public CommandType {
private: private:
const MorphSkillType* morphSkillType; const MorphSkillType* morphSkillType;
const UnitType* morphUnit; const UnitType* morphUnit;
@ -362,7 +362,7 @@ private:
public: public:
MorphCommandType(); 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, virtual void load(int id, const XmlNode *n, const string &dir,
const TechTree *tt, const FactionType *ft, const UnitType &ut, const TechTree *tt, const FactionType *ft, const UnitType &ut,
std::map<string,int> &loadedFileList); std::map<string,int> &loadedFileList);

File diff suppressed because it is too large Load Diff

View File

@ -100,17 +100,17 @@ public:
void updateUnit(Unit *unit); void updateUnit(Unit *unit);
//update commands //update commands
void updateUnitCommand(Unit *unit); void updateUnitCommand(Unit *unit, int frameIndex);
void updateStop(Unit *unit); void updateStop(Unit *unit, int frameIndex);
void updateMove(Unit *unit); void updateMove(Unit *unit, int frameIndex);
void updateAttack(Unit *unit); void updateAttack(Unit *unit, int frameIndex);
void updateAttackStopped(Unit *unit); void updateAttackStopped(Unit *unit, int frameIndex);
void updateBuild(Unit *unit); void updateBuild(Unit *unit, int frameIndex);
void updateHarvest(Unit *unit); void updateHarvest(Unit *unit, int frameIndex);
void updateRepair(Unit *unit); void updateRepair(Unit *unit, int frameIndex);
void updateProduce(Unit *unit); void updateProduce(Unit *unit, int frameIndex);
void updateUpgrade(Unit *unit); void updateUpgrade(Unit *unit, int frameIndex);
void updateMorph(Unit *unit); void updateMorph(Unit *unit, int frameIndex);
private: private:
//attack //attack
@ -133,6 +133,7 @@ private:
const CommandType *commandType, const CommandType *commandType,
int originalValue,int newValue); 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() { void World::updateAllFactionUnits() {
scriptManager->onTimerTriggerEvent(); scriptManager->onTimerTriggerEvent();
//units
// Signal the faction threads to do any pre-processing
int factionCount = getFactionCount(); 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) { for(int i = 0; i < factionCount; ++i) {
Faction *faction = getFaction(i); Faction *faction = getFaction(i);
if(faction == NULL) { if(faction == NULL) {
@ -290,6 +326,8 @@ void World::updateAllFactionUnits() {
unitUpdater.updateUnit(unit); 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() { void World::underTakeDeadFactionUnits() {

View File

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