Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TSdlReference.ipp
Go to the documentation of this file.
1#pragma once
2
5#include "SDL/ISdlResource.h"
8#include "SDL/sdl_helpers.h"
9
10#include <Common/assertion.h>
11#include <Common/Utility/string_utils.h>
12
13#include <utility>
14
15namespace ph
16{
17
18template<typename T, typename Owner>
20 std::string valueName,
21 std::shared_ptr<T> Owner::* const valuePtr) :
22
23 TSdlOwnedField<Owner>(
24 std::string(sdl::category_to_string(sdl::category_of<T>())),
25 std::move(valueName)),
26
27 m_valuePtr(valuePtr)
28{
29 static_assert(std::is_base_of_v<ISdlResource, T>,
30 "T must be a SDL resource (derive from ISdlResource).");
31
32 PH_ASSERT(m_valuePtr);
33}
34
35template<typename T, typename Owner>
36inline void TSdlReference<T, Owner>::ownedValueToDefault(Owner& owner) const
37{
38 // Default value for a SDL resource defined as nullptr
39 setValueRef(owner, nullptr);
40}
41
42template<typename T, typename Owner>
43inline std::string TSdlReference<T, Owner>::valueToString(const Owner& owner) const
44{
45 return
46 "[" + std::string(sdl::category_to_string(sdl::category_of<T>())) + " ref: " +
47 std::string(getValueRef(owner) ? "valid" : "empty") + "]";
48}
49
50template<typename T, typename Owner>
52 const Owner& owner,
53 std::vector<const ISdlResource*>& out_resources) const
54{
55 const T* const storedResource = getValueRef(owner).get();
56 if(storedResource != nullptr)
57 {
58 out_resources.push_back(storedResource);
59 }
60}
61
62template<typename T, typename Owner>
64{
65 std::shared_ptr<T>& valueRef = owner.*m_valuePtr;
66 T* const originalDataPtr = valueRef.get();
67
68 // Read-only for ordinary access to avoid accidental object slicing and other polymorphic
69 // assignment issues. User should use direct accessor for assignment.
71 [originalDataPtr](std::size_t elementIdx) -> SdlGetterVariant
72 {
73 return originalDataPtr
76 });
77 data.setDirectAccessor(AnyNonConstPtr(&valueRef));
80 return data;
81}
82
83template<typename T, typename Owner>
84inline void TSdlReference<T, Owner>::setValueRef(Owner& owner, std::shared_ptr<T> value) const
85{
86 owner.*m_valuePtr = std::move(value);
87}
88
89template<typename T, typename Owner>
90inline const std::shared_ptr<T>& TSdlReference<T, Owner>::getValueRef(const Owner& owner) const
91{
92 return owner.*m_valuePtr;
93}
94
95template<typename T, typename Owner>
97 Owner& owner,
98 const SdlInputClause& clause,
99 const SdlInputContext& ctx) const
100{
101 try
102 {
103 setValueRef(owner, loadReference(clause, ctx));
104 }
105 catch(const SdlException& e)
106 {
107 throw_formatted<SdlLoadError>(
108 "on parsing reference {} -> {}", valueToString(owner), e.whatStr());
109 }
110}
111
112template<typename T, typename Owner>
114 const Owner& owner,
115 SdlOutputClause& out_clause,
116 const SdlOutputContext& ctx) const
117{
118 const auto& resource = getValueRef(owner);
119 if(!resource)
120 {
121 out_clause.isEmpty = true;
122 return;
123 }
124
125 try
126 {
127 const auto resourceName = ctx.getResourceName(resource.get());
128 if(resourceName.empty())
129 {
130 throw SdlSaveError(
131 "resource name unavailable");
132 }
133
135 if(string_utils::has_any_of(resourceName, string_utils::get_whitespaces()))
136 {
137 out_clause.value = '"';
138 out_clause.value += resourceName;
139 out_clause.value += '"';
140 }
141 else
142 {
143 out_clause.value = resourceName;
144 }
145 }
146 catch(const SdlException& e)
147 {
148 throw_formatted<SdlSaveError>(
149 "on saving resource reference {} -> {}", valueToString(owner), e.whatStr());
150 }
151}
152
153template<typename T, typename Owner>
154template<typename ResourceType>
155inline std::shared_ptr<ResourceType> TSdlReference<T, Owner>::loadReference(
156 const SdlInputClause& clause,
157 const SdlInputContext& ctx)
158{
159 if(!ctx.getSrcResources())
160 {
161 throw SdlLoadError(
162 "no target reference group specified");
163 }
164
166 {
167 throw SdlLoadError(
168 "bad reference type (only persistent target is supported)");
169 }
170
171 return loadReference(clause.value, ctx);
172}
173
174template<typename T, typename Owner>
175template<typename ResourceType>
176inline std::shared_ptr<ResourceType> TSdlReference<T, Owner>::loadReference(
177 std::string_view referenceName,
178 const SdlInputContext& ctx)
179{
180 if(referenceName.empty())
181 {
182 throw SdlLoadError(
183 "reference name cannot be empty");
184 }
185
186 // TODO: allow type mismatch?
187 auto resource = ctx.getSrcResources()->getTyped<ResourceType>(referenceName);
188 if(!resource)
189 {
190 throw_formatted<SdlLoadError>(
191 "cannot find resource referenced by <{}>", referenceName);
192 }
193
194 return resource;
195}
196
197template<typename T, typename Owner>
200{
201 this->setImportance(importance);
202 return *this;
203}
204
205template<typename T, typename Owner>
206inline auto TSdlReference<T, Owner>::description(std::string descriptionStr)
208{
209 this->setDescription(std::move(descriptionStr));
210 return *this;
211}
212
213template<typename T, typename Owner>
216{
217 return withImportance(EFieldImportance::Optional);
218}
219
220template<typename T, typename Owner>
223{
224 return withImportance(EFieldImportance::NiceToHave);
225}
226
227template<typename T, typename Owner>
230{
231 return withImportance(EFieldImportance::Required);
232}
233
234}// end namespace ph
std::shared_ptr< T > getTyped(std::string_view resourceName) const
Get a resource reference of type T with name resourceName.
Definition ISdlReferenceGroup.h:48
General exception thrown on error related to SDL.
Definition sdl_exceptions.h:13
Carries SDL representation of various data during the input process. Helps to read input data such as...
Definition SdlInputClause.h:15
std::string value
Loaded stringified data of a clause. All potential SDL value prefixes or suffixes (e....
Definition SdlInputClause.h:25
ESdlClauseValue valueType
Type of the carried value. For identifying the type of the value string only. Does not check whether ...
Definition SdlInputClause.h:33
Data that SDL input process can rely on.
Definition SdlInputContext.h:19
const ISdlReferenceGroup * getSrcResources() const
Definition SdlInputContext.h:93
Error on the SDL input process.
Definition sdl_exceptions.h:22
Definition SdlNativeData.h:88
void setDirectAccessor(AnyNonConstPtr accessor)
Definition SdlNativeData.ipp:267
static auto permissiveElementGetter(ElementType *elementPtr) -> SdlGetterVariant
Given a valid target element, get its value in a permissive way (with auto conversions).
Definition SdlNativeData.ipp:312
ESdlDataType elementType
Hint for the type of elements.
Definition SdlNativeData.h:113
std::optional< T > get(std::size_t elementIdx) const
Definition SdlNativeData.ipp:182
ESdlDataFormat elementContainer
Hint for the type that encapsulates elements.
Definition SdlNativeData.h:109
Carries SDL representation of various data during the output process. Helps to write output data such...
Definition SdlOutputClause.h:14
std::string value
Stores stringified data of a clause. As the output clause generator knows best how its data look like...
Definition SdlOutputClause.h:29
bool isEmpty
If the clause carries no data and does not need to be written.
Definition SdlOutputClause.h:41
ESdlClauseValue valueType
Type of the carried value. For identifying the type of the value string only. Does not check whether ...
Definition SdlOutputClause.h:37
Data that SDL output process can rely on.
Definition SdlOutputContext.h:19
std::string_view getResourceName(const ISdlResource *resource) const
Definition SdlOutputContext.cpp:9
Error on the SDL output process.
Definition sdl_exceptions.h:30
Definition SdlNativeData.h:24
References a SDL object. This is a lightweight utility for referencing SDL objects....
Definition TSdlAnyInstance.h:20
Abstraction for a value that is owned by some owner type. Governs how a field should be initialized o...
Definition TSdlOwnedField.h:15
A value that points to a SDL resource.
Definition TSdlReference.h:21
TSdlReference & optional()
Definition TSdlReference.ipp:214
void ownedValueToDefault(Owner &owner) const override
By default, default value of a SDL reference is empty.
Definition TSdlReference.ipp:36
static std::shared_ptr< ResourceType > loadReference(const SdlInputClause &clause, const SdlInputContext &ctx)
Definition TSdlReference.ipp:155
void loadFromSdl(Owner &owner, const SdlInputClause &clause, const SdlInputContext &ctx) const override
Load SDL value to actual value and store it in the owner's field. Implementations are highly encourag...
Definition TSdlReference.ipp:96
TSdlReference & required()
Definition TSdlReference.ipp:228
SdlNativeData ownedNativeData(Owner &owner) const override
Direct access to the field memory of an owner. Short-lived owner objects such as function parameter s...
Definition TSdlReference.ipp:63
std::string valueToString(const Owner &owner) const override
Convert the value of the field to human-readable string.
Definition TSdlReference.ipp:43
const std::shared_ptr< T > & getValueRef(const Owner &owner) const
Definition TSdlReference.ipp:90
TSdlReference(std::string valueName, std::shared_ptr< T > Owner::*valuePtr)
Definition TSdlReference.ipp:19
TSdlReference & description(std::string descriptionStr)
Definition TSdlReference.ipp:206
TSdlReference & niceToHave()
Definition TSdlReference.ipp:221
TSdlReference & withImportance(EFieldImportance importance)
Definition TSdlReference.ipp:198
void ownedResources(const Owner &owner, std::vector< const ISdlResource * > &out_resources) const override
Get all SDL resources associated by owner.
Definition TSdlReference.ipp:51
void setValueRef(Owner &owner, std::shared_ptr< T > value) const
Definition TSdlReference.ipp:84
void saveToSdl(const Owner &owner, SdlOutputClause &out_clause, const SdlOutputContext &ctx) const override
Convert actual value back to SDL value. Saving a loaded value as SDL value should rarely fail–as load...
Definition TSdlReference.ipp:113
std::string_view category_to_string(const ESdlTypeCategory category)
Definition ESdlTypeCategory.h:59
constexpr ESdlTypeCategory category_of()
Statically gets the SDL category of T.
Definition sdl_helpers.ipp:409
constexpr ESdlDataType resource_type_of()
Definition sdl_helpers.ipp:492
The root for all renderer implementations.
Definition EEngineProject.h:6
TAnyPtr< false > AnyNonConstPtr
A type-safe, lightweight wrapper for any non-const raw pointer type.
Definition TAnyPtr.h:47
EFieldImportance
Definition EFieldImportance.h:7
@ PersistentTargetName
Definition sdl_fwd.h:48
Definition TAABB2D.h:96
Low-level helpers for SDL. Helpers are in an additional sdl namespace.