PixelBullet  0.0.1
A C++ game engine
Loading...
Searching...
No Matches
subrender_holder.h
1#pragma once
2
3#include "pixelbullet/graphics/subrender.h"
4
5#include <map>
6#include <memory>
7#include <type_traits>
8#include <typeindex>
9#include <unordered_map>
10
11namespace pixelbullet
12{
14
15class SubrenderHolder
16{
17 friend class Graphics;
18
19public:
20 SubrenderHolder() = default;
21 ~SubrenderHolder() = default;
22
23 SubrenderHolder(const SubrenderHolder&) = delete;
24 SubrenderHolder& operator=(const SubrenderHolder&) = delete;
25 SubrenderHolder(SubrenderHolder&&) noexcept = default;
26 SubrenderHolder& operator=(SubrenderHolder&&) noexcept = default;
27
28 template <typename T, typename = std::enable_if_t<std::is_convertible_v<T*, Subrender*>>>
29 bool Has() const
30 {
31 return subrenders_.count(std::type_index(typeid(T))) != 0;
32 }
33
34 template <typename T, typename = std::enable_if_t<std::is_convertible_v<T*, Subrender*>>>
35 T* Get() const
36 {
37 auto it = subrenders_.find(std::type_index(typeid(T)));
38 return (it != subrenders_.end()) ? static_cast<T*>(it->second.get()) : nullptr;
39 }
40
41 template <typename T, typename = std::enable_if_t<std::is_convertible_v<T*, Subrender*>>>
42 T* Add(const Subrender::Stage& stage, std::unique_ptr<T>&& subrender)
43 {
44 const auto type_id = std::type_index(typeid(T));
45 stages_.emplace(StageIndex(stage, subrenders_.size()), type_id);
46 subrenders_[type_id] = std::move(subrender);
47 return static_cast<T*>(subrenders_[type_id].get());
48 }
49
50 template <typename T, typename = std::enable_if_t<std::is_convertible_v<T*, Subrender*>>>
51 void Remove()
52 {
53 const auto type_id = std::type_index(typeid(T));
54 RemoveSubrenderStage(type_id);
55 subrenders_.erase(type_id);
56 }
57
58 void Clear()
59 {
60 stages_.clear();
61 subrenders_.clear();
62 }
63
64private:
65 friend class GraphicsState;
66 friend class RendererRuntimeAccess;
67
68 using StageIndex = std::pair<Subrender::Stage, std::size_t>;
69
70 void RemoveSubrenderStage(std::type_index id)
71 {
72 for (auto it = stages_.begin(); it != stages_.end();)
73 {
74 if (it->second == id)
75 {
76 it = stages_.erase(it);
77 }
78 else
79 {
80 ++it;
81 }
82 }
83 }
84
85 void RenderStage(const Subrender::Stage& stage, const RenderFrameContext& frame_context)
86 {
87 for (auto const& [stage_idx, type_id] : stages_)
88 {
89 if (stage_idx.first != stage)
90 {
91 continue;
92 }
93
94 auto& subrender = subrenders_[type_id];
95 if (subrender && subrender->IsEnabled())
96 {
97 subrender->Render(frame_context);
98 }
99 }
100 }
101
102 std::unordered_map<std::type_index, std::unique_ptr<Subrender>> subrenders_;
103 std::multimap<StageIndex, std::type_index> stages_;
104};
105} // namespace pixelbullet
Definition render_frame_context.h:15
Definition renderer_runtime_internal.h:16