mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-05-03 10:04:54 +00:00
316 lines
8.6 KiB
C++
316 lines
8.6 KiB
C++
//
|
|
// Copyright Contributors to the MaterialX Project
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
#ifndef MATERIALX_VALUE_H
|
|
#define MATERIALX_VALUE_H
|
|
|
|
/// @file
|
|
/// Generic value classes
|
|
|
|
#include <MaterialXCore/Exception.h>
|
|
|
|
#include <MaterialXCore/Types.h>
|
|
#include <MaterialXCore/Util.h>
|
|
|
|
MATERIALX_NAMESPACE_BEGIN
|
|
|
|
/// A vector of integers.
|
|
using IntVec = vector<int>;
|
|
/// A vector of booleans.
|
|
using BoolVec = vector<bool>;
|
|
/// A vector of floats.
|
|
using FloatVec = vector<float>;
|
|
|
|
class Value;
|
|
class AggregateValue;
|
|
|
|
/// A shared pointer to a Value
|
|
using ValuePtr = shared_ptr<Value>;
|
|
/// A shared pointer to a const Value
|
|
using ConstValuePtr = shared_ptr<const Value>;
|
|
|
|
/// A shared pointer to an Aggregate Value
|
|
using AggregateValuePtr = shared_ptr<AggregateValue>;
|
|
/// A shared pointer to a const Aggregate Value
|
|
using ConstAggregateValuePtr = shared_ptr<const AggregateValue>;
|
|
|
|
class TypeDef;
|
|
using ConstTypeDefPtr = shared_ptr<const TypeDef>;
|
|
|
|
template <class T> class TypedValue;
|
|
|
|
/// A generic, discriminated value, whose type may be queried dynamically.
|
|
class MX_CORE_API Value
|
|
{
|
|
public:
|
|
/// Float formats to use when converting values to strings.
|
|
enum FloatFormat
|
|
{
|
|
FloatFormatDefault = 0,
|
|
FloatFormatFixed = 1,
|
|
FloatFormatScientific = 2
|
|
};
|
|
|
|
public:
|
|
Value()
|
|
{
|
|
}
|
|
virtual ~Value() { }
|
|
|
|
/// Create a new value from an object of any valid MaterialX type.
|
|
template <class T> static ValuePtr createValue(const T& data)
|
|
{
|
|
return std::make_shared<TypedValue<T>>(data);
|
|
}
|
|
|
|
// Create a new value from a C-style string.
|
|
static ValuePtr createValue(const char* data)
|
|
{
|
|
return createValue(data ? string(data) : EMPTY_STRING);
|
|
}
|
|
|
|
/// Create a new value instance from value and type strings.
|
|
/// @return A shared pointer to a typed value, or an empty shared pointer
|
|
/// if the conversion to the given data type cannot be performed.
|
|
static ValuePtr createValueFromStrings(const string& value, const string& type, ConstTypeDefPtr typeDef = nullptr);
|
|
|
|
/// Create a deep copy of the value.
|
|
virtual ValuePtr copy() const = 0;
|
|
|
|
/// @name Data Accessors
|
|
/// @{
|
|
|
|
/// Return true if this value is of the given type.
|
|
template <class T> bool isA() const;
|
|
|
|
/// Return our underlying data as an object of the given type.
|
|
/// If the given type doesn't match our own data type, then an
|
|
/// exception is thrown.
|
|
template <class T> const T& asA() const;
|
|
|
|
/// Return the type string for this value.
|
|
virtual const string& getTypeString() const = 0;
|
|
|
|
/// Return the value string for this value.
|
|
virtual string getValueString() const = 0;
|
|
|
|
/// Set float formatting for converting values to strings.
|
|
/// Formats to use are FloatFormatFixed, FloatFormatScientific
|
|
/// or FloatFormatDefault to set default format.
|
|
static void setFloatFormat(FloatFormat format);
|
|
|
|
/// Set float precision for converting values to strings.
|
|
static void setFloatPrecision(int precision);
|
|
|
|
/// Return the current float format.
|
|
static FloatFormat getFloatFormat();
|
|
|
|
/// Return the current float precision.
|
|
static int getFloatPrecision();
|
|
|
|
// Returns true if value data matches.
|
|
virtual bool isEqual(ConstValuePtr other) const = 0;
|
|
|
|
protected:
|
|
template <class T> friend class ValueRegistry;
|
|
|
|
using CreatorFunction = ValuePtr (*)(const string&);
|
|
using CreatorMap = std::unordered_map<string, CreatorFunction>;
|
|
|
|
private:
|
|
static CreatorMap _creatorMap;
|
|
};
|
|
|
|
/// The class template for typed subclasses of Value
|
|
template <class T> class TypedValue : public Value
|
|
{
|
|
public:
|
|
MX_CORE_API TypedValue() :
|
|
_data{}
|
|
{
|
|
}
|
|
MX_CORE_API explicit TypedValue(const T& value) :
|
|
_data(value)
|
|
{
|
|
}
|
|
MX_CORE_API virtual ~TypedValue() { }
|
|
|
|
/// Create a deep copy of the value.
|
|
MX_CORE_API ValuePtr copy() const override
|
|
{
|
|
return Value::createValue<T>(_data);
|
|
}
|
|
|
|
/// Set stored data object.
|
|
MX_CORE_API void setData(const T& value)
|
|
{
|
|
_data = value;
|
|
}
|
|
|
|
/// Set stored data object.
|
|
MX_CORE_API void setData(const TypedValue<T>& value)
|
|
{
|
|
_data = value._data;
|
|
}
|
|
|
|
/// Return stored data object.
|
|
MX_CORE_API const T& getData() const
|
|
{
|
|
return _data;
|
|
}
|
|
|
|
/// Return type string.
|
|
MX_CORE_API const string& getTypeString() const override;
|
|
|
|
/// Return value string.
|
|
MX_CORE_API string getValueString() const override;
|
|
|
|
// Returns true if value data matches.
|
|
MX_CORE_API bool isEqual(ConstValuePtr other) const override
|
|
{
|
|
if (!other || !other->isA<T>())
|
|
{
|
|
return false;
|
|
}
|
|
return _data == other->asA<T>();
|
|
}
|
|
|
|
//
|
|
// Static helper methods
|
|
//
|
|
|
|
/// Create a new value of this type from a value string.
|
|
/// @return A shared pointer to a typed value, or an empty shared pointer
|
|
/// if the conversion to the given data type cannot be performed.
|
|
MX_CORE_API static ValuePtr createFromString(const string& value);
|
|
|
|
public:
|
|
MX_CORE_API static const string TYPE;
|
|
|
|
private:
|
|
T _data;
|
|
};
|
|
|
|
/// A subclass for aggregate values with multiple members
|
|
class MX_CORE_API AggregateValue : public Value
|
|
{
|
|
public:
|
|
AggregateValue(const string& typeName) :
|
|
_typeName(typeName)
|
|
{
|
|
}
|
|
virtual ~AggregateValue() { }
|
|
|
|
/// Create a deep copy of the value.
|
|
ValuePtr copy() const override
|
|
{
|
|
auto result = createAggregateValue(_typeName);
|
|
for (const auto& val : _data)
|
|
{
|
|
result->appendValue(val->copy());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// Append a member value to the aggregate.
|
|
void appendValue(ConstValuePtr valuePtr)
|
|
{
|
|
_data.emplace_back(valuePtr);
|
|
}
|
|
|
|
const vector<ConstValuePtr>& getMembers() const
|
|
{
|
|
return _data;
|
|
}
|
|
|
|
/// Query an indexed member value from the aggregate.
|
|
ConstValuePtr getMemberValue(size_t index) const
|
|
{
|
|
return _data[index];
|
|
}
|
|
|
|
/// Return type string.
|
|
const string& getTypeString() const override { return _typeName; }
|
|
|
|
/// Return value string.
|
|
string getValueString() const override;
|
|
|
|
// Returns true if value data matches.
|
|
bool isEqual(ConstValuePtr other) const override;
|
|
|
|
//
|
|
// Static helper methods
|
|
//
|
|
|
|
/// Create a new value from an object of any valid MaterialX type.
|
|
static AggregateValuePtr createAggregateValue(const string& typeName)
|
|
{
|
|
return std::make_shared<AggregateValue>(typeName);
|
|
}
|
|
|
|
static AggregateValuePtr createAggregateValueFromString(const string& value, const string& type, ConstTypeDefPtr typeDefPtr);
|
|
|
|
private:
|
|
const string _typeName;
|
|
|
|
vector<ConstValuePtr> _data;
|
|
};
|
|
|
|
/// @class ScopedFloatFormatting
|
|
/// An RAII class for controlling the float formatting of values.
|
|
class MX_CORE_API ScopedFloatFormatting
|
|
{
|
|
public:
|
|
explicit ScopedFloatFormatting(Value::FloatFormat format, int precision = -1);
|
|
~ScopedFloatFormatting();
|
|
|
|
private:
|
|
Value::FloatFormat _format;
|
|
int _precision;
|
|
};
|
|
|
|
/// Return the type string associated with the given data type.
|
|
template <class T> MX_CORE_API const string& getTypeString();
|
|
|
|
/// Convert the given data value to a value string.
|
|
template <class T> MX_CORE_API string toValueString(const T& data);
|
|
|
|
/// Convert the given value string to a data value of the given type.
|
|
/// @throws ExceptionTypeError if the conversion cannot be performed.
|
|
template <class T> MX_CORE_API T fromValueString(const string& value);
|
|
|
|
/// Tokenize the string representation of a struct value i.e, "{1;2;3}" into a
|
|
/// vector of substrings.
|
|
/// Note: "{1;2;{3;4;5}}" will be split in to ["1", "2", "{3;4;5}"]
|
|
MX_CORE_API StringVec parseStructValueString(const string& value);
|
|
|
|
/// Forward declaration of specific template instantiations.
|
|
/// Base types
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<int>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<bool>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<float>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Color3>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Color4>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Vector2>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Vector3>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Vector4>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Matrix33>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<Matrix44>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<string>);
|
|
|
|
/// Array types
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<IntVec>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<BoolVec>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<FloatVec>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<StringVec>);
|
|
|
|
/// Alias types
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<long>);
|
|
MX_CORE_EXTERN_TEMPLATE(TypedValue<double>);
|
|
|
|
MATERIALX_NAMESPACE_END
|
|
|
|
#endif
|