Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/simulation2/components/CCmpPathfinder_Common.h
/* Copyright (C) 2020 Wildfire Games. | /* Copyright (C) 2021 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 24 Lines | |||||
#include "graphics/Overlay.h" | #include "graphics/Overlay.h" | ||||
#include "graphics/Terrain.h" | #include "graphics/Terrain.h" | ||||
#include "maths/MathUtil.h" | #include "maths/MathUtil.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "renderer/TerrainOverlay.h" | #include "renderer/TerrainOverlay.h" | ||||
#include "simulation2/components/ICmpObstructionManager.h" | #include "simulation2/components/ICmpObstructionManager.h" | ||||
#include "simulation2/helpers/Grid.h" | #include "simulation2/helpers/Grid.h" | ||||
#include <vector> | |||||
class HierarchicalPathfinder; | class HierarchicalPathfinder; | ||||
class LongPathfinder; | class LongPathfinder; | ||||
class VertexPathfinder; | class VertexPathfinder; | ||||
class SceneCollector; | class SceneCollector; | ||||
class AtlasOverlay; | class AtlasOverlay; | ||||
#ifdef NDEBUG | #ifdef NDEBUG | ||||
#define PATHFIND_DEBUG 0 | #define PATHFIND_DEBUG 0 | ||||
#else | #else | ||||
#define PATHFIND_DEBUG 1 | #define PATHFIND_DEBUG 1 | ||||
#endif | #endif | ||||
/** | /** | ||||
* Implementation of ICmpPathfinder | * Implementation of ICmpPathfinder | ||||
*/ | */ | ||||
class CCmpPathfinder final : public ICmpPathfinder | class CCmpPathfinder final : public ICmpPathfinder | ||||
{ | { | ||||
protected: | |||||
class PathfinderWorker | |||||
{ | |||||
friend CCmpPathfinder; | |||||
public: | |||||
PathfinderWorker(); | |||||
// Process path requests, checking if we should stop before each new one. | |||||
void Work(const CCmpPathfinder& pathfinder); | |||||
private: | |||||
// Insert requests in m_[Long/Short]Requests depending on from. | |||||
// This could be removed when we may use if-constexpr in CCmpPathfinder::PushRequestsToWorkers | |||||
template<typename T> | |||||
void PushRequests(std::vector<T>& from, ssize_t amount); | |||||
// Stores our results, the main thread will fetch this. | |||||
std::vector<PathResult> m_Results; | |||||
std::vector<LongPathRequest> m_LongRequests; | |||||
std::vector<ShortPathRequest> m_ShortRequests; | |||||
}; | |||||
// Allow the workers to access our private variables | |||||
friend class PathfinderWorker; | |||||
public: | public: | ||||
static void ClassInit(CComponentManager& componentManager) | static void ClassInit(CComponentManager& componentManager) | ||||
{ | { | ||||
componentManager.SubscribeToMessageType(MT_Deserialized); | componentManager.SubscribeToMessageType(MT_Deserialized); | ||||
componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays | componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays | ||||
componentManager.SubscribeToMessageType(MT_TerrainChanged); | componentManager.SubscribeToMessageType(MT_TerrainChanged); | ||||
componentManager.SubscribeToMessageType(MT_WaterChanged); | componentManager.SubscribeToMessageType(MT_WaterChanged); | ||||
componentManager.SubscribeToMessageType(MT_ObstructionMapShapeChanged); | componentManager.SubscribeToMessageType(MT_ObstructionMapShapeChanged); | ||||
} | } | ||||
~CCmpPathfinder(); | ~CCmpPathfinder(); | ||||
DEFAULT_COMPONENT_ALLOCATOR(Pathfinder) | DEFAULT_COMPONENT_ALLOCATOR(Pathfinder) | ||||
// Template state: | // Template state: | ||||
std::map<std::string, pass_class_t> m_PassClassMasks; | std::map<std::string, pass_class_t> m_PassClassMasks; | ||||
std::vector<PathfinderPassability> m_PassClasses; | std::vector<PathfinderPassability> m_PassClasses; | ||||
u16 m_MaxSameTurnMoves; // Compute only this many paths when useMax is true in StartProcessingMoves. | |||||
// Dynamic state: | // Dynamic state: | ||||
std::vector<LongPathRequest> m_LongPathRequests; | |||||
std::vector<ShortPathRequest> m_ShortPathRequests; | |||||
u32 m_NextAsyncTicket; // Unique IDs for asynchronous path requests. | |||||
u16 m_MaxSameTurnMoves; // Compute only this many paths when useMax is true in StartProcessingMoves. | |||||
// Lazily-constructed dynamic state (not serialized): | // Lazily-constructed dynamic state (not serialized): | ||||
u16 m_MapSize; // tiles per side | u16 m_MapSize; // tiles per side | ||||
Grid<NavcellData>* m_Grid; // terrain/passability information | Grid<NavcellData>* m_Grid; // terrain/passability information | ||||
Grid<NavcellData>* m_TerrainOnlyGrid; // same as m_Grid, but only with terrain, to avoid some recomputations | Grid<NavcellData>* m_TerrainOnlyGrid; // same as m_Grid, but only with terrain, to avoid some recomputations | ||||
// Keep clever updates in memory to avoid memory fragmentation from the grid. | // Keep clever updates in memory to avoid memory fragmentation from the grid. | ||||
// This should be used only in UpdateGrid(), there is no guarantee the data is properly initialized anywhere else. | // This should be used only in UpdateGrid(), there is no guarantee the data is properly initialized anywhere else. | ||||
GridUpdateInformation m_DirtinessInformation; | GridUpdateInformation m_DirtinessInformation; | ||||
// The data from clever updates is stored for the AI manager | // The data from clever updates is stored for the AI manager | ||||
GridUpdateInformation m_AIPathfinderDirtinessInformation; | GridUpdateInformation m_AIPathfinderDirtinessInformation; | ||||
bool m_TerrainDirty; | bool m_TerrainDirty; | ||||
std::unique_ptr<VertexPathfinder> m_VertexPathfinder; | std::unique_ptr<VertexPathfinder> m_VertexPathfinder; | ||||
std::unique_ptr<HierarchicalPathfinder> m_PathfinderHier; | std::unique_ptr<HierarchicalPathfinder> m_PathfinderHier; | ||||
std::unique_ptr<LongPathfinder> m_LongPathfinder; | std::unique_ptr<LongPathfinder> m_LongPathfinder; | ||||
// Workers process pathing requests. | template<typename T> | ||||
std::vector<PathfinderWorker> m_Workers; | class PathRequests { | ||||
public: | |||||
std::vector<T> m_Requests; | |||||
std::vector<PathResult> m_Results; | |||||
// This is the array index of the next path to compute. | |||||
size_t m_NextPathToCompute = 0; | |||||
// This is false until all scheduled paths have been computed. | |||||
bool m_ComputeDone = true; | |||||
void ClearComputed() | |||||
{ | |||||
if (m_Results.size() == m_Requests.size()) | |||||
m_Requests.clear(); | |||||
else | |||||
m_Requests.erase(m_Requests.end() - m_Results.size(), m_Requests.end()); | |||||
m_Results.clear(); | |||||
} | |||||
/** | |||||
* @param max - if non-zero, how many paths to process. | |||||
*/ | |||||
void PrepareForComputation(u16 max) | |||||
{ | |||||
size_t n = m_Requests.size(); | |||||
if (max && n > max) | |||||
n = max; | |||||
m_NextPathToCompute = 0; | |||||
m_Results.resize(n); | |||||
m_ComputeDone = n == 0; | |||||
} | |||||
template<typename U> | |||||
void Compute(const CCmpPathfinder& cmpPathfinder, const U& pathfinder); | |||||
}; | |||||
PathRequests<LongPathRequest> m_LongPathRequests; | |||||
PathRequests<ShortPathRequest> m_ShortPathRequests; | |||||
u32 m_NextAsyncTicket; // Unique IDs for asynchronous path requests. | |||||
AtlasOverlay* m_AtlasOverlay; | AtlasOverlay* m_AtlasOverlay; | ||||
static std::string GetSchema() | static std::string GetSchema() | ||||
{ | { | ||||
return "<a:component type='system'/><empty/>"; | return "<a:component type='system'/><empty/>"; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | public: | ||||
virtual bool CheckMovement(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, pass_class_t passClass) const; | virtual bool CheckMovement(const IObstructionTestFilter& filter, entity_pos_t x0, entity_pos_t z0, entity_pos_t x1, entity_pos_t z1, entity_pos_t r, pass_class_t passClass) const; | ||||
virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint) const; | virtual ICmpObstruction::EFoundationCheck CheckUnitPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t r, pass_class_t passClass, bool onlyCenterPoint) const; | ||||
virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass) const; | virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass) const; | ||||
virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint) const; | virtual ICmpObstruction::EFoundationCheck CheckBuildingPlacement(const IObstructionTestFilter& filter, entity_pos_t x, entity_pos_t z, entity_pos_t a, entity_pos_t w, entity_pos_t h, entity_id_t id, pass_class_t passClass, bool onlyCenterPoint) const; | ||||
virtual void FetchAsyncResultsAndSendMessages(); | virtual void SendRequestedPaths(); | ||||
virtual void StartProcessingMoves(bool useMax); | virtual void StartProcessingMoves(bool useMax); | ||||
template <typename T> | template <typename T> | ||||
std::vector<T> GetMovesToProcess(std::vector<T>& requests, bool useMax = false, size_t maxMoves = 0); | std::vector<T> GetMovesToProcess(std::vector<T>& requests, bool useMax = false, size_t maxMoves = 0); | ||||
template <typename T> | template <typename T> | ||||
void PushRequestsToWorkers(std::vector<T>& from); | void PushRequestsToWorkers(std::vector<T>& from); | ||||
▲ Show 20 Lines • Show All 54 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator