- attempt to see if threaded pathfinding will work and if it improves performance
This commit is contained in:
parent
e65f588045
commit
07f56669b7
|
@ -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();
|
||||
PathFinder::~PathFinder() {
|
||||
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 arrived
|
||||
unit->setCurrSkill(scStop);
|
||||
|
||||
if(frameIndex < 0) {
|
||||
//if arrived
|
||||
unit->setCurrSkill(scStop);
|
||||
}
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
||||
string commandDesc = "none";
|
||||
Command *command= unit->getCurrCommand();
|
||||
|
@ -102,37 +122,40 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
//unit->getFaction()->addCachedPath(finalPos,unit);
|
||||
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)) {
|
||||
if(map->canMove(unit, unit->getPos(), pos)) {
|
||||
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(frameIndex < 0);
|
||||
|
||||
if(map->canMove(unit, unit->getPos(), pos)) {
|
||||
if(frameIndex < 0) {
|
||||
unit->setTargetPos(pos);
|
||||
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
||||
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!");
|
||||
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)) {
|
||||
if(frameIndex < 0) {
|
||||
advPath->pop();
|
||||
unit->setTargetPos(pos);
|
||||
}
|
||||
return tsMoving;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw runtime_error("unsupported or missing path finder detected!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TravelState ts = tsImpossible;
|
||||
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
|
||||
//if(cachedPath.size() > 0) {
|
||||
|
@ -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) {
|
||||
unit->setCurrSkill(scStop);
|
||||
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)) {
|
||||
unit->setTargetPos(pos);
|
||||
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
||||
if(frameIndex < 0) {
|
||||
unit->setTargetPos(pos);
|
||||
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unit->setCurrSkill(scStop);
|
||||
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)) {
|
||||
advPath->pop();
|
||||
unit->setTargetPos(pos);
|
||||
if(frameIndex < 0) {
|
||||
advPath->pop();
|
||||
unit->setTargetPos(pos);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unit->setCurrSkill(scStop);
|
||||
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;
|
||||
path->incBlockCount();
|
||||
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
|
||||
path->clear();
|
||||
if(frameIndex < 0) {
|
||||
path->clear();
|
||||
}
|
||||
|
||||
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
if(i < pathFindRefresh) {
|
||||
path->add(nodePos);
|
||||
}
|
||||
else if(tryLastPathCache == false) {
|
||||
break;
|
||||
if(frameIndex >= 0) {
|
||||
factions[unit->getFactionIndex()].precachedPath[unit->getId()].push_back(nodePos);
|
||||
}
|
||||
else {
|
||||
if(i < pathFindRefresh) {
|
||||
path->add(nodePos);
|
||||
}
|
||||
else if(tryLastPathCache == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(tryLastPathCache == true && basicPathFinder) {
|
||||
basicPathFinder->addToLastPathCache(nodePos);
|
||||
if(tryLastPathCache == true && basicPathFinder) {
|
||||
basicPathFinder->addToLastPathCache(nodePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -764,7 +872,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);
|
||||
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -26,7 +26,164 @@
|
|||
|
||||
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
|
||||
|
@ -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(){
|
||||
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__);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
pathQueue.erase(pathQueue.begin());
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "sound_container.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
namespace Glest{ namespace Game{
|
||||
namespace Glest { namespace Game {
|
||||
|
||||
using Shared::Util::MultiFactory;
|
||||
|
||||
|
@ -31,7 +31,7 @@ class UnitType;
|
|||
class TechTree;
|
||||
class FactionType;
|
||||
|
||||
enum CommandClass{
|
||||
enum CommandClass {
|
||||
ccStop,
|
||||
ccMove,
|
||||
ccAttack,
|
||||
|
@ -47,7 +47,7 @@ enum CommandClass{
|
|||
ccNull
|
||||
};
|
||||
|
||||
enum Clicks{
|
||||
enum Clicks {
|
||||
cOne,
|
||||
cTwo
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -109,13 +109,13 @@ public:
|
|||
// class StopCommandType
|
||||
// ===============================
|
||||
|
||||
class StopCommandType: public CommandType{
|
||||
class StopCommandType: public CommandType {
|
||||
private:
|
||||
const StopSkillType* stopSkillType;
|
||||
|
||||
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;
|
||||
|
@ -131,13 +131,13 @@ public:
|
|||
// class MoveCommandType
|
||||
// ===============================
|
||||
|
||||
class MoveCommandType: public CommandType{
|
||||
class MoveCommandType: public CommandType {
|
||||
private:
|
||||
const MoveSkillType *moveSkillType;
|
||||
|
||||
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);
|
||||
|
@ -153,14 +153,14 @@ public:
|
|||
// class AttackCommandType
|
||||
// ===============================
|
||||
|
||||
class AttackCommandType: public CommandType{
|
||||
class AttackCommandType: public CommandType {
|
||||
private:
|
||||
const MoveSkillType* moveSkillType;
|
||||
const AttackSkillType* attackSkillType;
|
||||
|
||||
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);
|
||||
|
@ -177,14 +177,14 @@ public:
|
|||
// class AttackStoppedCommandType
|
||||
// =======================================
|
||||
|
||||
class AttackStoppedCommandType: public CommandType{
|
||||
class AttackStoppedCommandType: public CommandType {
|
||||
private:
|
||||
const StopSkillType* stopSkillType;
|
||||
const AttackSkillType* attackSkillType;
|
||||
|
||||
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);
|
||||
|
@ -201,7 +201,7 @@ public:
|
|||
// class BuildCommandType
|
||||
// ===============================
|
||||
|
||||
class BuildCommandType: public CommandType{
|
||||
class BuildCommandType: public CommandType {
|
||||
private:
|
||||
const MoveSkillType* moveSkillType;
|
||||
const BuildSkillType* buildSkillType;
|
||||
|
@ -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);
|
||||
|
@ -233,7 +233,7 @@ public:
|
|||
// class HarvestCommandType
|
||||
// ===============================
|
||||
|
||||
class HarvestCommandType: public CommandType{
|
||||
class HarvestCommandType: public CommandType {
|
||||
private:
|
||||
const MoveSkillType *moveSkillType;
|
||||
const MoveSkillType *moveLoadedSkillType;
|
||||
|
@ -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);
|
||||
|
@ -270,7 +270,7 @@ public:
|
|||
// class RepairCommandType
|
||||
// ===============================
|
||||
|
||||
class RepairCommandType: public CommandType{
|
||||
class RepairCommandType: public CommandType {
|
||||
private:
|
||||
const MoveSkillType* moveSkillType;
|
||||
const RepairSkillType* repairSkillType;
|
||||
|
@ -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);
|
||||
|
@ -301,14 +301,14 @@ public:
|
|||
// class ProduceCommandType
|
||||
// ===============================
|
||||
|
||||
class ProduceCommandType: public CommandType{
|
||||
class ProduceCommandType: public CommandType {
|
||||
private:
|
||||
const ProduceSkillType* produceSkillType;
|
||||
const UnitType *producedUnit;
|
||||
|
||||
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);
|
||||
|
@ -328,14 +328,14 @@ public:
|
|||
// class UpgradeCommandType
|
||||
// ===============================
|
||||
|
||||
class UpgradeCommandType: public CommandType{
|
||||
class UpgradeCommandType: public CommandType {
|
||||
private:
|
||||
const UpgradeSkillType* upgradeSkillType;
|
||||
const UpgradeType* producedUpgrade;
|
||||
|
||||
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);
|
||||
|
@ -354,7 +354,7 @@ public:
|
|||
// class MorphCommandType
|
||||
// ===============================
|
||||
|
||||
class MorphCommandType: public CommandType{
|
||||
class MorphCommandType: public CommandType {
|
||||
private:
|
||||
const MorphSkillType* morphSkillType;
|
||||
const UnitType* morphUnit;
|
||||
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
};
|
||||
|
||||
// =====================================================
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue