From 6e7d4aeec576d6cfc1abd5ea89fb64b7b93968c2 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 17 Apr 2012 07:51:45 +0000 Subject: [PATCH] - speed up some heavily used functions --- source/glest_game/ai/path_finder.cpp | 109 --------------------- source/glest_game/ai/path_finder.h | 127 ++++++++++++++++++++++-- source/glest_game/world/map.cpp | 90 ----------------- source/glest_game/world/map.h | 138 ++++++++++++++++++++------- 4 files changed, 222 insertions(+), 242 deletions(-) diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index 337d84cb..6f0739ca 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -409,52 +409,6 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu // ==================== PRIVATE ==================== - -bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached,int maxNodeCount) { - bool result = false; - Vec2i sucPos= node->pos + Vec2i(i, j); - -// std::map > >::iterator iterFind1 = factions[unit->getFactionIndex()].mapFromToNodeList.find(unit->getType()->getId()); -// if(iterFind1 != factions[unit->getFactionIndex()].mapFromToNodeList.end()) { -// std::map >::iterator iterFind2 = iterFind1->second.find(node->pos); -// if(iterFind2 != iterFind1->second.end()) { -// std::map::iterator iterFind3 = iterFind2->second.find(sucPos); -// if(iterFind3 != iterFind2->second.end()) { -// //printf("found duplicate check in processNode\n"); -// return iterFind3->second; -// } -// } -// } - - //bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos); - //bool canUnitMoveToCell = map->aproxCanMoveSoon(unit, node->pos, sucPos); - if(openPos(sucPos, factions[unit->getFactionIndex()]) == false && - canUnitMoveSoon(unit, node->pos, sucPos) == true) { - //if node is not open and canMove then generate another node - Node *sucNode= newNode(factions[unit->getFactionIndex()],maxNodeCount); - 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(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) { - factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear(); - } - factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode); - factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true; - - result = true; - } - else { - nodeLimitReached= true; - } - } - -// factions[unit->getFactionIndex()].mapFromToNodeList[unit->getType()->getId()][node->pos][sucPos] = result; - return result; -} - bool PathFinder::addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded, bool bypassChecks) { bool result = false; @@ -1419,18 +1373,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout return ts; } -PathFinder::Node *PathFinder::newNode(FactionState &faction, int maxNodeCount) { - if( faction.nodePoolCount < faction.nodePool.size() && - //faction.nodePoolCount < faction.useMaxNodeCount) { - faction.nodePoolCount < maxNodeCount) { - Node *node= &(faction.nodePool[faction.nodePoolCount]); - node->clear(); - faction.nodePoolCount++; - return node; - } - return NULL; -} - void PathFinder::processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist) { Vec2i currPos= finalPos + Vec2i(i, j); if(map->isAproxFreeCells(currPos, size, field, teamIndex)) { @@ -1478,31 +1420,6 @@ Vec2i PathFinder::computeNearestFreePos(const Unit *unit, const Vec2i &finalPos) return nearestPos; } -float PathFinder::heuristic(const Vec2i &pos, const Vec2i &finalPos) { - return pos.dist(finalPos); -} - -PathFinder::Node * PathFinder::minHeuristicFastLookup(FactionState &faction) { - assert(faction.openNodesList.empty() == false); - if(faction.openNodesList.empty() == true) { - throw megaglest_runtime_error("openNodesList.empty() == true"); - } - - 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, FactionState &faction) { - if(faction.openPosList.find(sucPos) == faction.openPosList.end()) { - return false; - } - return true; -} - int PathFinder::findNodeIndex(Node *node, Nodes &nodeList) { int index = -1; if(node != NULL) { @@ -1531,32 +1448,6 @@ int PathFinder::findNodeIndex(Node *node, std::vector &nodeList) { return index; } -bool PathFinder::canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) { - bool result = true; - -// std::map > &badCellList = factions[unit->getFactionIndex()].badCellList; -// if(badCellList.find(unit->getType()->getSize()) != badCellList.end()) { -// std::map &badFieldList = badCellList[unit->getType()->getSize()]; -// if(badFieldList.find(unit->getCurrField()) != badFieldList.end()) { -// BadUnitNodeList &badList = badFieldList[unit->getCurrField()]; -// if(badList.isPosBad(pos1,pos2) == true) { -// result = false; -// } -// } -// } -// if(result == true) { -// //bool canUnitMoveToCell = map->canMove(unit, unitPos, pos); -// //bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos); -// result = map->aproxCanMoveSoon(unit, pos1, pos2); -// if(result == false) { -// badCellList[unit->getType()->getSize()][unit->getCurrField()].badPosList[pos1][pos2]=false; -// } -// } - - result = map->aproxCanMoveSoon(unit, pos1, pos2); - return result; -} - void PathFinder::saveGame(XmlNode *rootNode) { std::map mapTagReplacements; XmlNode *pathfinderNode = rootNode->addChild("PathFinder"); diff --git a/source/glest_game/ai/path_finder.h b/source/glest_game/ai/path_finder.h index b95a113f..5828d0fc 100644 --- a/source/glest_game/ai/path_finder.h +++ b/source/glest_game/ai/path_finder.h @@ -18,6 +18,9 @@ #include #include "game_constants.h" #include "skill_type.h" +#include "map.h" +#include "unit.h" + #include "leak_dumper.h" using std::vector; @@ -25,8 +28,8 @@ using Shared::Graphics::Vec2i; namespace Glest { namespace Game { -class Map; -class Unit; +//class Map; +//class Unit; // The order of directions is: // N, NE, E, SE, S, SW, W, NW @@ -156,14 +159,96 @@ public: private: TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1); - Node *newNode(FactionState &faction,int maxNodeCount); + //Node *newNode(FactionState &faction,int maxNodeCount); + inline static Node *newNode(FactionState &faction, int maxNodeCount) { + if( faction.nodePoolCount < faction.nodePool.size() && + //faction.nodePoolCount < faction.useMaxNodeCount) { + faction.nodePoolCount < maxNodeCount) { + Node *node= &(faction.nodePool[faction.nodePoolCount]); + node->clear(); + faction.nodePoolCount++; + return node; + } + return NULL; + } + Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos); - float heuristic(const Vec2i &pos, const Vec2i &finalPos); - bool openPos(const Vec2i &sucPos,FactionState &faction); + //float heuristic(const Vec2i &pos, const Vec2i &finalPos); + inline static float heuristic(const Vec2i &pos, const Vec2i &finalPos) { + return pos.dist(finalPos); + } - Node * minHeuristicFastLookup(FactionState &faction); + //bool openPos(const Vec2i &sucPos,FactionState &faction); + inline static bool openPos(const Vec2i &sucPos, FactionState &faction) { + if(faction.openPosList.find(sucPos) == faction.openPosList.end()) { + return false; + } + return true; + } + + + //Node * minHeuristicFastLookup(FactionState &faction); + inline static Node * minHeuristicFastLookup(FactionState &faction) { + assert(faction.openNodesList.empty() == false); + if(faction.openNodesList.empty() == true) { + throw megaglest_runtime_error("openNodesList.empty() == true"); + } + + 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 processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached, int maxNodeCount); + inline bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached,int maxNodeCount) { + bool result = false; + Vec2i sucPos= node->pos + Vec2i(i, j); + + // std::map > >::iterator iterFind1 = factions[unit->getFactionIndex()].mapFromToNodeList.find(unit->getType()->getId()); + // if(iterFind1 != factions[unit->getFactionIndex()].mapFromToNodeList.end()) { + // std::map >::iterator iterFind2 = iterFind1->second.find(node->pos); + // if(iterFind2 != iterFind1->second.end()) { + // std::map::iterator iterFind3 = iterFind2->second.find(sucPos); + // if(iterFind3 != iterFind2->second.end()) { + // //printf("found duplicate check in processNode\n"); + // return iterFind3->second; + // } + // } + // } + + //bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos); + //bool canUnitMoveToCell = map->aproxCanMoveSoon(unit, node->pos, sucPos); + if(openPos(sucPos, factions[unit->getFactionIndex()]) == false && + canUnitMoveSoon(unit, node->pos, sucPos) == true) { + //if node is not open and canMove then generate another node + Node *sucNode= newNode(factions[unit->getFactionIndex()],maxNodeCount); + 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(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) { + factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear(); + } + factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode); + factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true; + + result = true; + } + else { + nodeLimitReached= true; + } + } + + // factions[unit->getFactionIndex()].mapFromToNodeList[unit->getType()->getId()][node->pos][sucPos] = result; + return result; + } - bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached, int maxNodeCount); void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist); int getPathFindExtendRefreshNodeCount(int factionIndex); @@ -187,7 +272,33 @@ private: Vec2i jump(Vec2i dest, direction dir, Vec2i start,std::vector &path,int pathLength); bool addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded,bool bypassChecks); - bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2); + //bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2); + inline bool canUnitMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) { + bool result = true; + + // std::map > &badCellList = factions[unit->getFactionIndex()].badCellList; + // if(badCellList.find(unit->getType()->getSize()) != badCellList.end()) { + // std::map &badFieldList = badCellList[unit->getType()->getSize()]; + // if(badFieldList.find(unit->getCurrField()) != badFieldList.end()) { + // BadUnitNodeList &badList = badFieldList[unit->getCurrField()]; + // if(badList.isPosBad(pos1,pos2) == true) { + // result = false; + // } + // } + // } + // if(result == true) { + // //bool canUnitMoveToCell = map->canMove(unit, unitPos, pos); + // //bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos); + // result = map->aproxCanMoveSoon(unit, pos1, pos2); + // if(result == false) { + // badCellList[unit->getType()->getSize()][unit->getCurrField()].badPosList[pos1][pos2]=false; + // } + // } + + result = map->aproxCanMoveSoon(unit, pos1, pos2); + return result; + } + }; }}//end namespace diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 9bf031ac..5b90ba83 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -53,30 +53,8 @@ Cell::Cell() { // ==================== misc ==================== //returns if the cell is free -bool Cell::isFree(Field field) const { - bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting(); - - if(result == false) { - //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); - } - - return result; -} //returns if the cell is free -bool Cell::isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const { - bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting(); - - if(result == false) { - if(originPos.dist(cellPos) > 5 && getUnit(field)->getType()->isMobile() == true) { - result = true; - } - - //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); - } - - return result; -} void Cell::saveGame(XmlNode *rootNode, int index) const { bool saveCell = false; @@ -171,16 +149,6 @@ void SurfaceCell::end(){ } } - -bool SurfaceCell::isFree() const { - bool result = object==NULL || object->getWalkable(); - - if(result == false) { - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - } - return result; -} - void SurfaceCell::deleteResource() { cellChangedFromOriginalMapLoad = true; @@ -357,48 +325,6 @@ void Map::end(){ if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } -int Map::getSurfaceCellArraySize() const { - return (surfaceW * surfaceH); -} - -SurfaceCell *Map::getSurfaceCell(const Vec2i &sPos) const { - return getSurfaceCell(sPos.x, sPos.y); -} - -SurfaceCell *Map::getSurfaceCell(int sx, int sy) const { - int arrayIndex = sy * surfaceW + sx; - if(arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) { - throw megaglest_runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + - " surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH) + - " sx: " + intToStr(sx) + " sy: " + intToStr(sy)); - } - else if(surfaceCells == NULL) { - throw megaglest_runtime_error("surfaceCells == NULL"); - } - return &surfaceCells[arrayIndex]; -} - -int Map::getCellArraySize() const { - return (w * h); -} - -Cell *Map::getCell(const Vec2i &pos) const { - return getCell(pos.x, pos.y); -} - -Cell *Map::getCell(int x, int y) const { - int arrayIndex = y * w + x; - if(arrayIndex < 0 || arrayIndex >= getCellArraySize()) { - //abort(); - throw megaglest_runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h)); - } - else if(cells == NULL) { - throw megaglest_runtime_error("cells == NULL"); - } - - return &cells[arrayIndex]; -} - Vec2i Map::getStartLocation(int locationIndex) const { if(locationIndex >= maxPlayers) { char szBuf[4096]=""; @@ -558,22 +484,6 @@ void Map::init(Tileset *tileset) { // ==================== is ==================== -bool Map::isInside(int x, int y) const { - return x>=0 && y>=0 && x=0 && sy>=0 && sx +#include "unit_type.h" #include "leak_dumper.h" @@ -59,17 +60,37 @@ public: Cell(); //get - Unit *getUnit(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return units[field];} - Unit *getUnitWithEmptyCellMap(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return unitsWithEmptyCellMap[field];} - float getHeight() const {return height;} + inline Unit *getUnit(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return units[field];} + inline Unit *getUnitWithEmptyCellMap(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return unitsWithEmptyCellMap[field];} + inline float getHeight() const {return height;} void setUnit(int field, Unit *unit) { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} units[field]= unit;} void setUnitWithEmptyCellMap(int field, Unit *unit) { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} unitsWithEmptyCellMap[field]= unit;} void setHeight(float height) {this->height= height;} - bool isFree(Field field) const; + inline bool isFree(Field field) const { + bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting(); - bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const; + if(result == false) { + //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); + } + + return result; + } + + inline bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const { + bool result = getUnit(field) == NULL || getUnit(field)->isPutrefacting(); + + if(result == false) { + if(originPos.dist(cellPos) > 5 && getUnit(field)->getType()->isMobile() == true) { + result = true; + } + + //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); + } + + return result; + } void saveGame(XmlNode *rootNode,int index) const; void loadGame(const XmlNode *rootNode, int index, World *world); @@ -125,8 +146,8 @@ public: const Vec2f &getSurfTexCoord() const {return surfTexCoord;} bool getNearSubmerged() const {return nearSubmerged;} - bool isVisible(int teamIndex) const {return visible[teamIndex];} - bool isExplored(int teamIndex) const {return explored[teamIndex];} + inline bool isVisible(int teamIndex) const {return visible[teamIndex];} + inline bool isExplored(int teamIndex) const {return explored[teamIndex];} //set void setVertex(const Vec3f &vertex) {this->vertex= vertex;} @@ -145,7 +166,14 @@ public: //misc void deleteResource(); bool decAmount(int value); - bool isFree() const; + inline bool isFree() const { + bool result = object==NULL || object->getWalkable(); + + if(result == false) { + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + } + return result; + } bool getCellChangedFromOriginalMapLoad() const { return cellChangedFromOriginalMapLoad; } void saveGame(XmlNode *rootNode,int index) const; @@ -196,34 +224,74 @@ public: Checksum load(const string &path, TechTree *techTree, Tileset *tileset); //get - Cell *getCell(int x, int y) const; - int getCellArraySize() const; - Cell *getCell(const Vec2i &pos) const; - int getSurfaceCellArraySize() const; - SurfaceCell *getSurfaceCell(int sx, int sy) const; - SurfaceCell *getSurfaceCell(const Vec2i &sPos) const; - int getW() const {return w;} - int getH() const {return h;} - int getSurfaceW() const {return surfaceW;} - int getSurfaceH() const {return surfaceH;} - int getMaxPlayers() const {return maxPlayers;} - float getHeightFactor() const {return heightFactor;} - float getWaterLevel() const {return waterLevel;} - float getCliffLevel() const {return cliffLevel;} - int getCameraHeight() const {return cameraHeight;} - float getMaxMapHeight() const {return maxMapHeight;} + inline Cell *getCell(int x, int y) const { + int arrayIndex = y * w + x; + if(arrayIndex < 0 || arrayIndex >= getCellArraySize()) { + //abort(); + throw megaglest_runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h)); + } + else if(cells == NULL) { + throw megaglest_runtime_error("cells == NULL"); + } + + return &cells[arrayIndex]; + } + inline Cell *getCell(const Vec2i &pos) const { + return getCell(pos.x, pos.y); + } + + inline int getCellArraySize() const { + return (w * h); + } + inline int getSurfaceCellArraySize() const { + return (surfaceW * surfaceH); + } + inline SurfaceCell *getSurfaceCell(int sx, int sy) const { + int arrayIndex = sy * surfaceW + sx; + if(arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) { + throw megaglest_runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + + " surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH) + + " sx: " + intToStr(sx) + " sy: " + intToStr(sy)); + } + else if(surfaceCells == NULL) { + throw megaglest_runtime_error("surfaceCells == NULL"); + } + return &surfaceCells[arrayIndex]; + } + inline SurfaceCell *getSurfaceCell(const Vec2i &sPos) const { + return getSurfaceCell(sPos.x, sPos.y); + } + + inline int getW() const {return w;} + inline int getH() const {return h;} + inline int getSurfaceW() const {return surfaceW;} + inline int getSurfaceH() const {return surfaceH;} + inline int getMaxPlayers() const {return maxPlayers;} + inline float getHeightFactor() const {return heightFactor;} + inline float getWaterLevel() const {return waterLevel;} + inline float getCliffLevel() const {return cliffLevel;} + inline int getCameraHeight() const {return cameraHeight;} + inline float getMaxMapHeight() const {return maxMapHeight;} Vec2i getStartLocation(int locationIndex) const; - bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()getHeight()getHeight()getHeight()getHeight()getHeight()getHeight()getHeight()=0 && y>=0 && x=0 && sy>=0 && sx