1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef PATHESTIMATOR_H
#define PATHESTIMATOR_H
#include <string>
#include <vector>
#include <list>
#include "IPath.h"
#include "IPathFinder.h"
#include "PathConstants.h"
#include "PathDataTypes.h"
#include "System/float3.h"
#include <boost/detail/atomic_count.hpp>
#include <boost/cstdint.hpp>
struct MoveDef;
class CPathFinder;
class CPathEstimatorDef;
class CPathFinderDef;
class CPathCache;
class CSolidObject;
namespace boost {
class thread;
class barrier;
}
class CPathEstimator: public IPathFinder {
public:
/**
* Creates a new estimator based on a couple of parameters
* @param pathFinder
* The pathfinder to be used for exact cost-calculation of vertices.
*
* @param BSIZE
* The resolution of the estimator, given in mapsquares.
*
* @param cacheFileName
* Name of the file on disk where pre-calculated data is stored.
* The name given are added to the end of the filename, after the
* name of the corresponding map.
* Ex. PE-name "pe" + Mapname "Desert" => "Desert.pe"
*/
CPathEstimator(IPathFinder*, unsigned int BSIZE, const std::string& cacheFileName, const std::string& mapFileName);
~CPathEstimator();
/**
* This is called whenever the ground structure of the map changes
* (for example on explosions and new buildings).
* The affected rectangular area is defined by (x1, z1)-(x2, z2).
* The estimator itself will decided if an update of the area is needed.
*/
void MapChanged(unsigned int x1, unsigned int z1, unsigned int x2, unsigned int z2);
/**
* called every frame
*/
void Update();
/**
* Returns a checksum that can be used to check if every player has the same
* path data.
*/
boost::uint32_t GetPathChecksum() const { return pathChecksum; }
static const int2* GetDirectionVectorsTable();
protected: // IPathFinder impl
IPath::SearchResult DoSearch(const MoveDef&, const CPathFinderDef&, const CSolidObject* owner);
bool TestBlock(
const MoveDef& moveDef,
const CPathFinderDef& pfDef,
const PathNode* parentSquare,
const CSolidObject* owner,
const unsigned int pathOptDir,
const unsigned int blockStatus,
float speedMod,
bool withinConstraints);
IPath::SearchResult FinishSearch(const MoveDef& moveDef, const CPathFinderDef& pfDef, IPath::Path& path) const;
const CPathCache::CacheItem* GetCache(
const int2 strtBlock,
const int2 goalBlock,
float goalRadius,
int pathType,
const bool synced
) const;
void AddCache(
const IPath::Path* path,
const IPath::SearchResult result,
const int2 strtBlock,
const int2 goalBlock,
float goalRadius,
int pathType,
const bool synced
);
private:
void InitEstimator(const std::string& cacheFileName, const std::string& map);
void InitBlocks();
void CalcOffsetsAndPathCosts(unsigned int threadNum);
void CalculateBlockOffsets(unsigned int, unsigned int);
void EstimatePathCosts(unsigned int, unsigned int);
int2 FindOffset(const MoveDef&, unsigned int, unsigned int) const;
void CalculateVertices(const MoveDef&, int2, unsigned int threadNum = 0);
void CalculateVertex(const MoveDef&, int2, unsigned int, unsigned int threadNum = 0);
bool ReadFile(const std::string& cacheFileName, const std::string& map);
void WriteFile(const std::string& cacheFileName, const std::string& map);
unsigned int Hash() const;
private:
friend class CPathManager;
friend class CDefaultPathDrawer;
const unsigned int BLOCKS_TO_UPDATE;
unsigned int nextOffsetMessageIdx;
unsigned int nextCostMessageIdx;
boost::uint32_t pathChecksum; ///< currently crc from the zip
boost::detail::atomic_count offsetBlockNum;
boost::detail::atomic_count costBlockNum;
boost::barrier* pathBarrier;
IPathFinder* pathFinder;
CPathCache* pathCache[2]; /// [0] = !synced, [1] = synced
std::vector<IPathFinder*> pathFinders;
std::vector<boost::thread*> threads;
CPathEstimator* nextPathEstimator;
std::vector<float> vertexCosts;
std::list<int2> updatedBlocks; /// Blocks that may need an update due to map changes.
int blockUpdatePenalty;
};
#endif
|