Skip to content

Commit

Permalink
fix #5763 after 13517d8#diff-5f8d61f00d2ba54bf017a831c6336272L1259
Browse files Browse the repository at this point in the history
also fix unchecked maxFeatureIDs argument in CAICallback::GetFeatures/2
  • Loading branch information
rt committed Sep 16, 2017
1 parent 38fcf02 commit 9837521
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 73 deletions.
70 changes: 38 additions & 32 deletions rts/ExternalAI/AICallback.cpp
Expand Up @@ -1226,75 +1226,81 @@ bool CAICallback::UnitBeingBuilt(int unitId)
return beingBuilt;
}

int CAICallback::GetFeatures(int* featureIds, int featureIds_sizeMax)


int CAICallback::GetFeatures(int* featureIds, int maxFeatureIDs)
{
int numFeatures = 0;
int numFeatureIDs = 0;

verify();
const int allyteam = teamHandler->AllyTeam(team);

const auto& activeFeatureIDs = featureHandler->GetActiveFeatureIDs();
for (const int featureID: activeFeatureIDs) {
// non-spatial query
for (const int featureID: featureHandler->GetActiveFeatureIDs()) {
if (numFeatureIDs >= maxFeatureIDs)
break;

const CFeature* f = featureHandler->GetFeature(featureID);

assert(f != nullptr);

if (f->IsInLosForAllyTeam(allyteam)) {
// if NULL, caller only wants to know the number of features
if (featureIds != nullptr)
featureIds[numFeatures] = f->id;
if (!f->IsInLosForAllyTeam(allyteam))
continue;

numFeatures++;
}
// if array is NULL, caller only wants to know the number of features
if (featureIds != nullptr)
featureIds[numFeatureIDs] = f->id;

numFeatureIDs++;
}

return numFeatures;
return numFeatureIDs;
}

int CAICallback::GetFeatures(int* featureIds, int featureIds_sizeMax, const float3& pos, float radius)
int CAICallback::GetFeatures(int* featureIds, int maxFeatureIDs, const float3& pos, float radius)
{
int featureIds_size = 0;
int numFeatureIDs = 0;

verify();
QuadFieldQuery qfQuery;
quadField->GetFeaturesExact(qfQuery, pos, radius);
const int allyteam = teamHandler->AllyTeam(team);

std::vector<CFeature*>::const_iterator it;
for (const CFeature* f: *qfQuery.features) {
if (f->IsInLosForAllyTeam(allyteam)) {
// if it is NULL, the caller only wants to know
// the number of features
if (featureIds != NULL) {
featureIds[featureIds_size] = f->id;
}
featureIds_size++;
}
if (numFeatureIDs >= maxFeatureIDs)
break;

if (!f->IsInLosForAllyTeam(allyteam))
continue;

// if array is NULL, caller only wants to know the number of features
if (featureIds != nullptr)
featureIds[numFeatureIDs] = f->id;

numFeatureIDs++;
}

return featureIds_size;
return numFeatureIDs;
}



const FeatureDef* CAICallback::GetFeatureDef(int featureId)
{
const FeatureDef* featureDef = NULL;

verify();

const FeatureDef* featureDef = nullptr;
const CFeature* f = featureHandler->GetFeature(featureId);

if (f) {
const int allyteam = teamHandler->AllyTeam(team);
if (f->IsInLosForAllyTeam(allyteam)) {
featureDef = f->def;
}
}
if (f != nullptr && f->IsInLosForAllyTeam(teamHandler->AllyTeam(team)))
featureDef = f->def;

return featureDef;
}
const FeatureDef* CAICallback::GetFeatureDefById(int featureDefId)
{
// NOTE: this function is never called, implemented in SSkirmishAICallbackImpl
return NULL;
return nullptr;
}

float CAICallback::GetFeatureHealth(int featureId)
Expand Down
16 changes: 8 additions & 8 deletions rts/Sim/Path/Default/IPathFinder.cpp
Expand Up @@ -32,22 +32,22 @@ int2 IPathFinder::PE_DIRECTION_VECTORS[PATH_DIRECTIONS] = {

//FIXME why not use PATHDIR_* consts and merge code with top one
int2 IPathFinder::PF_DIRECTION_VECTORS_2D[PATH_DIRECTIONS << 1] = {
int2(0, 0),
int2( 0, 0 ),
int2(+1 * PATH_NODE_SPACING, 0 * PATH_NODE_SPACING), // PATHOPT_LEFT
int2(-1 * PATH_NODE_SPACING, 0 * PATH_NODE_SPACING), // PATHOPT_RIGHT
int2(0, 0), // PATHOPT_LEFT | PATHOPT_RIGHT
int2( 0, 0 ), // PATHOPT_LEFT | PATHOPT_RIGHT
int2( 0 * PATH_NODE_SPACING, +1 * PATH_NODE_SPACING), // PATHOPT_UP
int2(+1 * PATH_NODE_SPACING, +1 * PATH_NODE_SPACING), // PATHOPT_LEFT | PATHOPT_UP
int2(-1 * PATH_NODE_SPACING, +1 * PATH_NODE_SPACING), // PATHOPT_RIGHT | PATHOPT_UP
int2(0, 0), // PATHOPT_LEFT | PATHOPT_RIGHT | PATHOPT_UP
int2( 0, 0 ), // PATHOPT_LEFT | PATHOPT_RIGHT | PATHOPT_UP
int2( 0 * PATH_NODE_SPACING, -1 * PATH_NODE_SPACING), // PATHOPT_DOWN
int2(+1 * PATH_NODE_SPACING, -1 * PATH_NODE_SPACING), // PATHOPT_LEFT | PATHOPT_DOWN
int2(-1 * PATH_NODE_SPACING, -1 * PATH_NODE_SPACING), // PATHOPT_RIGHT | PATHOPT_DOWN
int2(0, 0),
int2(0, 0),
int2(0, 0),
int2(0, 0),
int2(0, 0),
int2( 0, 0 ),
int2( 0, 0 ),
int2( 0, 0 ),
int2( 0, 0 ),
int2( 0, 0 ),
};


Expand Down
2 changes: 2 additions & 0 deletions rts/Sim/Path/Default/IPathFinder.h
Expand Up @@ -68,6 +68,8 @@ class IPathFinder {
const unsigned int maxNodes
);

virtual IPathFinder* GetParent() { return nullptr; }

protected:
IPath::SearchResult InitSearch(const MoveDef&, const CPathFinderDef&, const CSolidObject* owner);

Expand Down
67 changes: 36 additions & 31 deletions rts/Sim/Path/Default/PathConstants.h
Expand Up @@ -7,54 +7,57 @@
#include <array>
#include "Sim/Misc/GlobalConstants.h"

static const float PATHCOST_INFINITY = std::numeric_limits<float>::infinity();
static constexpr float PATHCOST_INFINITY = std::numeric_limits<float>::infinity();

// NOTE:
// PF and PE both use a PathNodeBuffer of size MAX_SEARCHED_NODES,
// thus MAX_SEARCHED_NODES_{PF, PE} MUST be <= MAX_SEARCHED_NODES
static const unsigned int MAX_SEARCHED_NODES = 65536U;
static const unsigned int MAX_SEARCHED_NODES_PF = MAX_SEARCHED_NODES;
static const unsigned int MAX_SEARCHED_NODES_PE = MAX_SEARCHED_NODES;
static constexpr unsigned int MAX_SEARCHED_NODES = 65536U;
static constexpr unsigned int MAX_SEARCHED_NODES_PF = MAX_SEARCHED_NODES;
static constexpr unsigned int MAX_SEARCHED_NODES_PE = MAX_SEARCHED_NODES;

// PathManager distance thresholds (to use PF or PE)
static const float MAXRES_SEARCH_DISTANCE = 50.0f;
static const float MEDRES_SEARCH_DISTANCE = 100.0f;
static constexpr float MAXRES_SEARCH_DISTANCE = 50.0f;
static constexpr float MEDRES_SEARCH_DISTANCE = 100.0f;
// path-refinement lookahead distances (MED to MAX and LOW to MED)
static const float MAXRES_SEARCH_DISTANCE_EXT = (MAXRES_SEARCH_DISTANCE * 0.4f) * SQUARE_SIZE;
static const float MEDRES_SEARCH_DISTANCE_EXT = (MEDRES_SEARCH_DISTANCE * 0.4f) * SQUARE_SIZE;

// how many recursive refinement attempts NextWayPoint should make
static const unsigned int MAX_PATH_REFINEMENT_DEPTH = 4;
static constexpr unsigned int MAX_PATH_REFINEMENT_DEPTH = 4;

static const unsigned int PATHESTIMATOR_VERSION = 86;
static constexpr unsigned int PATHESTIMATOR_VERSION = 86;

static const unsigned int MEDRES_PE_BLOCKSIZE = 16;
static const unsigned int LOWRES_PE_BLOCKSIZE = 32;
static constexpr unsigned int MEDRES_PE_BLOCKSIZE = 16;
static constexpr unsigned int LOWRES_PE_BLOCKSIZE = 32;

static const unsigned int SQUARES_TO_UPDATE = 1000;
static const unsigned int MAX_SEARCHED_NODES_ON_REFINE = 2000;
static constexpr unsigned int SQUARES_TO_UPDATE = 1000;
static constexpr unsigned int MAX_SEARCHED_NODES_ON_REFINE = 2000;

static const unsigned int PATH_HEATMAP_XSCALE = 1; // wrt. mapDims.hmapx
static const unsigned int PATH_HEATMAP_ZSCALE = 1; // wrt. mapDims.hmapy
static const unsigned int PATH_FLOWMAP_XSCALE = 32; // wrt. mapDims.mapx
static const unsigned int PATH_FLOWMAP_ZSCALE = 32; // wrt. mapDims.mapy
static constexpr unsigned int PATH_HEATMAP_XSCALE = 1; // wrt. mapDims.hmapx
static constexpr unsigned int PATH_HEATMAP_ZSCALE = 1; // wrt. mapDims.hmapy
static constexpr unsigned int PATH_FLOWMAP_XSCALE = 32; // wrt. mapDims.mapx
static constexpr unsigned int PATH_FLOWMAP_ZSCALE = 32; // wrt. mapDims.mapy


// PE-only flags (indices)
enum {
PATHDIR_LEFT = 0, // +x
PATHDIR_LEFT = 0, // +x (LEFT *TO* RIGHT)
PATHDIR_LEFT_UP = 1, // +x+z
PATHDIR_UP = 2, // +z
PATHDIR_UP = 2, // +z (UP *TO* DOWN)
PATHDIR_RIGHT_UP = 3, // -x+z
PATHDIR_RIGHT = 4, // -x

PATHDIR_RIGHT = 4, // -x (RIGHT *TO* LEFT)
PATHDIR_RIGHT_DOWN = 5, // -x-z
PATHDIR_DOWN = 6, // -z
PATHDIR_DOWN = 6, // -z (DOWN *TO* UP)
PATHDIR_LEFT_DOWN = 7, // +x-z

PATH_DIRECTIONS = 8,
};
static const unsigned int PATHDIR_CARDINALS[4] = {PATHDIR_LEFT, PATHDIR_RIGHT, PATHDIR_UP, PATHDIR_DOWN};
static const unsigned int PATH_DIRECTION_VERTICES = PATH_DIRECTIONS >> 1;
static const unsigned int PATH_NODE_SPACING = 2;

static constexpr unsigned int PATHDIR_CARDINALS[4] = {PATHDIR_LEFT, PATHDIR_RIGHT, PATHDIR_UP, PATHDIR_DOWN};
static constexpr unsigned int PATH_DIRECTION_VERTICES = PATH_DIRECTIONS >> 1;
static constexpr unsigned int PATH_NODE_SPACING = 2;

// note: because the spacing between nodes is 2 (not 1) we
// must also make sure not to skip across any intermediate
Expand All @@ -75,12 +78,14 @@ enum {

PATHOPT_SIZE = 255, // size of PATHOPT bitmask
};
static const unsigned int PATHOPT_CARDINALS = (PATHOPT_RIGHT | PATHOPT_LEFT | PATHOPT_UP | PATHOPT_DOWN);

static constexpr unsigned int PATHOPT_CARDINALS = (PATHOPT_RIGHT | PATHOPT_LEFT | PATHOPT_UP | PATHOPT_DOWN);


static inline std::array<unsigned int, PATH_DIRECTIONS> GetPathDir2PathOpt()
{
std::array<unsigned int, PATH_DIRECTIONS> a;

a[PATHDIR_LEFT] = PATHOPT_LEFT;
a[PATHDIR_RIGHT] = PATHOPT_RIGHT;
a[PATHDIR_UP] = PATHOPT_UP;
Expand All @@ -89,23 +94,27 @@ static inline std::array<unsigned int, PATH_DIRECTIONS> GetPathDir2PathOpt()
a[PATHDIR_RIGHT_UP] = (PATHOPT_RIGHT | PATHOPT_UP);
a[PATHDIR_RIGHT_DOWN] = (PATHOPT_RIGHT | PATHOPT_DOWN);
a[PATHDIR_LEFT_DOWN] = (PATHOPT_LEFT | PATHOPT_DOWN);

return a;
}

static inline std::array<unsigned int, 15> GetPathOpt2PathDir()
{
std::array<unsigned int, 15> a;
a.fill(0);

a[PATHOPT_LEFT] = PATHDIR_LEFT;
a[PATHOPT_RIGHT] = PATHDIR_RIGHT;
a[PATHOPT_UP] = PATHDIR_UP;
a[PATHOPT_DOWN] = PATHDIR_DOWN;

a[(PATHOPT_LEFT | PATHOPT_UP)] = PATHDIR_LEFT_UP;
a[(PATHOPT_RIGHT | PATHOPT_UP)] = PATHDIR_RIGHT_UP;
a[(PATHOPT_RIGHT | PATHOPT_DOWN)] = PATHDIR_RIGHT_DOWN;
a[(PATHOPT_LEFT | PATHOPT_DOWN)] = PATHDIR_LEFT_DOWN;
return a;
}

static const std::array<unsigned int, PATH_DIRECTIONS> DIR2OPT = GetPathDir2PathOpt();
static const std::array<unsigned int, 15> OPT2DIR = GetPathOpt2PathDir();

Expand All @@ -118,18 +127,14 @@ static inline unsigned int PathOpt2PathDir(unsigned int pathOptDir) { return OPT
// (cost(A-->B) == cost(A<--B)) so we only need to store
// (PATH_DIRECTIONS >> 1) values
static inline int GetBlockVertexOffset(unsigned int pathDir, unsigned int numBlocks) {
int bvo = 0;
int bvo = pathDir;

switch (pathDir) {
case PATHDIR_LEFT: { bvo = PATHDIR_LEFT; } break;
case PATHDIR_LEFT_UP: { bvo = PATHDIR_LEFT_UP; } break;
case PATHDIR_UP: { bvo = PATHDIR_UP; } break;
case PATHDIR_RIGHT_UP: { bvo = PATHDIR_RIGHT_UP; } break;

case PATHDIR_RIGHT: { bvo = int(PATHDIR_LEFT ) - PATH_DIRECTION_VERTICES; } break;
case PATHDIR_RIGHT_DOWN: { bvo = int(PATHDIR_LEFT_UP ) - (numBlocks * PATH_DIRECTION_VERTICES) - PATH_DIRECTION_VERTICES; } break;
case PATHDIR_DOWN: { bvo = int(PATHDIR_UP ) - (numBlocks * PATH_DIRECTION_VERTICES); } break;
case PATHDIR_DOWN: { bvo = int(PATHDIR_UP ) - (numBlocks * PATH_DIRECTION_VERTICES) ; } break;
case PATHDIR_LEFT_DOWN: { bvo = int(PATHDIR_RIGHT_UP) - (numBlocks * PATH_DIRECTION_VERTICES) + PATH_DIRECTION_VERTICES; } break;
default: {} break;
}

return bvo;
Expand Down
6 changes: 4 additions & 2 deletions rts/Sim/Path/Default/PathEstimator.h
Expand Up @@ -57,6 +57,8 @@ class CPathEstimator: public IPathFinder {
*/
void Update();

IPathFinder* GetParent() override { return pathFinder; }

/**
* Returns a checksum that can be used to check if every player has the same
* path data.
Expand Down Expand Up @@ -132,10 +134,10 @@ class CPathEstimator: public IPathFinder {
std::atomic<std::int64_t> costBlockNum;
spring::barrier* pathBarrier;

IPathFinder* pathFinder;
IPathFinder* pathFinder; // parent (PF if BLOCK_SIZE is 16, PE[16] if 32)
CPathCache* pathCache[2]; // [0] = !synced, [1] = synced

std::vector<IPathFinder*> pathFinders;
std::vector<IPathFinder*> pathFinders; // InitEstimator helpers
std::vector<spring::thread*> threads;

// next lower-resolution estimator
Expand Down

0 comments on commit 9837521

Please sign in to comment.