From 7736312c2f361512ab841f852c1b18349abd6d3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Tue, 4 Aug 2020 01:33:31 +0200 Subject: [PATCH] ShaderNodes: Replace union by std::variant --- include/Nazara/Renderer/ShaderNodes.hpp | 23 +++++-------- include/Nazara/Renderer/ShaderNodes.inl | 42 ++---------------------- src/Nazara/Renderer/GlslWriter.cpp | 39 +++++++++------------- src/Nazara/Renderer/ShaderNodes.cpp | 19 ++++++++++- src/Nazara/Renderer/ShaderSerializer.cpp | 39 +++++++++++----------- 5 files changed, 66 insertions(+), 96 deletions(-) diff --git a/include/Nazara/Renderer/ShaderNodes.hpp b/include/Nazara/Renderer/ShaderNodes.hpp index 0c5049df9..0b6daec79 100644 --- a/include/Nazara/Renderer/ShaderNodes.hpp +++ b/include/Nazara/Renderer/ShaderNodes.hpp @@ -220,22 +220,17 @@ namespace Nz ShaderExpressionType GetExpressionType() const override; void Visit(ShaderVisitor& visitor) override; - BasicType exprType; + using Variant = std::variant< + bool, + float, + Vector2f, + Vector3f, + Vector4f + >; - union - { - bool bool1; - float vec1; - Vector2f vec2; - Vector3f vec3; - Vector4f vec4; - } values; + Variant value; - static inline std::shared_ptr Build(bool value); - static inline std::shared_ptr Build(float value); - static inline std::shared_ptr Build(const Vector2f& value); - static inline std::shared_ptr Build(const Vector3f& value); - static inline std::shared_ptr Build(const Vector4f& value); + template static std::shared_ptr Build(const T& value); }; struct NAZARA_RENDERER_API SwizzleOp : public Expression diff --git a/include/Nazara/Renderer/ShaderNodes.inl b/include/Nazara/Renderer/ShaderNodes.inl index 606487e0c..27d387bcd 100644 --- a/include/Nazara/Renderer/ShaderNodes.inl +++ b/include/Nazara/Renderer/ShaderNodes.inl @@ -239,47 +239,11 @@ namespace Nz::ShaderNodes { } - inline std::shared_ptr Constant::Build(bool value) + template + std::shared_ptr Nz::ShaderNodes::Constant::Build(const T& value) { auto node = std::make_shared(); - node->exprType = BasicType::Boolean; - node->values.bool1 = value; - - return node; - } - - inline std::shared_ptr Constant::Build(float value) - { - auto node = std::make_shared(); - node->exprType = BasicType::Float1; - node->values.vec1 = value; - - return node; - } - - inline std::shared_ptr Constant::Build(const Vector2f& value) - { - auto node = std::make_shared(); - node->exprType = BasicType::Float2; - node->values.vec2 = value; - - return node; - } - - inline std::shared_ptr Constant::Build(const Vector3f& value) - { - auto node = std::make_shared(); - node->exprType = BasicType::Float3; - node->values.vec3 = value; - - return node; - } - - inline std::shared_ptr Constant::Build(const Vector4f& value) - { - auto node = std::make_shared(); - node->exprType = BasicType::Float4; - node->values.vec4 = value; + node->value = value; return node; } diff --git a/src/Nazara/Renderer/GlslWriter.cpp b/src/Nazara/Renderer/GlslWriter.cpp index 3f2a4a4a3..fcb1847a7 100644 --- a/src/Nazara/Renderer/GlslWriter.cpp +++ b/src/Nazara/Renderer/GlslWriter.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -426,31 +427,23 @@ namespace Nz void GlslWriter::Visit(const ShaderNodes::Constant& node) { - switch (node.exprType) + std::visit([&](auto&& arg) { - case ShaderNodes::BasicType::Boolean: - Append((node.values.bool1) ? "true" : "false"); - break; + using T = std::decay_t; - case ShaderNodes::BasicType::Float1: - Append(std::to_string(node.values.vec1)); - break; - - case ShaderNodes::BasicType::Float2: - Append("vec2(" + std::to_string(node.values.vec2.x) + ", " + std::to_string(node.values.vec2.y) + ")"); - break; - - case ShaderNodes::BasicType::Float3: - Append("vec3(" + std::to_string(node.values.vec3.x) + ", " + std::to_string(node.values.vec3.y) + ", " + std::to_string(node.values.vec3.z) + ")"); - break; - - case ShaderNodes::BasicType::Float4: - Append("vec4(" + std::to_string(node.values.vec4.x) + ", " + std::to_string(node.values.vec4.y) + ", " + std::to_string(node.values.vec4.z) + ", " + std::to_string(node.values.vec4.w) + ")"); - break; - - default: - throw std::runtime_error("Unhandled expression type"); - } + if constexpr (std::is_same_v) + Append((arg) ? "true" : "false"); + else if constexpr (std::is_same_v) + Append(std::to_string(arg)); + else if constexpr (std::is_same_v) + Append("vec2(" + std::to_string(arg.x) + ", " + std::to_string(arg.y) + ")"); + else if constexpr (std::is_same_v) + Append("vec3(" + std::to_string(arg.x) + ", " + std::to_string(arg.y) + ", " + std::to_string(arg.z) + ")"); + else if constexpr (std::is_same_v) + Append("vec4(" + std::to_string(arg.x) + ", " + std::to_string(arg.y) + ", " + std::to_string(arg.z) + ", " + std::to_string(arg.w) + ")"); + else + static_assert(AlwaysFalse::value, "non-exhaustive visitor"); + }, node.value); } void GlslWriter::Visit(const ShaderNodes::DeclareVariable& node) diff --git a/src/Nazara/Renderer/ShaderNodes.cpp b/src/Nazara/Renderer/ShaderNodes.cpp index ddf5e09c7..da2157826 100644 --- a/src/Nazara/Renderer/ShaderNodes.cpp +++ b/src/Nazara/Renderer/ShaderNodes.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -150,7 +151,23 @@ namespace Nz::ShaderNodes ShaderExpressionType Constant::GetExpressionType() const { - return exprType; + return std::visit([&](auto&& arg) + { + using T = std::decay_t; + + if constexpr (std::is_same_v) + return ShaderNodes::BasicType::Boolean; + else if constexpr (std::is_same_v) + return ShaderNodes::BasicType::Float1; + else if constexpr (std::is_same_v) + return ShaderNodes::BasicType::Float2; + else if constexpr (std::is_same_v) + return ShaderNodes::BasicType::Float3; + else if constexpr (std::is_same_v) + return ShaderNodes::BasicType::Float4; + else + static_assert(AlwaysFalse::value, "non-exhaustive visitor"); + }, value); } void Constant::Visit(ShaderVisitor& visitor) diff --git a/src/Nazara/Renderer/ShaderSerializer.cpp b/src/Nazara/Renderer/ShaderSerializer.cpp index 7441162a0..2433bf070 100644 --- a/src/Nazara/Renderer/ShaderSerializer.cpp +++ b/src/Nazara/Renderer/ShaderSerializer.cpp @@ -178,29 +178,30 @@ namespace Nz void ShaderSerializerBase::Serialize(ShaderNodes::Constant& node) { - Enum(node.exprType); + UInt32 typeIndex; + if (IsWriting()) + typeIndex = UInt32(node.value.index()); - switch (node.exprType) + Value(typeIndex); + + // Waiting for template lambda in C++20 + auto SerializeValue = [&](auto dummyType) { - case ShaderNodes::BasicType::Boolean: - Value(node.values.bool1); - break; + using T = std::decay_t; - case ShaderNodes::BasicType::Float1: - Value(node.values.vec1); - break; + auto& value = (IsWriting()) ? std::get(node.value) : node.value.emplace(); + Value(value); + }; - case ShaderNodes::BasicType::Float2: - Value(node.values.vec2); - break; - - case ShaderNodes::BasicType::Float3: - Value(node.values.vec3); - break; - - case ShaderNodes::BasicType::Float4: - Value(node.values.vec4); - break; + static_assert(std::variant_size_v == 5); + switch (typeIndex) + { + case 0: SerializeValue(bool()); break; + case 1: SerializeValue(float()); break; + case 2: SerializeValue(Vector2f()); break; + case 3: SerializeValue(Vector3f()); break; + case 4: SerializeValue(Vector4f()); break; + default: throw std::runtime_error("unexpected data type"); } }