1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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 node = out.getNode(pos, layer);
node->reset();
auto accessibility = evaluateAccessibility(pos, tinfo);
/// TODO: Probably this shouldn't be handled by initializeGraph
if(blockNotAccessible
&& (accessibility != CGPathNode::ACCESSIBLE || tinfo->terType == ETerrainType::WATER))
{
accessibility = CGPathNode::BLOCKED;
node->accessible = accessibility;
}
node->update(pos, layer, accessibility);
};
int3 pos;
@ -823,8 +824,8 @@ int CPathfinderHelper::getMovementCost(const CGHeroInstance * h, const int3 & ds
return getMovementCost(h, h->visitablePos(), dst, h->movement);
}
CGPathNode::CGPathNode(int3 Coord, ELayer Layer)
: coord(Coord), layer(Layer)
CGPathNode::CGPathNode()
: coord(int3(-1, -1, -1)), layer(ELayer::WRONG)
{
reset();
}
@ -839,6 +840,19 @@ void CGPathNode::reset()
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
{
return turns < 255;
@ -870,63 +884,61 @@ CPathsInfo::CPathsInfo(const int3 & Sizes)
{
hero = nullptr;
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()
{
}
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)
return nullptr;
return getNode(tile, layer);
boost::unique_lock<boost::mutex> pathLock(pathMx);
return getNode(tile);
}
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);
out.nodes.clear();
const CGPathNode * curnode = getNode(dst, layer);
const CGPathNode * curnode = getNode(dst);
if(!curnode->theNodeBefore)
return false;
while(curnode)
{
CGPathNode cpn = * curnode;
const CGPathNode cpn = * curnode;
curnode = curnode->theNodeBefore;
out.nodes.push_back(cpn);
}
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);
CGPath ret;
if(getPath(ret, tile, layer))
if(getPath(ret, tile))
return ret.nodes.size();
else
return 255;
}
CGPathNode * CPathsInfo::getNode(const int3 & coord, const ELayer layer) const
const CGPathNode * CPathsInfo::getNode(const int3 & coord) const
{
if(layer != ELayer::AUTO)
return nodes[coord.x][coord.y][coord.z][layer];
auto landNode = nodes[coord.x][coord.y][coord.z][ELayer::LAND];
if(landNode->theNodeBefore)
auto landNode = &nodes[coord.x][coord.y][coord.z][ELayer::LAND];
if(landNode->reachable())
return landNode;
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;
ENodeAction action;
CGPathNode(int3 Coord, ELayer Layer);
CGPathNode();
void reset();
void update(const int3 & Coord, const ELayer Layer, const EAccessibility Accessible);
bool reachable() const;
};
@ -78,14 +79,16 @@ struct DLL_LINKAGE CPathsInfo
const CGHeroInstance * hero;
int3 hpos;
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 CGPathNode * getPathInfo(const int3 & tile, const ELayer layer = ELayer::AUTO) const;
bool getPath(CGPath & out, const int3 & dst, const ELayer layer = ELayer::AUTO) const;
int getDistance(const int3 & tile, const ELayer layer = ELayer::AUTO) const;
CGPathNode * getNode(const int3 & coord, const ELayer layer) const;
const CGPathNode * getPathInfo(const int3 & tile) const;
bool getPath(CGPath & out, const int3 & dst) const;
int getDistance(const int3 & tile) const;
const CGPathNode * getNode(const int3 & coord) const;
CGPathNode * getNode(const int3 & coord, const ELayer layer);
};
class CPathfinder : private CGameInfoCallback