// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Object.h"
#include "GraphNode.h"
///
/// Shader source generator value container. Caches the value type and the value variable name (shader local, global parameter or constant value). Supports value type casting and component swizzle.
///
struct ShaderGraphValue : Object
{
private:
static const Char* _subs[];
public:
///
/// The value type.
///
VariantType::Types Type;
///
/// The shader value.
///
String Value;
public:
///
/// Zero value (as float).
///
static const ShaderGraphValue Zero;
///
/// Half value (as float).
///
static const ShaderGraphValue Half;
///
/// One value (as float).
///
static const ShaderGraphValue One;
///
/// True value (as bool).
///
static const ShaderGraphValue True;
///
/// False value (as bool).
///
static const ShaderGraphValue False;
public:
///
/// Initializes a new instance of the struct.
///
ShaderGraphValue()
: Type(VariantType::Types::Null)
{
}
///
/// Initializes a new instance of the struct.
///
/// The type.
/// The value.
ShaderGraphValue(VariantType::Types type, const Char* value)
: Type(type)
, Value(value)
{
}
///
/// Initializes a new instance of the struct.
///
/// The type.
/// The value.
ShaderGraphValue(VariantType::Types type, const String&& value)
: Type(type)
, Value(MoveTemp(value))
{
}
///
/// Initializes a new instance of the struct.
///
/// The type.
/// The value.
ShaderGraphValue(VariantType::Types type, const String& value)
: Type(type)
, Value(value)
{
}
///
/// Initializes a new instance of the struct.
///
/// The value.
explicit ShaderGraphValue(const bool value)
: Type(VariantType::Types::Bool)
, Value(value ? TEXT("true") : TEXT("false"))
{
}
///
/// Initializes a new instance of the struct.
///
/// The value.
explicit ShaderGraphValue(const float value)
: Type(VariantType::Types::Float)
, Value(StringUtils::ToString(value))
{
}
///
/// Initializes a new instance of the struct.
///
/// The value.
explicit ShaderGraphValue(const double value)
: Type(VariantType::Types::Float)
, Value(StringUtils::ToString(value))
{
}
///
/// Initializes a new instance of the struct.
///
/// The value.
explicit ShaderGraphValue(const int32 value)
: Type(VariantType::Types::Int)
, Value(StringUtils::ToString(value))
{
}
///
/// Initializes a new instance of the struct.
///
/// The value.
explicit ShaderGraphValue(const Variant& v);
public:
///
/// Returns true if value is valid.
///
FORCE_INLINE bool IsValid() const
{
return Type != VariantType::Types::Null;
}
///
/// Returns true if value is invalid.
///
FORCE_INLINE bool IsInvalid() const
{
return Type == VariantType::Types::Null;
}
///
/// Checks if value contains static part with zero.
///
bool IsZero() const;
///
/// Checks if value contains static part with one.
///
bool IsOne() const;
///
/// Checks if value is a compile-time constant literal (eg. int, bool or float).
///
bool IsLiteral() const;
///
/// Clears this instance.
///
void Clear()
{
Type = VariantType::Types::Null;
Value.Clear();
}
public:
///
/// Formats thw value.
///
/// The format text.
/// The value.
/// The formatted value.
static String Format(const Char* format, const ShaderGraphValue& v1)
{
return String::Format(format, v1.Value);
}
///
/// Formats thw value.
///
/// The format text.
/// The first value.
/// The second value.
/// The formatted value.
static String Format(const Char* format, const ShaderGraphValue& v1, const ShaderGraphValue& v2)
{
return String::Format(format, v1.Value, v2.Value);
}
///
/// Formats thw value.
///
/// The format text.
/// The first value.
/// The second value.
/// The third value.
/// The formatted value.
static String Format(const Char* format, const ShaderGraphValue& v1, const ShaderGraphValue& v2, const ShaderGraphValue& v3)
{
return String::Format(format, v1.Value, v2.Value, v3.Value);
}
///
/// Formats thw value.
///
/// The format text.
/// The first value.
/// The second value.
/// The third value.
/// The fourth value.
/// The formatted value.
static String Format(const Char* format, const ShaderGraphValue& v1, const ShaderGraphValue& v2, const ShaderGraphValue& v3, const ShaderGraphValue& v4)
{
return String::Format(format, v1.Value, v2.Value, v3.Value, v4.Value);
}
public:
///
/// Initializes the shader variable for given connection type Zero.
///
/// The graph connection type.
/// Initial value for given type.
static ShaderGraphValue InitForZero(VariantType::Types type);
///
/// Initializes the shader variable for given connection type Half.
///
/// The graph connection type.
/// Initial value for given type.
static ShaderGraphValue InitForHalf(VariantType::Types type);
///
/// Initializes the shader variable for given connection type One.
///
/// The graph connection type.
/// Initial value for given type.
static ShaderGraphValue InitForOne(VariantType::Types type);
///
/// Create float2 from X and Y values.
///
/// The x.
/// The y.
/// float2
static ShaderGraphValue Float2(const ShaderGraphValue& x, const ShaderGraphValue& y)
{
return ShaderGraphValue(
VariantType::Types::Float2,
String::Format(TEXT("float2({0}, {1})"),
Cast(x, VariantType::Types::Float).Value,
Cast(y, VariantType::Types::Float).Value));
}
///
/// Create float3 from X, Y and Z values.
///
/// The x.
/// The y.
/// The z.
/// float3
static ShaderGraphValue Float3(const ShaderGraphValue& x, const ShaderGraphValue& y, const ShaderGraphValue& z)
{
return ShaderGraphValue(
VariantType::Types::Float3,
String::Format(TEXT("float3({0}, {1}, {2})"),
Cast(x, VariantType::Types::Float).Value,
Cast(y, VariantType::Types::Float).Value,
Cast(z, VariantType::Types::Float).Value));
}
///
/// Create float4 from X, Y, Z and W values.
///
/// The X.
/// The Y.
/// The Z.
/// The W.
/// float4
static ShaderGraphValue Float4(const ShaderGraphValue& x, const ShaderGraphValue& y, const ShaderGraphValue& z, const ShaderGraphValue& w)
{
return ShaderGraphValue(
VariantType::Types::Float4,
String::Format(TEXT("float4({0}, {1}, {2}, {3})"),
Cast(x, VariantType::Types::Float).Value,
Cast(y, VariantType::Types::Float).Value,
Cast(z, VariantType::Types::Float).Value,
Cast(w, VariantType::Types::Float).Value));
}
public:
///
/// Gets the X component of the value. Valid only for single or vector types.
///
/// The X component.
ShaderGraphValue GetX() const
{
return ShaderGraphValue(VariantType::Types::Float, Value + _subs[0]);
}
///
/// Gets the Y component of the value. Valid only for vector types.
///
/// The Y component.
ShaderGraphValue GetY() const;
///
/// Gets the Z component of the value. Valid only for vector types.
///
/// The Z component.
ShaderGraphValue GetZ() const;
///
/// Gets the W component of the value. Valid only for vector types.
///
/// The W component.
ShaderGraphValue GetW() const;
public:
///
/// Casts the value to the bool type.
///
/// Bool
ShaderGraphValue AsBool() const
{
return Cast(*this, VariantType::Types::Bool);
}
///
/// Casts the value to the integer type.
///
/// Integer
ShaderGraphValue AsInt() const
{
return Cast(*this, VariantType::Types::Int);
}
///
/// Casts the value to the unsigned integer type.
///
/// UnsignedInteger
ShaderGraphValue AsUint() const
{
return Cast(*this, VariantType::Types::Uint);
}
///
/// Casts the value to the float type.
///
/// Float
ShaderGraphValue AsFloat() const
{
return Cast(*this, VariantType::Types::Float);
}
///
/// Casts the value to the Float2 type.
///
/// Float2
ShaderGraphValue AsFloat2() const
{
return Cast(*this, VariantType::Types::Float2);
}
///
/// Casts the value to the Float3 type.
///
/// Float3
ShaderGraphValue AsFloat3() const
{
return Cast(*this, VariantType::Types::Float3);
}
///
/// Casts the value to the Float4 type.
///
/// Float4
ShaderGraphValue AsFloat4() const
{
return Cast(*this, VariantType::Types::Float4);
}
///
/// Casts the value from its type to the another type.
///
/// The result type.
/// The result value.
ShaderGraphValue Cast(const VariantType::Types to) const
{
return Cast(*this, to);
}
///
/// Casts the value from its type to the another type.
///
/// The value to cast.
/// The result type.
/// The result value.
static ShaderGraphValue Cast(const ShaderGraphValue& v, VariantType::Types to);
public:
// [Object]
String ToString() const override
{
return Value;
}
};