1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

CPathsInfo: rework nodes multi_array allocation

This commit is contained in:
ArseniyShestakov
2015-11-12 00:05:20 +03:00
parent 09473f6648
commit d76b2b7ca8
2 changed files with 47 additions and 32 deletions

View File

@@ -566,14 +566,15 @@ void CPathfinder::initializeGraph()
auto updateNode = [&](int3 pos, ELayer layer, const TerrainTile * tinfo, bool blockNotAccessible) auto updateNode = [&](int3 pos, ELayer layer, const TerrainTile * tinfo, bool blockNotAccessible)
{ {
auto node = out.getNode(pos, layer); auto node = out.getNode(pos, layer);
node->reset();
auto accessibility = evaluateAccessibility(pos, tinfo); auto accessibility = evaluateAccessibility(pos, tinfo);
/// TODO: Probably this shouldn't be handled by initializeGraph /// TODO: Probably this shouldn't be handled by initializeGraph
if(blockNotAccessible if(blockNotAccessible
&& (accessibility != CGPathNode::ACCESSIBLE || tinfo->terType == ETerrainType::WATER)) && (accessibility != CGPathNode::ACCESSIBLE || tinfo->terType == ETerrainType::WATER))
{
accessibility = CGPathNode::BLOCKED; accessibility = CGPathNode::BLOCKED;
node->accessible = accessibility; }
node->update(pos, layer, accessibility);
}; };
int3 pos; int3 pos;
@@ -823,8 +824,8 @@ int CPathfinderHelper::getMovementCost(const CGHeroInstance * h, const int3 & ds
return getMovementCost(h, h->visitablePos(), dst, h->movement); return getMovementCost(h, h->visitablePos(), dst, h->movement);
} }
CGPathNode::CGPathNode(int3 Coord, ELayer Layer) CGPathNode::CGPathNode()
: coord(Coord), layer(Layer) : coord(int3(-1, -1, -1)), layer(ELayer::WRONG)
{ {
reset(); reset();
} }
@@ -839,6 +840,19 @@ void CGPathNode::reset()
action = UNKNOWN; action = UNKNOWN;
} }
void CGPathNode::update(const int3 & Coord, const ELayer Layer, const EAccessibility Accessible)
{
if(layer == ELayer::WRONG)
{
coord = Coord;
layer = Layer;
}
else
reset();
accessible = Accessible;
}
bool CGPathNode::reachable() const bool CGPathNode::reachable() const
{ {
return turns < 255; return turns < 255;
@@ -870,63 +884,61 @@ CPathsInfo::CPathsInfo(const int3 & Sizes)
{ {
hero = nullptr; hero = nullptr;
nodes.resize(boost::extents[sizes.x][sizes.y][sizes.z][ELayer::NUM_LAYERS]); nodes.resize(boost::extents[sizes.x][sizes.y][sizes.z][ELayer::NUM_LAYERS]);
for(int i = 0; i < sizes.x; i++)
for(int j = 0; j < sizes.y; j++)
for(int z = 0; z < sizes.z; z++)
for(int l = 0; l < ELayer::NUM_LAYERS; l++)
nodes[i][j][z][l] = new CGPathNode(int3(i, j, z), static_cast<ELayer>(l));
} }
CPathsInfo::~CPathsInfo() CPathsInfo::~CPathsInfo()
{ {
} }
const CGPathNode * CPathsInfo::getPathInfo(const int3 & tile, const ELayer layer) const const CGPathNode * CPathsInfo::getPathInfo(const int3 & tile) const
{ {
boost::unique_lock<boost::mutex> pathLock(pathMx); assert(vstd::iswithin(tile.x, 0, sizes.x));
assert(vstd::iswithin(tile.y, 0, sizes.y));
assert(vstd::iswithin(tile.z, 0, sizes.z));
if(tile.x >= sizes.x || tile.y >= sizes.y || tile.z >= sizes.z || layer >= ELayer::NUM_LAYERS) boost::unique_lock<boost::mutex> pathLock(pathMx);
return nullptr; return getNode(tile);
return getNode(tile, layer);
} }
bool CPathsInfo::getPath(CGPath & out, const int3 & dst, const ELayer layer) const bool CPathsInfo::getPath(CGPath & out, const int3 & dst) const
{ {
boost::unique_lock<boost::mutex> pathLock(pathMx); boost::unique_lock<boost::mutex> pathLock(pathMx);
out.nodes.clear(); out.nodes.clear();
const CGPathNode * curnode = getNode(dst, layer); const CGPathNode * curnode = getNode(dst);
if(!curnode->theNodeBefore) if(!curnode->theNodeBefore)
return false; return false;
while(curnode) while(curnode)
{ {
CGPathNode cpn = * curnode; const CGPathNode cpn = * curnode;
curnode = curnode->theNodeBefore; curnode = curnode->theNodeBefore;
out.nodes.push_back(cpn); out.nodes.push_back(cpn);
} }
return true; return true;
} }
int CPathsInfo::getDistance(const int3 & tile, const ELayer layer) const int CPathsInfo::getDistance(const int3 & tile) const
{ {
boost::unique_lock<boost::mutex> pathLock(pathMx); boost::unique_lock<boost::mutex> pathLock(pathMx);
CGPath ret; CGPath ret;
if(getPath(ret, tile, layer)) if(getPath(ret, tile))
return ret.nodes.size(); return ret.nodes.size();
else else
return 255; return 255;
} }
CGPathNode * CPathsInfo::getNode(const int3 & coord, const ELayer layer) const const CGPathNode * CPathsInfo::getNode(const int3 & coord) const
{ {
if(layer != ELayer::AUTO) auto landNode = &nodes[coord.x][coord.y][coord.z][ELayer::LAND];
return nodes[coord.x][coord.y][coord.z][layer]; if(landNode->reachable())
auto landNode = nodes[coord.x][coord.y][coord.z][ELayer::LAND];
if(landNode->theNodeBefore)
return landNode; return landNode;
else else
return nodes[coord.x][coord.y][coord.z][ELayer::SAIL]; return &nodes[coord.x][coord.y][coord.z][ELayer::SAIL];
}
CGPathNode * CPathsInfo::getNode(const int3 & coord, const ELayer layer)
{
return &nodes[coord.x][coord.y][coord.z][layer];
} }

View File

@@ -55,8 +55,9 @@ struct DLL_LINKAGE CGPathNode
ELayer layer; ELayer layer;
ENodeAction action; ENodeAction action;
CGPathNode(int3 Coord, ELayer Layer); CGPathNode();
void reset(); void reset();
void update(const int3 & Coord, const ELayer Layer, const EAccessibility Accessible);
bool reachable() const; bool reachable() const;
}; };
@@ -78,14 +79,16 @@ struct DLL_LINKAGE CPathsInfo
const CGHeroInstance * hero; const CGHeroInstance * hero;
int3 hpos; int3 hpos;
int3 sizes; int3 sizes;
boost::multi_array<CGPathNode *, 4> nodes; //[w][h][level][layer] boost::multi_array<CGPathNode, 4> nodes; //[w][h][level][layer]
CPathsInfo(const int3 & Sizes); CPathsInfo(const int3 & Sizes);
~CPathsInfo(); ~CPathsInfo();
const CGPathNode * getPathInfo(const int3 & tile, const ELayer layer = ELayer::AUTO) const; const CGPathNode * getPathInfo(const int3 & tile) const;
bool getPath(CGPath & out, const int3 & dst, const ELayer layer = ELayer::AUTO) const; bool getPath(CGPath & out, const int3 & dst) const;
int getDistance(const int3 & tile, const ELayer layer = ELayer::AUTO) const; int getDistance(const int3 & tile) const;
CGPathNode * getNode(const int3 & coord, const ELayer layer) const; const CGPathNode * getNode(const int3 & coord) const;
CGPathNode * getNode(const int3 & coord, const ELayer layer);
}; };
class CPathfinder : private CGameInfoCallback class CPathfinder : private CGameInfoCallback