Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TSdlStructArray.ipp
Go to the documentation of this file.
1#pragma once
2
10#include "SDL/sdl_helpers.h"
11#include "SDL/sdl_traits.h"
12#include "SDL/sdl_parser.h"
13#include "SDL/Tokenizer.h"
14
15#include <Common/assertion.h>
16
17#include <utility>
18
19namespace ph
20{
21
22template<typename Struct, typename Owner>
24 std::string valueName,
25 std::vector<Struct> Owner::* const valuePtr)
26
27 : TSdlOwnedField<Owner>(
28 "struct-array",
29 std::move(valueName),
30 "[S/" + getStructTypeName())
31
32 , m_valuePtr(valuePtr)
33{
34 PH_ASSERT(m_valuePtr);
35}
36
37template<typename Struct, typename Owner>
39{
40 // Default value for an array is empty
41 owner.*m_valuePtr = std::vector<Struct>{};
42}
43
44template<typename Struct, typename Owner>
45inline std::string TSdlStructArray<Struct, Owner>::valueToString(const Owner& owner) const
46{
47 const std::vector<Struct>& structVector = owner.*m_valuePtr;
48
49 return
50 "[" + std::to_string(structVector.size()) + " " +
51 getStructTypeName() + " struct instances...]";
52}
53
54template<typename Struct, typename Owner>
56 const Owner& owner,
57 std::vector<const ISdlResource*>& out_resources) const
58{
60 {
61 return;
62 }
63
64 const std::vector<Struct>& storedVector = getValueVec(owner);
65 for(const Struct& storedObj : storedVector)
66 {
67 Struct::getSdlStruct()->referencedResources(&storedObj, out_resources);
68 }
69}
70
71template<typename Struct, typename Owner>
73{
74 std::vector<Struct>* const structVec = &(owner.*m_valuePtr);
75
76 SdlNativeData data;
77 if(structVec)
78 {
79 Struct* const structVecData = structVec->data();
80
81 // Read-only for ordinary access to avoid accidental object slicing and other polymorphic
82 // assignment issues. User should use direct accessor for assignment.
83 data = SdlNativeData(
84 [structVecData](std::size_t elementIdx) -> SdlGetterVariant
85 {
86 Struct* const structPtr = &structVecData[elementIdx];
87 return structPtr
90 });
91
92 data.numElements = structVec->size();
93 data.setDirectAccessor(AnyNonConstPtr(structVec));
94 }
97 return data;
98}
99
100template<typename Struct, typename Owner>
101inline void TSdlStructArray<Struct, Owner>::setValueVec(Owner& owner, std::vector<Struct> value) const
102{
103 owner.*m_valuePtr = std::move(value);
104}
105
106template<typename Struct, typename Owner>
107inline const std::vector<Struct>& TSdlStructArray<Struct, Owner>::getValueVec(const Owner& owner) const
108{
109 return owner.*m_valuePtr;
110}
111
112template<typename Struct, typename Owner>
114 Owner& owner,
115 const SdlInputClause& clause,
116 const SdlInputContext& ctx) const
117{
118 try
119 {
120 setValueVec(owner, loadStructArray(clause, ctx));
121 }
122 catch(const SdlException& e)
123 {
124 throw_formatted<SdlLoadError>(
125 "on parsing struct array {} -> {}", valueToString(owner), e.whatStr());
126 }
127}
128
129template<typename Struct, typename Owner>
131 const Owner& owner,
132 SdlOutputClause& out_clause,
133 const SdlOutputContext& ctx) const
134{
135 const std::vector<Struct>& structVector = getValueVec(owner);
136 if(structVector.empty())
137 {
138 out_clause.isEmpty = true;
139 return;
140 }
141
142 static_assert(CHasSdlStructDefinition<Struct>);
143
144 // Basically generates a list of data packet names (with proper specifier)
145 try
146 {
147 if(!ctx.getNamedOutputClauses())
148 {
149 throw SdlSaveError(
150 "requires named output clauses to save");
151 }
152
153 out_clause.value = '{';
154 for(const Struct& obj : structVector)
155 {
156 SdlOutputClauses objClauses;
157 Struct::getSdlStruct()->saveObject(&obj, objClauses, ctx);
158
159 const auto generatedName = ctx.getNamedOutputClauses()->addOrUpdate(objClauses);
160
162 out_clause.value += generatedName;
163 out_clause.value += ' ';
164 }
165 out_clause.value += '}';
166 }
167 catch(const SdlException& e)
168 {
169 throw_formatted<SdlSaveError>(
170 "unable to save struct array {} -> {}", valueToString(owner), e.whatStr());
171 }
172}
173
174template<typename Struct, typename Owner>
176 const SdlInputClause& clause,
177 const SdlInputContext& ctx)
178{
179 static const Tokenizer tokenizer({' ', '\t', '\n', '\r'}, {{'"', '"'}});
180
181 if(!ctx.getSrcDataPackets())
182 {
183 throw SdlLoadError(
184 "no target data packet group specified");
185 }
186
188 {
189 auto obj = loadStruct(clause.value, ctx);
190 return {obj};
191 }
192 else if(clause.valueType == ESdlClauseValue::General)
193 {
194 std::vector<std::string> tokens;
195 tokenizer.tokenize(clause.value, tokens);
196 if(tokens.size() % 2 != 0)
197 {
198 throw SdlLoadError("syntax error: unexpected input format");
199 }
200
201 const auto numPacketNameTokens = tokens.size() / 2;
202 std::vector<Struct> structVector(numPacketNameTokens);
203 for(std::size_t i = 0; i < numPacketNameTokens; ++i)
204 {
205 const std::string packetNameToken = tokens[i * 2] + tokens[i * 2 + 1];
206 const auto packetName = sdl_parser::get_data_packet_name(packetNameToken);
207 structVector[i] = loadStruct(packetName, ctx);
208 }
209
210 return structVector;
211 }
212 else
213 {
214 throw SdlLoadError(
215 "bad data packet type (only cached target is supported)");
216 }
217}
218
219template<typename Struct, typename Owner>
221 std::string_view packetName,
222 const SdlInputContext& ctx)
223{
224 if(packetName.empty())
225 {
226 throw SdlLoadError(
227 "packet name cannot be empty");
228 }
229
230 const SdlInputClauses* const packet = ctx.getSrcDataPackets()->get(packetName);
231 if(!packet)
232 {
233 throw_formatted<SdlLoadError>(
234 "cannot find data packet with name <{}>", packetName);
235 }
236
237 static_assert(CHasSdlStructDefinition<Struct>);
238
239 // OPT: remove this copy; currently init will modify packet (pop swap)
240 SdlInputClauses copiedPacket = *packet;
241
242 Struct obj{};
243 Struct::getSdlStruct()->initObject(&obj, copiedPacket, ctx);
244 return obj;
245}
246
247template<typename Struct, typename Owner>
249{
251 {
252 PH_ASSERT(Struct::getSdlStruct());
253 return std::string(Struct::getSdlStruct()->getTypeName());
254 }
255 else
256 {
257 return "struct";
258 }
259}
260
261template<typename Struct, typename Owner>
264{
265 this->setImportance(importance);
266 return *this;
267}
268
269template<typename Struct, typename Owner>
270inline auto TSdlStructArray<Struct, Owner>::description(std::string descriptionStr)
272{
273 this->setDescription(std::move(descriptionStr));
274 return *this;
275}
276
277template<typename Struct, typename Owner>
280{
281 return withImportance(EFieldImportance::Optional);
282}
283
284template<typename Struct, typename Owner>
287{
288 return withImportance(EFieldImportance::NiceToHave);
289}
290
291template<typename Struct, typename Owner>
294{
295 return withImportance(EFieldImportance::Required);
296}
297
298}// end namespace ph
virtual const SdlInputClauses * get(std::string_view packetName) const =0
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
Container for input clauses.
Definition SdlInputClauses.h:18
Data that SDL input process can rely on.
Definition SdlInputContext.h:19
const ISdlDataPacketGroup * getSrcDataPackets() const
Definition SdlInputContext.h:98
Error on the SDL input process.
Definition sdl_exceptions.h:22
void addOrUpdate(SdlOutputClauses clauses, std::string_view clausesName)
Add a named output clauses. Potentially update the existing one.
Definition SdlNamedOutputClauses.cpp:33
Definition SdlNativeData.h:88
std::size_t numElements
Hint for number of elements in this block of native data. For example, numElements would be 12 for an...
Definition SdlNativeData.h:99
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
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
Definition SdlOutputClauses.h:14
Data that SDL output process can rely on.
Definition SdlOutputContext.h:19
SdlNamedOutputClauses * getNamedOutputClauses() const
Definition SdlOutputContext.h:97
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
Definition TSdlStructArray.h:15
static Struct loadStruct(std::string_view packetName, const SdlInputContext &ctx)
Definition TSdlStructArray.ipp:220
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 TSdlStructArray.ipp:130
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 TSdlStructArray.ipp:113
void ownedValueToDefault(Owner &owner) const override
By default, default value of the array is empty.
Definition TSdlStructArray.ipp:38
TSdlStructArray(std::string valueName, std::vector< Struct > Owner::*const valuePtr)
Definition TSdlStructArray.ipp:23
const std::vector< Struct > & getValueVec(const Owner &owner) const
Definition TSdlStructArray.ipp:107
TSdlStructArray & niceToHave()
Definition TSdlStructArray.ipp:285
TSdlStructArray & required()
Definition TSdlStructArray.ipp:292
TSdlStructArray & optional()
Definition TSdlStructArray.ipp:278
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 TSdlStructArray.ipp:72
static std::vector< Struct > loadStructArray(const SdlInputClause &clause, const SdlInputContext &ctx)
Definition TSdlStructArray.ipp:175
TSdlStructArray & withImportance(EFieldImportance importance)
Definition TSdlStructArray.ipp:262
std::string valueToString(const Owner &owner) const override
Convert the value of the field to human-readable string.
Definition TSdlStructArray.ipp:45
TSdlStructArray & description(std::string descriptionStr)
Definition TSdlStructArray.ipp:270
void setValueVec(Owner &owner, std::vector< Struct > value) const
Definition TSdlStructArray.ipp:101
void ownedResources(const Owner &owner, std::vector< const ISdlResource * > &out_resources) const override
Get all SDL resources associated by owner.
Definition TSdlStructArray.ipp:55
Definition Tokenizer.h:13
Whether T is a well-defined SDL struct.
Definition sdl_traits.h:36
constexpr char cached_specifier
Definition sdl_parser.h:10
std::string_view get_data_packet_name(std::string_view dataPacketNameToken)
Definition sdl_parser.cpp:136
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
@ General
Definition sdl_fwd.h:45
@ CachedTargetName
Definition sdl_fwd.h:51
Definition TAABB2D.h:96
Low-level helpers for SDL. Helpers are in an additional sdl namespace.