Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TSdlAnyInstance.ipp
Go to the documentation of this file.
1#pragma once
2
4#include "Utility/traits.h"
5#include "Utility/utility.h"
6#include "SDL/sdl_traits.h"
7#include "SDL/sdl_helpers.h"
11
12#include <Common/assertion.h>
13
14#include <utility>
15
16namespace ph
17{
18
19template<bool IS_CONST>
23
24template<bool IS_CONST>
25inline TSdlAnyInstance<IS_CONST>::TSdlAnyInstance(std::nullptr_t /* instance */)
26 : m_instance()
27 , m_meta()
28{}
29
30template<bool IS_CONST>
31template<typename T>
34{
35 static_assert(sizeof(T) == sizeof(T),
36 "Input must be a complete type.");
37
38 if constexpr(CDerived<T, ISdlResource>)
39 {
40 // `T` may be const qualified; this automatically sets the right type (void pointer has
41 // lower rank in overload resolution)
42 m_instance = target;
43
44 if(target)
45 {
46 m_meta = target->getDynamicSdlClass();
47 }
48 else if constexpr(CHasSdlClassDefinition<T>)
49 {
50 m_meta = T::getSdlClass();
51 }
52 }
53 else if constexpr(CHasSdlStructDefinition<T>)
54 {
55 // `T` may be const qualified; this automatically sets the right type
56 m_instance = target;
57
58 m_meta = T::getSdlStruct();
59 }
60 else if constexpr(CHasSdlFunctionDefinition<T>)
61 {
62 // `T` may be const qualified; this automatically sets the right type
63 m_instance = target;
64
65 m_meta = T::getSdlFunction();
66 }
67 else
68 {
69 PH_STATIC_ASSERT_DEPENDENT_FALSE(T,
70 "Input is not a valid SDL target type (must be a SDL class/struct/function).");
71
72 // Make sure every invalid `T` also fail this concept
73 static_assert(!CSdlInstance<T>);
74 }
75
76 // Make sure every valid `T` also satisfy this concept
77 static_assert(CSdlInstance<T>);
78}
79
80template<bool IS_CONST>
81template<typename T>
83{
84 using ReturnType = std::conditional_t<IS_CONST, const T, T>;
85
86 // Only one of class, struct and function can exist (may all be null also)
87 PH_ASSERT_LE(
88 (getClass() != nullptr) + (getStruct() != nullptr) + (getFunction() != nullptr),
89 1);
90
91 if constexpr(CDerived<T, ISdlResource>)
92 {
93 ClassInstanceType* const instance = std::holds_alternative<ClassInstanceType*>(m_instance)
94 ? std::get<ClassInstanceType*>(m_instance) : nullptr;
95 if(instance)
96 {
97 return sdl::cast_to<ReturnType>(instance);
98 }
99 }
100 else if constexpr(CHasSdlStructDefinition<T>)
101 {
102 if(std::holds_alternative<StructInstanceType*>(m_instance))
103 {
104 // Ensure `T` and stored instance are the same type before casting
105 if(T::getSdlStruct() == getStruct())
106 {
107 StructInstanceType* const instance = std::get<StructInstanceType*>(m_instance);
108 return static_cast<ReturnType*>(instance);
109 }
110 }
111 }
112 else if constexpr(CHasSdlFunctionDefinition<T>)
113 {
114 if(std::holds_alternative<StructInstanceType*>(m_instance))
115 {
116 // Ensure `T` and stored instance are the same type before casting
117 if(T::getSdlFunction() == getFunction())
118 {
119 StructInstanceType* const instance = std::get<StructInstanceType*>(m_instance);
120 return static_cast<ReturnType*>(instance);
121 }
122 }
123 }
124
125 return static_cast<ReturnType*>(nullptr);
126}
127
128template<bool IS_CONST>
130{
131 return std::holds_alternative<const SdlClass*>(m_meta)
132 ? std::get<const SdlClass*>(m_meta) : nullptr;
133}
134
135template<bool IS_CONST>
137{
138 return std::holds_alternative<const SdlStruct*>(m_meta)
139 ? std::get<const SdlStruct*>(m_meta) : nullptr;
140}
141
142template<bool IS_CONST>
144{
145 return std::holds_alternative<const SdlFunction*>(m_meta)
146 ? std::get<const SdlFunction*>(m_meta) : nullptr;
147}
148
149template<bool IS_CONST>
151{
152 return m_meta.index() == variant_index_of<const SdlClass*>(m_meta);
153}
154
155template<bool IS_CONST>
157{
158 return m_meta.index() == variant_index_of<const SdlStruct*>(m_meta);
159}
160
161template<bool IS_CONST>
163{
164 return m_meta.index() == variant_index_of<const SdlFunction*>(m_meta);
165}
166
167template<bool IS_CONST>
169{
170 constexpr auto classIdx = variant_index_of<const SdlClass*, MetaType>();
171 constexpr auto structIdx = variant_index_of<const SdlStruct*, MetaType>();
172 constexpr auto functionIdx = variant_index_of<const SdlFunction*, MetaType>();
173
174 switch(m_meta.index())
175 {
176 case classIdx: return std::get<classIdx>(m_meta);
177 case structIdx: return std::get<structIdx>(m_meta);
178 case functionIdx: return std::get<functionIdx>(m_meta);
179 default: return nullptr;
180 }
181}
182
183template<bool IS_CONST>
185{
186 constexpr auto classInstanceIdx = variant_index_of<ClassInstanceType*, InstanceType>();
187 constexpr auto structInstanceIdx = variant_index_of<StructInstanceType*, InstanceType>();
188
189 switch(m_instance.index())
190 {
191 case classInstanceIdx: return std::get<classInstanceIdx>(m_instance) != nullptr;
192 case structInstanceIdx: return std::get<structInstanceIdx>(m_instance) != nullptr;
193 default: return false;
194 }
195}
196
197}// end namespace ph
Definition ISdlInstantiable.h:12
Definition SdlClass.h:25
Definition SdlFunction.h:18
Definition SdlStruct.h:25
References a SDL object. This is a lightweight utility for referencing SDL objects....
Definition TSdlAnyInstance.h:20
bool isStruct() const
Definition TSdlAnyInstance.ipp:156
const SdlClass * getClass() const
Definition TSdlAnyInstance.ipp:129
const ISdlInstantiable * getInstantiable() const
Definition TSdlAnyInstance.ipp:168
const SdlStruct * getStruct() const
Definition TSdlAnyInstance.ipp:136
bool isFunction() const
Definition TSdlAnyInstance.ipp:162
TSdlAnyInstance()
Definition TSdlAnyInstance.ipp:20
bool isClass() const
Definition TSdlAnyInstance.ipp:150
const SdlFunction * getFunction() const
Definition TSdlAnyInstance.ipp:143
auto * get() const
Definition TSdlAnyInstance.ipp:82
Checks whether DerivedType is derived from BaseType. The result is also true if both types are the sa...
Definition traits.h:122
Whether T is a well-defined SDL class.
Definition sdl_traits.h:29
Whether T is a well-defined SDL function.
Definition sdl_traits.h:42
Whether T is a well-defined SDL struct.
Definition sdl_traits.h:36
Definition sdl_traits.h:55
DstType * cast_to(SrcType *srcResource)
Cast between SDL resource types. Cast the input SDL resource instance of SrcType to an instance of Ds...
Definition sdl_helpers.ipp:549
The root for all renderer implementations.
Definition EEngineProject.h:6
Low-level helpers for SDL. Helpers are in an additional sdl namespace.