Skip to content

Commit 5098ee7

Browse files
authored
Replace PriorityQueue class with it's stl equivalent (#218)
* replace PriorityQueue class with stl priority queue * delete old PriorityQueue class and it's tests * replace priority_queue push with emplace * add using keyword for long declarations * replace emplace with push when not constructing element in place * replace unneeded assignments with DISCARD * remove std::make_pair when not needed * replace priority queue empty with std::swap * fix swap call * add new wrapper class of priority_queue with clear method * add missing std:: * fix compile errors * fix misstypes * fix clear method compile errors * update priority queue templates * add priority queue tests * fix priority queue comparator in tests * fix loops * fix spelling errors * fix compile errors * fix comparsion errors * change default priority queue predicament from lesser to greater * add missing comparator * change back default predicament from greater to less * change priority queue comparator from less to greater
1 parent 290916a commit 5098ee7

File tree

13 files changed

+139
-150
lines changed

13 files changed

+139
-150
lines changed

PolyEngine/Core/Src/pe/Defines.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#include <cstddef>
8686
#include <vector>
8787
#include <deque>
88+
#include <queue>
8889
#include <future>
8990
#include <optional>
9091

PolyEngine/Core/Src/pe/core/storage/PriorityQueue.hpp

Lines changed: 58 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -2,109 +2,82 @@
22

33
#include <pe/Defines.hpp>
44

5-
65
namespace pe::core::storage
76
{
8-
template<typename T>
9-
struct DefaultCmp
10-
{
11-
bool operator()(const T& a, const T& b) const { return a < b; }
12-
};
13-
14-
15-
template <typename T, typename Less = DefaultCmp<T>>
16-
class PriorityQueue final : BaseObjectLiteralType<>
7+
template<class Ty,class Pr = std::greater<typename std::vector<Ty>::value_type> >
8+
class PriorityQueue final : public std::priority_queue<Ty,std::vector<Ty>,Pr>
179
{
1810
public:
19-
PriorityQueue(size_t prealocatedSize = 0) { Data.reserve(prealocatedSize); }
20-
PriorityQueue(Less lessCmp, size_t prealocatedSize = 0) : LessCmp(std::move(lessCmp)) { Data.reserve(prealocatedSize);}
21-
PriorityQueue(std::vector<T> data) : Data(std::move(data))
11+
12+
PriorityQueue()
13+
: std::priority_queue<Ty, std::vector<Ty>, Pr>()
2214
{
23-
for (size_t idx = Data.size() / 2; idx > 0; --idx)
24-
SiftDown(idx - 1);
2515
}
2616

27-
void Push(T val)
28-
{
29-
Data.push_back(std::move(val));
30-
SiftUp(Data.size() - 1);
17+
PriorityQueue(const std::vector<Ty>& _Cont)
18+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(Pr(), _Cont)
19+
{
3120
}
3221

33-
T Pop()
34-
{
35-
T& first = Data[0];
36-
T& last = Data[GetSize() - 1];
37-
T tmp = std::move(first);
38-
Swap(first, last);
39-
Data.pop_back();
40-
SiftDown(0);
41-
return tmp;
22+
PriorityQueue(const Pr& Pred, const std::vector<Ty>& _Cont)
23+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(Pred,_Cont)
24+
{
4225
}
4326

44-
void Clear() { Data.clear(); }
4527

46-
const T& Head() const { return Data[0]; }
47-
size_t GetSize() const { return Data.size(); }
48-
void Reserve(size_t size) { Data.reserve(size); }
49-
private:
50-
void SiftUp(size_t idx)
28+
explicit PriorityQueue(const Pr& Pred)
29+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(Pred)
5130
{
52-
while (idx > 0)
53-
{
54-
T& val = Data[idx];
55-
const size_t parentIdx = GetParent(idx);
56-
T& parent = Data[parentIdx];
57-
if (!LessCmp(val, parent))
58-
break;
59-
60-
Swap(val, parent);
61-
idx = parentIdx;
62-
}
6331
}
6432

65-
void SiftDown(size_t idx)
66-
{
67-
while (idx < GetSize())
68-
{
69-
const size_t leftChild = GetLeftChild(idx);
70-
const size_t rightChild = GetRightChild(idx);
71-
72-
const bool leftOk = leftChild < GetSize();
73-
const bool rightOk = rightChild < GetSize();
74-
75-
if (!leftOk && !rightOk)
76-
return;
77-
78-
T& val = Data[idx];
79-
// assign val, simple trick to bypass null reference limitations
80-
T* left = leftOk ? &Data[leftChild] : nullptr;
81-
T* right = rightOk ? &Data[rightChild] : nullptr;
82-
83-
const bool rightBetter = !leftOk || (rightOk && LessCmp(*right, *left));
84-
T* candidate = rightBetter ? right : left;
85-
86-
if (candidate && LessCmp(*candidate, val))
87-
{
88-
Swap(val, *candidate);
89-
idx = rightBetter ? rightChild : leftChild;
90-
}
91-
else
92-
return;
93-
}
33+
34+
template<class InIt>
35+
PriorityQueue(InIt _First, InIt _Last)
36+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(_First,_Last)
37+
{
9438
}
9539

96-
inline void Swap(T& a, T& b)
97-
{
98-
T tmp = std::move(a);
99-
a = std::move(b);
100-
b = std::move(tmp);
40+
template<class InIt>
41+
PriorityQueue(InIt _First, InIt _Last, const Pr& Pred)
42+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(_First,_Last,Pred)
43+
{
10144
}
10245

103-
inline size_t GetParent(size_t node) { return (node - 1) / 2; }
104-
inline size_t GetLeftChild(size_t node) { return 2 * node + 1; }
105-
inline size_t GetRightChild(size_t node) { return 2 * node + 2; }
46+
47+
template<class Alloc,
48+
class = std::enable_if_t<std::uses_allocator_v<std::vector<Ty>, Alloc>>>
49+
explicit PriorityQueue(const Alloc& _Al)
50+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(_Al)
51+
{
52+
}
10653

107-
Less LessCmp;
108-
std::vector<T> Data;
54+
template<class Alloc,
55+
class = std::enable_if_t<std::uses_allocator_v<std::vector<Ty>, Alloc>>>
56+
PriorityQueue(const Pr& Pred, const Alloc& _Al)
57+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(Pred,_Al)
58+
{
59+
}
60+
61+
template<class Alloc,
62+
class = std::enable_if_t<std::uses_allocator_v<std::vector<Ty>, Alloc>>>
63+
PriorityQueue(const std::priority_queue<Ty, std::vector<Ty>, Pr>& _Right, const Alloc& _Al)
64+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(_Right,_Al)
65+
{
66+
}
67+
68+
69+
template<class Alloc,
70+
class = std::enable_if_t<std::uses_allocator_v<std::vector<Ty>, Alloc>>>
71+
PriorityQueue(std::priority_queue<Ty, std::vector<Ty>, Pr>&& _Right, const Alloc& _Al)
72+
: std::priority_queue<Ty, std::vector<Ty>, Pr>(_Right,_Al)
73+
{
74+
}
75+
76+
77+
void clear()
78+
{
79+
this->c.clear();
80+
}
10981
};
110-
} //namespace Poly
82+
}
83+

PolyEngine/Core/Src/pe/core/storage/impl/IndexedStringManager.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void IndexedStringManager::scheduleErase(const IndexedStringEntry* entry)
5656
HEAVY_ASSERTE(entry->getRemovalTimePoint().value_or(0) <= removalTimePoint,
5757
"Cannot set removal time point to a previous one than already set!");
5858
entry->setRemovalTimePoint(removalTimePoint);
59-
m_ttlEntries.Push(TTLEntry{removalTimePoint, entry});
59+
m_ttlEntries.emplace(TTLEntry{removalTimePoint, entry});
6060
}
6161

6262
void IndexedStringManager::erase(const IndexedStringEntry* entry)
@@ -70,7 +70,7 @@ void IndexedStringManager::setTTLMode(bool enabled)
7070
{
7171
if(m_ttlEnabled && !enabled)
7272
{
73-
m_ttlEntries.Clear();
73+
m_ttlEntries.clear();
7474
}
7575
m_ttlEnabled = enabled;
7676
}
@@ -88,9 +88,10 @@ void IndexedStringManager::tickTTL(size_t ttlTickCount)
8888

8989
m_tickCount += ttlTickCount;
9090

91-
while(m_ttlEntries.GetSize() > 0 && m_ttlEntries.Head().m_scheduledTimePoint <= m_tickCount)
91+
while(m_ttlEntries.size() > 0 && m_ttlEntries.top().m_scheduledTimePoint <= m_tickCount)
9292
{
93-
auto entry = m_ttlEntries.Pop().m_entry;
93+
auto entry = m_ttlEntries.top().m_entry;
94+
m_ttlEntries.pop();
9495
auto realRemovalTimePoint = entry->getRemovalTimePoint();
9596
if (realRemovalTimePoint.value_or(m_tickCount+1) <= m_tickCount)
9697
{

PolyEngine/Core/Src/pe/core/storage/impl/IndexedStringManager.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct TTLEntry
1313
const IndexedStringEntry* m_entry;
1414

1515
bool operator<(const TTLEntry& rhs) const { return m_scheduledTimePoint < rhs.m_scheduledTimePoint; }
16+
bool operator>(const TTLEntry& rhs) const { return m_scheduledTimePoint > rhs.m_scheduledTimePoint; }
1617
};
1718

1819
class CORE_DLLEXPORT IndexedStringManager final : public core::BaseObjectLiteralType<>

PolyEngine/Engine/Src/AI/PathfindingSystem.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ std::optional<std::vector<::pe::core::math::Vector>> CalculateNewPath(const NavG
4040
std::map<const NavNode*, float> minCosts;
4141

4242
AllNodes.push_back(PathNode(startNode, 0, graph->GetHeuristicCost(startNode, destNode) ));
43-
openList.Push(std::make_pair(AllNodes.size() - 1, graph->GetHeuristicCost(startNode, destNode)));
43+
openList.emplace(AllNodes.size() - 1, graph->GetHeuristicCost(startNode, destNode));
4444
minCosts.emplace(startNode, 0.f);
4545

4646
i64 bestNodeIdx = -1;
4747
std::vector<const NavNode*> connections(8);
48-
while (openList.GetSize() > 0 && bestNodeIdx < 0)
48+
while (openList.size() > 0 && bestNodeIdx < 0)
4949
{
50-
i64 qIdx = openList.Pop().first;
51-
50+
i64 qIdx = openList.top().first;
51+
openList.pop();
52+
5253
connections.clear();
5354
graph->GetConnections(AllNodes[qIdx].Node, connections);
5455
for (const NavNode* connection : connections)
@@ -70,11 +71,11 @@ std::optional<std::vector<::pe::core::math::Vector>> CalculateNewPath(const NavG
7071
continue; // node has worse base cost than other (in the same pos) we visited before, skip it
7172

7273
AllNodes.push_back(s);
73-
openList.Push(std::make_pair(AllNodes.size() - 1, s.TotalCost()));
74+
openList.emplace(AllNodes.size() - 1, s.TotalCost());
7475
minCosts[s.Node] = s.Cost;
7576
}
7677

77-
closedList.Push(std::make_pair(qIdx, AllNodes[qIdx].TotalCost()));
78+
closedList.emplace(qIdx, AllNodes[qIdx].TotalCost());
7879
minCosts[AllNodes[qIdx].Node] = AllNodes[qIdx].Cost;
7980
}
8081

PolyEngine/Engine/Src/EnginePCH.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <pe/core/storage/Queue.hpp>
4444
#include <pe/core/storage/PriorityQueue.hpp>
4545

46+
4647
// Other
4748
#include <pe/core/math/Color.hpp>
4849
#include <pe/core/utils/FileIO.hpp>

PolyEngine/Engine/Src/Resources/MeshResource.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
using namespace Poly;
88

9+
using PairQueue = core::storage::PriorityQueue<std::pair<u8, float>,std::function<bool(const std::pair<u8, float>&, const std::pair<u8, float>&)>>;
10+
911
RTTI_DEFINE_TYPE(Poly::MeshResource)
1012

1113
core::math::Matrix MatFromAiMat(const aiMatrix4x4& m)
@@ -150,9 +152,9 @@ void MeshResource::SubMesh::LoadBones(aiMesh* mesh)
150152
if (mesh->HasBones())
151153
{
152154
ASSERTE((i8)mesh->mNumBones <= std::numeric_limits<typename decltype(MeshData.BoneIds)::value_type::ValueType>::max(), "Model has too many bones!");
153-
154-
std::vector<::pe::core::storage::PriorityQueue<std::pair<u8, float>, std::function<bool(const std::pair<u8, float>&, const std::pair<u8, float>&)>>> tmpBonesList;
155-
tmpBonesList.resize(mesh->mNumVertices, { [](const std::pair<u8, float>& v1, const std::pair<u8, float>& v2) { return v1.second > v2.second; } });
155+
156+
std::vector<PairQueue> tmpBonesList;
157+
tmpBonesList.resize(mesh->mNumVertices, { PairQueue([](const std::pair<u8, float>& v1, const std::pair<u8, float>& v2) { return v1.second > v2.second; })});
156158

157159
std::map<::pe::core::storage::String, size_t> nameToBoneIdx;
158160

@@ -169,7 +171,7 @@ void MeshResource::SubMesh::LoadBones(aiMesh* mesh)
169171
const auto& vertWeight = bone->mWeights[j];
170172
size_t vertId = vertWeight.mVertexId;
171173
float weight = vertWeight.mWeight;
172-
tmpBonesList[vertId].Push({ boneId, weight });
174+
tmpBonesList[vertId].emplace( boneId, weight );
173175
}
174176
}
175177
}
@@ -182,11 +184,12 @@ void MeshResource::SubMesh::LoadBones(aiMesh* mesh)
182184

183185
for (size_t vertId = 0; vertId < mesh->mNumVertices; ++vertId)
184186
{
185-
auto& boneQueue = tmpBonesList[vertId];
187+
PairQueue& boneQueue = tmpBonesList[vertId];
186188
float sum = 0.f;
187-
for (size_t k = 0; k < 4 && boneQueue.GetSize() > 0; ++k)
189+
for (size_t k = 0; k < 4 && boneQueue.size() > 0; ++k)
188190
{
189-
auto entry = boneQueue.Pop();
191+
auto entry = boneQueue.top();
192+
boneQueue.pop();
190193
sum += entry.second;
191194
MeshData.BoneIds[vertId].Data[k] = entry.first;
192195
MeshData.BoneWeights[vertId].Data[k] = entry.second;

PolyEngine/RenderingDevice/OpenGL/Src/GLWorldRendering.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <GLRenderingDevice.hpp>
44

55
#include <algorithm> // std::min
6-
6+
#include <pe/core/storage/PriorityQueue.hpp>
77
#include <Proxy/GLTextFieldBufferDeviceProxy.hpp>
88
#include <Proxy/GLTextureDeviceProxy.hpp>
99
#include <Pipeline/RenderingPassBase.hpp>
@@ -82,18 +82,18 @@ void GLRenderingDevice::FillSceneView(SceneView& sceneView)
8282
{
8383
if (meshCmp->GetBlendingMode() == eBlendingMode::OPAUQE)
8484
{
85-
sceneView.OpaqueQueue.Push(meshCmp);
85+
sceneView.OpaqueQueue.push(meshCmp);
8686
}
8787
else if (meshCmp->GetBlendingMode() == eBlendingMode::TRANSLUCENT)
8888
{
89-
sceneView.TranslucentQueue.Push(meshCmp);
89+
sceneView.TranslucentQueue.push(meshCmp);
9090
}
9191
}
9292
}
9393

9494
for (const auto& [particleCmp] : sceneView.SceneData->IterateComponents<ParticleComponent>())
9595
{
96-
sceneView.ParticleQueue.Push(particleCmp);
96+
sceneView.ParticleQueue.push(particleCmp);
9797
}
9898

9999
for (const auto& [dirLightCmp] : sceneView.SceneData->IterateComponents<DirectionalLightComponent>())
@@ -237,13 +237,12 @@ void GLRenderingDevice::CullShadowCasters(SceneView& sceneView, const core::math
237237

238238
// find all meshes that are inside extended DirLights AABB box
239239
core::math::Vector dirLightPos = sceneView.DirectionalLightList[0]->GetTransform().GetGlobalTranslation();
240-
MeshQueue shadowCasterQueue(SceneView::DistanceToCameraComparator(dirLightPos, SceneView::eSortOrderType::FRONT_TO_BACK), 0);
241-
240+
MeshQueue shadowCasterQueue(SceneView::DistanceToCameraComparator(dirLightPos, SceneView::eSortOrderType::FRONT_TO_BACK));
242241
for (auto& [box, meshCmp] : boxMeshes)
243242
{
244243
if (frustumAABBInLS.Contains(box))
245244
{
246-
shadowCasterQueue.Push(meshCmp);
245+
shadowCasterQueue.push(meshCmp);
247246

248247
if (sceneView.SettingsCmp && sceneView.SettingsCmp->DebugDrawShadowCastersBounds)
249248
DebugDrawSystem::DrawBox(scene, box.GetMin(), box.GetMax(), worldFromDirLight, core::math::Color::GREEN);

PolyEngine/RenderingDevice/OpenGL/Src/IRendererInterface.hpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <Rendering/Viewport.hpp>
55
#include <Rendering/Lighting/LightSourceComponent.hpp>
66
#include <Rendering/RenderingSettingsComponent.hpp>
7+
#include <pe/core/storage/PriorityQueue.hpp>
78

89
// TODO: inherit from BaseRenderPass - make multipass RenderPass
910

@@ -54,10 +55,10 @@ namespace Poly {
5455

5556
SceneView(Scene* s, Viewport& v)
5657
: SceneData(s), ViewportData(v), Rect(v.GetRect()), CameraCmp(v.GetCamera()),
57-
DirShadowCastersQueue(DistanceToCameraComparator(::pe::core::math::Vector::ZERO, eSortOrderType::FRONT_TO_BACK), 0), // filled by GLRenderingDevice::CullShadowCasters
58-
OpaqueQueue(DistanceToCameraComparator(v.GetCamera()->GetTransform().GetGlobalTranslation(), eSortOrderType::FRONT_TO_BACK), 0),
59-
TranslucentQueue(DistanceToCameraComparator(v.GetCamera()->GetTransform().GetGlobalTranslation(), eSortOrderType::BACK_TO_FRONT), 0),
60-
ParticleQueue(DistanceToCameraComparator(v.GetCamera()->GetTransform().GetGlobalTranslation(), eSortOrderType::BACK_TO_FRONT), 0)
58+
DirShadowCastersQueue(DistanceToCameraComparator(::pe::core::math::Vector::ZERO, eSortOrderType::FRONT_TO_BACK)), // filled by GLRenderingDevice::CullShadowCasters
59+
OpaqueQueue(DistanceToCameraComparator(v.GetCamera()->GetTransform().GetGlobalTranslation(), eSortOrderType::FRONT_TO_BACK)),
60+
TranslucentQueue(DistanceToCameraComparator(v.GetCamera()->GetTransform().GetGlobalTranslation(), eSortOrderType::BACK_TO_FRONT)),
61+
ParticleQueue(DistanceToCameraComparator(v.GetCamera()->GetTransform().GetGlobalTranslation(), eSortOrderType::BACK_TO_FRONT))
6162
{
6263
SettingsCmp = s->GetWorldComponent<RenderingSettingsComponent>();
6364
};
@@ -69,10 +70,10 @@ namespace Poly {
6970
const CameraComponent* CameraCmp;
7071
const RenderingSettingsComponent* SettingsCmp;
7172

72-
::pe::core::storage::PriorityQueue<const MeshRenderingComponent*, DistanceToCameraComparator> DirShadowCastersQueue;
73-
::pe::core::storage::PriorityQueue<const MeshRenderingComponent*, DistanceToCameraComparator> OpaqueQueue;
74-
::pe::core::storage::PriorityQueue<const MeshRenderingComponent*, DistanceToCameraComparator> TranslucentQueue;
75-
::pe::core::storage::PriorityQueue<const ParticleComponent*, DistanceToCameraComparator> ParticleQueue; // TODO: make translucent and particles one queue with common priority
73+
core::storage::PriorityQueue<const MeshRenderingComponent*, DistanceToCameraComparator> DirShadowCastersQueue;
74+
core::storage::PriorityQueue<const MeshRenderingComponent*, DistanceToCameraComparator> OpaqueQueue;
75+
core::storage::PriorityQueue<const MeshRenderingComponent*, DistanceToCameraComparator> TranslucentQueue;
76+
core::storage::PriorityQueue<const ParticleComponent*, DistanceToCameraComparator> ParticleQueue; // TODO: make translucent and particles one queue with common priority
7677

7778
::pe::core::math::AABox DirShadowAABBInLS;
7879
std::vector<const DirectionalLightComponent*> DirectionalLightList;

0 commit comments

Comments
 (0)