Skip to content

Commit ca140d7

Browse files
committed
xrGame/space_restriction_shape.h: parallelize iterate_vertices in fill_shape
1 parent 6f2447f commit ca140d7

File tree

5 files changed

+55
-7
lines changed

5 files changed

+55
-7
lines changed

src/xrAICore/Navigation/level_graph.h

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ class XRAICORE_API CLevelGraph
232232
IC void assign_y_values(xr_vector<T>& path);
233233
template <typename P>
234234
IC void iterate_vertices(const Fvector& min_position, const Fvector& max_position, const P& predicate) const;
235+
IC std::pair<CLevelVertex*, CLevelVertex*> get_range(const Fvector& min_position, const Fvector& max_position) const;
235236
IC bool check_vertex_in_direction(u32 start_vertex_id, const Fvector2& start_position, u32 finish_vertex_id) const;
236237
IC u32 check_position_in_direction(
237238
u32 start_vertex_id, const Fvector2& start_position, const Fvector2& finish_position) const;

src/xrAICore/Navigation/level_graph_inline.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,14 @@ IC void CLevelGraph::clear_mask_no_check(u32 vertex_id) { m_access_mask[vertex_i
571571
template <typename P>
572572
IC void CLevelGraph::iterate_vertices(
573573
const Fvector& min_position, const Fvector& max_position, const P& predicate) const
574+
{
575+
auto [I, E] = get_range(min_position, max_position);
576+
577+
for (; I != E; ++I)
578+
predicate(*I);
579+
}
580+
581+
IC std::pair<CLevelGraph::CLevelVertex *, CLevelGraph::CLevelVertex *> CLevelGraph::get_range(const Fvector& min_position, const Fvector& max_position) const
574582
{
575583
const auto begin = m_nodes->begin(), end = m_nodes->end();
576584

@@ -591,8 +599,7 @@ IC void CLevelGraph::iterate_vertices(
591599
else
592600
E = end;
593601

594-
for (; I != E; ++I)
595-
predicate(*I);
602+
return {I, E};
596603
}
597604

598605
IC u32 CLevelGraph::max_x() const { return (m_max_x); }

src/xrGame/Level.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,7 @@ void CLevel::OnFrame()
443443
if (g_mt_config.test(mtMap))
444444
{
445445
R_ASSERT(m_map_manager);
446-
Device.seqParallel.push_back(
447-
fastdelegate::FastDelegate0<>(m_map_manager, &CMapManager::Update));
446+
Device.seqParallel.emplace_back(m_map_manager, &CMapManager::Update);
448447
}
449448
else
450449
MapManager().Update();

src/xrGame/space_restriction_shape.cpp

+36-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "xrAICore/Navigation/level_graph.h"
1313
#include "space_restrictor.h"
1414
#include "xrAICore/Navigation/graph_engine.h"
15+
#include "xrCore/Threading/ParallelFor.hpp"
1516

1617
struct CBorderMergePredicate
1718
{
@@ -79,10 +80,43 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape)
7980
}
8081
default: NODEFAULT;
8182
}
82-
ai().level_graph().iterate_vertices(start, dest, CBorderMergePredicate(this));
83+
84+
CLevelGraph& graph = ai().level_graph();
85+
86+
std::mutex mergeMutex;
87+
88+
auto [begin, end] = graph.get_range(start, dest);
89+
xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (auto &range) {
90+
xr_vector<u32> m_border_chunk;
91+
m_border_chunk.reserve(range.size());
92+
for (auto &vertex : range)
93+
{
94+
if (inside(graph.vertex_id(&vertex), true) &&
95+
!inside(graph.vertex_id(&vertex), false))
96+
m_border_chunk.push_back(graph.vertex_id(&vertex));
97+
}
98+
std::lock_guard lock(mergeMutex);
99+
if (m_border.capacity() < m_border.size() + m_border_chunk.size())
100+
m_border.reserve(m_border.size() + m_border_chunk.size());
101+
for (auto x : m_border_chunk)
102+
m_border.push_back(x);
103+
});
83104

84105
#ifdef DEBUG
85-
ai().level_graph().iterate_vertices(start, dest, CShapeTestPredicate(this));
106+
xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (const auto &range) {
107+
xr_vector<u32> m_test_storage_chunk;
108+
m_test_storage_chunk.reserve(range.size());
109+
for (auto &vertex : range)
110+
{
111+
if (inside(graph.vertex_id(&vertex), false))
112+
m_test_storage_chunk.push_back(graph.vertex_id(&vertex));
113+
}
114+
std::lock_guard lock(mergeMutex);
115+
if (m_test_storage.capacity() < m_test_storage.size() + m_test_storage_chunk.size())
116+
m_test_storage.reserve(m_test_storage.size() + m_test_storage_chunk.size());
117+
for (auto x : m_test_storage_chunk)
118+
m_test_storage.push_back(x);
119+
});
86120
#endif
87121
}
88122

src/xrGame/space_restrictor.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,14 @@ void CSpaceRestrictor::net_Destroy()
100100
bool CSpaceRestrictor::inside(const Fsphere& sphere) const
101101
{
102102
if (!actual())
103-
prepare();
103+
{
104+
static std::mutex prepareMutex;
105+
std::lock_guard lock(prepareMutex);
106+
107+
// Double-checked locking
108+
if (!actual())
109+
prepare();
110+
}
104111

105112
if (!m_selfbounds.intersect(sphere))
106113
return (false);

0 commit comments

Comments
 (0)