1#include <catch2/catch_test_macros.hpp>
3#include <Core/Containers/DynamicVisitor.hpp>
4#include <Core/Containers/VariableSetEnumManagement.hpp>
6#include <Core/Utils/Color.hpp>
7#include <Core/Utils/TypesUtils.hpp>
8#include <Engine/Data/RenderParameters.hpp>
9#include <Engine/Data/Texture.hpp>
10#include <Engine/RadiumEngine.hpp>
14using namespace Ra::Core::Utils;
21 void operator()(
const std::string& name,
const T& value ) {
22 output <<
"\tPrintThemAllVisitor: ( " << demangleType<T>() <<
" ) " << name <<
" --> "
34class StaticPrintVisitor
37 using customTypes = TypeList<std::string>;
39 using types = RenderParameters::BindableTypes::Append<customTypes>;
41 StaticPrintVisitor() {
42 std::cout <<
"StaticPrintVisitor will iterate on " << RenderParameters::BindableTypes::Size
43 <<
"+" << customTypes::Size <<
" types.\n";
46 template <typename T, typename std::enable_if<!std::is_class<T>::value,
bool>::type =
true>
48 if ( !prefix.empty() ) { output <<
"\t" << prefix <<
": "; }
49 else { output <<
"\tStaticPrintVisitor: "; }
50 output <<
"( " << simplifiedDemangledType<T>() <<
" ) " << name <<
" --> " << _in <<
"\n";
53 template <typename T, typename std::enable_if<std::is_class<T>::value,
bool>::type =
true>
55 [[maybe_unused]]
const T& _in,
57 if ( !prefix.empty() ) { output <<
"\t" << prefix <<
": "; }
58 else { output <<
"\tStaticPrintVisitor: "; }
60 output <<
"( " << simplifiedDemangledType<T>() <<
" ) " << name <<
" --> " << _in
63 else { output <<
"( " << simplifiedDemangledType<T>() <<
" ) " << name <<
"\n"; }
70 if ( prefix.empty() ) { localPrefix =
"StaticPrintVisitor: "; }
71 else { localPrefix = prefix; }
73 output <<
"\t" << localPrefix <<
"( " << simplifiedDemangledType( p ) <<
" ) " << name
74 <<
" --> visiting recursively\n";
78 output <<
"\t" << localPrefix <<
"( " << simplifiedDemangledType( p ) <<
" ) " << name
79 <<
" --> end recursive visit\n";
85TEST_CASE(
"Engine/Data/RenderParameters",
"[unittests][Engine][Engine/Data][RenderParameters]" ) {
87 using namespace VariableSetEnumManagement;
89 SECTION(
"Parameter storage" ) {
91 REQUIRE( !( p1.existsVariableType<
int>().has_value() ) );
92 REQUIRE( !( p1.existsVariableType<
bool>().has_value() ) );
93 REQUIRE( !( p1.existsVariableType<uint>().has_value() ) );
94 REQUIRE( !( p1.existsVariableType<Scalar>().has_value() ) );
98 REQUIRE( !( p1.existsVariableType<Vector2>().has_value() ) );
99 REQUIRE( !( p1.existsVariableType<Vector3>().has_value() ) );
100 REQUIRE( !( p1.existsVariableType<Vector4>().has_value() ) );
101 REQUIRE( !( p1.existsVariableType<
Color>().has_value() ) );
102 REQUIRE( !( p1.existsVariableType<Matrix2>().has_value() ) );
103 REQUIRE( !( p1.existsVariableType<Matrix3>().has_value() ) );
104 REQUIRE( !( p1.existsVariableType<Matrix4>().has_value() ) );
105 REQUIRE( !( p1.existsVariableType<RP::TextureInfo>().has_value() ) );
113 Vector2 vec2 { 0_ra, 1_ra };
114 Vector3 vec3 { 0_ra, 1_ra, 2_ra };
115 Vector4 vec4 { 0_ra, 1_ra, 2_ra, 4_ra };
116 Matrix2 mat2 = Matrix2::Identity();
117 Matrix3 mat3 = Matrix3::Identity();
118 Matrix4 mat4 = Matrix4::Identity();
119 Color color = Color::White();
120 Texture tex1 { {
"texture1" } };
122 p1.setTexture(
"TextureParameter", &tex1, 1 );
123 p1.setVariable(
"IntParameter", i );
124 p1.setVariable(
"BoolParameter", b );
125 p1.setVariable(
"UIntParameter", ui );
126 p1.setVariable(
"ScalarParameter", s );
127 p1.setVariable(
"IntsParameter", is );
128 p1.setVariable(
"UIntsParameter", uis );
129 p1.setVariable(
"ScalarsParameter", ss );
130 p1.setVariable(
"Vec2Parameter", vec2 );
131 p1.setVariable(
"Vec3Parameter", vec3 );
132 p1.setVariable(
"Vec4Parameter", vec4 );
133 p1.setVariable(
"ColorParameter", color );
134 p1.setVariable(
"Mat2Parameter", mat2 );
135 p1.setVariable(
"Mat3Parameter", mat3 );
136 p1.setVariable(
"Mat4Parameter", mat4 );
138 REQUIRE( p1.getAllVariables<
int>().size() == 1 );
139 REQUIRE( p1.getAllVariables<
bool>().size() == 1 );
140 REQUIRE( p1.getAllVariables<uint>().size() == 1 );
141 REQUIRE( p1.getAllVariables<Scalar>().size() == 1 );
145 REQUIRE( p1.getAllVariables<Vector2>().size() == 1 );
146 REQUIRE( p1.getAllVariables<Vector3>().size() == 1 );
147 REQUIRE( p1.getAllVariables<Vector4>().size() == 1 );
148 REQUIRE( p1.getAllVariables<
Color>().size() == 1 );
149 REQUIRE( p1.getAllVariables<Matrix2>().size() == 1 );
150 REQUIRE( p1.getAllVariables<Matrix3>().size() == 1 );
151 REQUIRE( p1.getAllVariables<Matrix4>().size() == 1 );
152 REQUIRE( p1.getAllVariables<RP::TextureInfo>().size() == 1 );
154 REQUIRE( p1.getAllVariables<
int>().at(
"IntParameter" ) == i );
155 REQUIRE( p1.getAllVariables<
bool>().at(
"BoolParameter" ) == b );
156 REQUIRE( p1.getAllVariables<uint>().at(
"UIntParameter" ) == ui );
157 REQUIRE( p1.getAllVariables<Scalar>().at(
"ScalarParameter" ) == s );
161 REQUIRE( p1.getAllVariables<Vector2>().at(
"Vec2Parameter" ) == vec2 );
162 REQUIRE( p1.getAllVariables<Vector3>().at(
"Vec3Parameter" ) == vec3 );
163 REQUIRE( p1.getAllVariables<Vector4>().at(
"Vec4Parameter" ) == vec4 );
164 REQUIRE( p1.getAllVariables<
Color>().at(
"ColorParameter" ) == color );
165 REQUIRE( p1.getAllVariables<Matrix2>().at(
"Mat2Parameter" ) == mat2 );
166 REQUIRE( p1.getAllVariables<Matrix3>().at(
"Mat3Parameter" ) == mat3 );
167 REQUIRE( p1.getAllVariables<Matrix4>().at(
"Mat4Parameter" ) == mat4 );
168 REQUIRE( p1.getAllVariables<RP::TextureInfo>().at(
"TextureParameter" ).first == &tex1 );
169 REQUIRE( p1.getAllVariables<RP::TextureInfo>().at(
"TextureParameter" ).second == 1 );
171 StaticPrintVisitor vstr;
172 p1.visit( vstr,
"p1 parameter set" );
177 p2.setVariable(
"IntParameter", i + 1 );
178 p2.setVariable(
"BoolParameter", !b );
179 p2.setVariable(
"UIntParameter", ui + 1 );
180 p2.setVariable(
"ScalarParameter", s + 1_ra );
182 p2.setVariable(
"IntsParameter", is );
184 p2.setVariable(
"UIntsParameter", uis );
185 ss.push_back( 0_ra );
186 p2.setVariable(
"ScalarsParameter", ss );
187 p2.setVariable(
"Vec2Parameter", Vector2 { vec2 + Vector2 { 1_ra, 1_ra } } );
188 p2.setVariable(
"Vec3Parameter", Vector3 { vec3 + Vector3 { 1_ra, 1_ra, 1_ra } } );
189 p2.setVariable(
"Vec4Parameter", Vector4 { vec4 + Vector4 { 1_ra, 1_ra, 1_ra, 1_ra } } );
190 p2.setVariable(
"ColorParameter", Color::Red() );
191 Texture tex2 { {
"texture2" } };
192 p2.setTexture(
"TextureParameter", &tex2, 2 );
193 p2.setVariable(
"Foo", 42 );
196 p1.setVariable(
"Bar", 43 );
199 kept.mergeKeepVariables( p2 );
202 REQUIRE( kept.getAllVariables<
int>().at(
"IntParameter" ) ==
203 p1.getAllVariables<
int>().at(
"IntParameter" ) );
204 REQUIRE( kept.getAllVariables<
bool>().at(
"BoolParameter" ) ==
205 p1.getAllVariables<
bool>().at(
"BoolParameter" ) );
206 REQUIRE( kept.getAllVariables<uint>().at(
"UIntParameter" ) ==
207 p1.getAllVariables<uint>().at(
"UIntParameter" ) );
208 REQUIRE( kept.getAllVariables<Scalar>().at(
"ScalarParameter" ) ==
209 p1.getAllVariables<Scalar>().at(
"ScalarParameter" ) );
216 REQUIRE( kept.getAllVariables<Vector2>().at(
"Vec2Parameter" ) ==
217 p1.getAllVariables<Vector2>().at(
"Vec2Parameter" ) );
218 REQUIRE( kept.getAllVariables<Vector3>().at(
"Vec3Parameter" ) ==
219 p1.getAllVariables<Vector3>().at(
"Vec3Parameter" ) );
220 REQUIRE( kept.getAllVariables<Vector4>().at(
"Vec4Parameter" ) ==
221 p1.getAllVariables<Vector4>().at(
"Vec4Parameter" ) );
222 REQUIRE( kept.getAllVariables<
Color>().at(
"ColorParameter" ) ==
223 p1.getAllVariables<
Color>().at(
"ColorParameter" ) );
224 REQUIRE( kept.getAllVariables<RP::TextureInfo>().at(
"TextureParameter" ) ==
225 p1.getAllVariables<RP::TextureInfo>().at(
"TextureParameter" ) );
227 REQUIRE( kept.getAllVariables<
int>().at(
"Foo" ) == p2.getAllVariables<
int>().at(
"Foo" ) );
230 REQUIRE( kept.getAllVariables<
int>().at(
"Bar" ) == p1.getAllVariables<
int>().at(
"Bar" ) );
233 replaced.mergeReplaceVariables( p2 );
235 REQUIRE( replaced.getAllVariables<
int>().at(
"IntParameter" ) ==
236 p2.getAllVariables<
int>().at(
"IntParameter" ) );
237 REQUIRE( replaced.getAllVariables<
bool>().at(
"BoolParameter" ) ==
238 p2.getAllVariables<
bool>().at(
"BoolParameter" ) );
239 REQUIRE( replaced.getAllVariables<uint>().at(
"UIntParameter" ) ==
240 p2.getAllVariables<uint>().at(
"UIntParameter" ) );
241 REQUIRE( replaced.getAllVariables<Scalar>().at(
"ScalarParameter" ) ==
242 p2.getAllVariables<Scalar>().at(
"ScalarParameter" ) );
249 REQUIRE( replaced.getAllVariables<Vector2>().at(
"Vec2Parameter" ) ==
250 p2.getAllVariables<Vector2>().at(
"Vec2Parameter" ) );
251 REQUIRE( replaced.getAllVariables<Vector3>().at(
"Vec3Parameter" ) ==
252 p2.getAllVariables<Vector3>().at(
"Vec3Parameter" ) );
253 REQUIRE( replaced.getAllVariables<Vector4>().at(
"Vec4Parameter" ) ==
254 p2.getAllVariables<Vector4>().at(
"Vec4Parameter" ) );
255 REQUIRE( replaced.getAllVariables<
Color>().at(
"ColorParameter" ) ==
256 p2.getAllVariables<
Color>().at(
"ColorParameter" ) );
257 REQUIRE( replaced.getAllVariables<
int>().at(
"Foo" ) ==
258 p2.getAllVariables<
int>().at(
"Foo" ) );
259 REQUIRE( replaced.getAllVariables<RP::TextureInfo>().at(
"TextureParameter" ) ==
260 p2.getAllVariables<RP::TextureInfo>().at(
"TextureParameter" ) );
262 REQUIRE( replaced.getAllVariables<
int>().at(
"Bar" ) ==
263 p1.getAllVariables<
int>().at(
"Bar" ) );
265 auto removed = replaced.deleteVariable<
int>(
"Bar" );
266 REQUIRE( removed ==
true );
267 auto found = replaced.existsVariable<
int>(
"Bar" );
268 REQUIRE( found.has_value() ==
false );
271 SECTION(
"Enum parameter" ) {
274 enum Values :
unsigned int { VALUE_0 = 10, VALUE_1 = 20, VALUE_2 = 30 };
275 using ValuesType =
typename std::underlying_type_t<Values>;
277 enum Unregistered :
int { LOW = -1, MIDDDLE = 0, HIGH = 1 };
278 using UnregisteredType =
typename std::underlying_type_t<Unregistered>;
282 { Values::VALUE_0,
"VALUE_0" },
283 { Values::VALUE_1,
"VALUE_1" },
284 { Values::VALUE_2,
"VALUE_2" } } );
287 REQUIRE( !getEnumConverter<ValuesType>( params,
"enum.semantic" ) );
288 addEnumConverter( params,
"enum.semantic", valuesEnumConverter );
289 REQUIRE( getEnumConverter<ValuesType>( params,
"enum.semantic" ) );
290 REQUIRE( !getEnumConverter<ValuesType>( params,
"enum.unknown" ) );
291 REQUIRE( !getEnumConverter<UnregisteredType>( params,
"enum.unknown" ) );
295 REQUIRE( getEnumString( params,
"enum.semantic", Values::VALUE_0 ) ==
"VALUE_0" );
296 REQUIRE( getEnumString( params,
"enum.unknown", Unregistered::LOW ) ==
"" );
299 setEnumVariable( params,
"enum.semantic", Values::VALUE_0 );
302 auto& v = getEnumVariable<Values>( params,
"enum.semantic" );
304 REQUIRE( v == Values::VALUE_0 );
308 REQUIRE( getEnumString( params,
"enum.semantic", v ) ==
"VALUE_0" );
311 setEnumVariable( params,
"enum.semantic",
"VALUE_2" );
312 REQUIRE( v == Values::VALUE_2 );
315 auto& vv = params.getVariable<ValuesType>(
"enum.semantic" );
317 REQUIRE( vv == Values::VALUE_2 );
318 params.setVariable(
"enum.semantic", ValuesType { Values::VALUE_0 } );
320 REQUIRE( vv == Values::VALUE_0 );
323 setEnumVariable( params,
"enum.unknown", Unregistered::LOW );
324 auto u = getEnumVariable<Unregistered>( params,
"enum.unknown" );
325 REQUIRE( u == Unregistered::LOW );
326 REQUIRE( getEnumString( params,
"enum.unknown", u ) ==
"" );
329 setEnumVariable( params,
"enum.unknown",
"Unregistered::HIGH" );
330 u = getEnumVariable<Unregistered>( params,
"enum.unknown" );
333 auto uu = params.getVariable<UnregisteredType>(
"enum.unknown" );
334 REQUIRE( uu == Unregistered::LOW );
337 SECTION(
"Parameter visit" ) {
339 enum Values :
unsigned int { VALUE_0 = 10, VALUE_1 = 20, VALUE_2 = 30 };
343 { Values::VALUE_1,
"VALUE_1" },
344 { Values::VALUE_2,
"VALUE_2" } } );
346 addEnumConverter( paramsToVisit,
"enum.semantic", valuesEnumConverter );
347 setEnumVariable( paramsToVisit,
"enum.semantic",
"VALUE_0" );
348 paramsToVisit.setVariable(
"int.simple",
int( 1 ) );
350 PrintThemAllVisitor ptm;
351 ptm.allowVisit<ValuesType>();
352 ptm.allowVisit<
int>();
353 std::cout <<
"Visiting with custom dynamic visitor:\n";
354 paramsToVisit.visit( ptm );
361 expected.
insert(
"\tPrintThemAllVisitor: ( int ) int.simple --> 1" );
362 expected.
insert(
"\tPrintThemAllVisitor: ( unsigned int ) enum.semantic --> 10" );
363 REQUIRE( outputSet == expected );
365 StaticPrintVisitor vstr;
366 std::cout <<
"Visiting with custom static visitor:\n";
367 paramsToVisit.visit( vstr );
371 std::cout <<
"Visiting with custom static visitor and hierarchical parameters:\n";
373 subParams.setVariable(
"sub.int", 3 );
374 subParams.setVariable(
"sub.string",
std::string {
"SubString" } );
375 addEnumConverter( subParams,
"enum.semantic", valuesEnumConverter );
376 setEnumVariable( subParams,
"enum.semantic",
"VALUE_1" );
377 paramsToVisit.setVariable(
"SubParameter", subParams );
378 paramsToVisit.visit( vstr,
"Visiting with subparameters" );
387 "\t\tVisiting with subparameters: ( basic_string<char, char_traits<char>, "
388 "allocator<char>> ) sub.string --> SubString" );
389 expected.
insert(
"\t\tVisiting with subparameters: ( int ) sub.int --> 3" );
391 "\t\tVisiting with subparameters: ( unsigned int ) enum.semantic --> 20" );
392 expected.
insert(
"\tVisiting with subparameters( Ra::Engine::Data::RenderParameters ) "
393 "SubParameter --> end recursive visit" );
394 expected.
insert(
"\tVisiting with subparameters( Ra::Engine::Data::RenderParameters ) "
395 "SubParameter --> visiting recursively" );
396 expected.
insert(
"\tVisiting with subparameters: ( int ) int.simple --> 1" );
398 "\tVisiting with subparameters: ( unsigned int ) enum.semantic --> 10" );
401 for (
const auto& s : outputSet )
404 for (
const auto& s : expected )
408 REQUIRE( outputSet == expected );
Base class for visitors with configurable per-type callbacks. Visiting will be prepared at running ti...
bool addOperator(F &&f)
Add a visiting operator.
This class manage the bijective association between string and integral representation of an enumerat...
void visit(F &&visitor) const
Visit the container using a user defined visitor.
Management of shader parameters with automatic binding of a named parameter to the corresponding glsl...
Represent a Texture of the engine.
This namespace contains everything "low level", related to data, datastuctures, and computation.
(GPU) Data representation, along with manager