Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/MaterialX-1.38.10/source/MaterialXGenShader/Syntax.h
2025-05-18 13:04:45 +08:00

303 lines
12 KiB
C++

//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//
#ifndef MATERIALX_SYNTAX_H
#define MATERIALX_SYNTAX_H
/// @file
/// Base class for syntax handling for shader generators
#include <MaterialXGenShader/Export.h>
#include <MaterialXCore/Definition.h>
#include <MaterialXCore/Library.h>
#include <MaterialXCore/Value.h>
MATERIALX_NAMESPACE_BEGIN
class Syntax;
class TypeSyntax;
class TypeDesc;
class ShaderPort;
/// Shared pointer to a Syntax
using SyntaxPtr = shared_ptr<Syntax>;
/// Shared pointer to a constant Syntax
using ConstSyntaxPtr = shared_ptr<const Syntax>;
/// Shared pointer to a TypeSyntax
using TypeSyntaxPtr = shared_ptr<TypeSyntax>;
/// Map holding identifier names and a counter for
/// creating unique names from them.
using IdentifierMap = std::unordered_map<string, size_t>;
/// @class Syntax
/// Base class for syntax objects used by shader generators
/// to emit code with correct syntax for each language.
class MX_GENSHADER_API Syntax
{
public:
/// Punctuation types
enum Punctuation
{
PARENTHESES,
CURLY_BRACKETS,
SQUARE_BRACKETS,
DOUBLE_SQUARE_BRACKETS
};
public:
virtual ~Syntax() { }
/// Register syntax handling for a data type.
/// Required to be set for all supported data types.
void registerTypeSyntax(const TypeDesc* type, TypeSyntaxPtr syntax);
/// Register names that are reserved words not to be used by a code generator when naming
/// variables and functions. Keywords, types, built-in functions etc. should be
/// added to this set. Multiple calls will add to the internal set of names.
void registerReservedWords(const StringSet& names);
/// Register a set string replacements for disallowed tokens
/// for a code generator when naming variables and functions.
/// Multiple calls will add to the internal set of tokens.
void registerInvalidTokens(const StringMap& tokens);
/// Returns a set of names that are reserved words for this language syntax.
const StringSet& getReservedWords() const { return _reservedWords; }
/// Returns a mapping from disallowed tokens to replacement strings for this language syntax.
const StringMap& getInvalidTokens() const { return _invalidTokens; }
/// Returns the type syntax object for a named type.
/// Throws an exception if a type syntax is not defined for the given type.
const TypeSyntax& getTypeSyntax(const TypeDesc* type) const;
/// Returns an array of all registered type syntax objects
const vector<TypeSyntaxPtr>& getTypeSyntaxes() const { return _typeSyntaxes; }
/// Returns a type description given a type syntax. Throws an exception
/// if the type syntax has not been registered
const TypeDesc* getTypeDescription(const TypeSyntaxPtr& typeSyntax) const;
/// Returns the name syntax of the given type
const string& getTypeName(const TypeDesc* type) const;
/// Returns the type name in an output context
virtual string getOutputTypeName(const TypeDesc* type) const;
/// Returns a type alias for the given data type.
/// If not used returns an empty string.
const string& getTypeAlias(const TypeDesc* type) const;
/// Returns a custom type definition if needed for the given data type.
/// If not used returns an empty string.
const string& getTypeDefinition(const TypeDesc* type) const;
/// Returns the default value string for the given type
const string& getDefaultValue(const TypeDesc* type, bool uniform = false) const;
/// Returns the value string for a given type and value object
virtual string getValue(const TypeDesc* type, const Value& value, bool uniform = false) const;
/// Returns the value string for a given shader port object
virtual string getValue(const ShaderPort* port, bool uniform = false) const;
/// Get syntax for a swizzled variable
virtual string getSwizzledVariable(const string& srcName, const TypeDesc* srcType, const string& channels, const TypeDesc* dstType) const;
/// Get swizzled value
virtual ValuePtr getSwizzledValue(ValuePtr value, const TypeDesc* srcType, const string& channels, const TypeDesc* dstType) const;
/// Returns a type qualifier to be used when declaring types for input variables.
/// Default implementation returns empty string and derived syntax classes should
/// override this method.
virtual const string& getInputQualifier() const { return EMPTY_STRING; };
/// Returns a type qualifier to be used when declaring types for output variables.
/// Default implementation returns empty string and derived syntax classes should
/// override this method.
virtual const string& getOutputQualifier() const { return EMPTY_STRING; };
/// Get the qualifier used when declaring constant variables.
/// Derived classes must define this method.
virtual const string& getConstantQualifier() const = 0;
/// Get the qualifier used when declaring uniform variables.
/// Default implementation returns empty string and derived syntax classes should
/// override this method.
virtual const string& getUniformQualifier() const { return EMPTY_STRING; };
/// Return the characters used for a newline.
virtual const string& getNewline() const { return NEWLINE; };
/// Return the characters used for a single indentation level.
virtual const string& getIndentation() const { return INDENTATION; };
/// Return the characters used to begin/end a string definition.
virtual const string& getStringQuote() const { return STRING_QUOTE; };
/// Return the string pattern used for a file include statement.
virtual const string& getIncludeStatement() const { return INCLUDE_STATEMENT; };
/// Return the characters used for single line comment.
virtual const string& getSingleLineComment() const { return SINGLE_LINE_COMMENT; };
/// Return the characters used to begin a multi line comments block.
virtual const string& getBeginMultiLineComment() const { return BEGIN_MULTI_LINE_COMMENT; };
/// Return the characters used to end a multi line comments block.
virtual const string& getEndMultiLineComment() const { return END_MULTI_LINE_COMMENT; };
/// Return the file extension used for source code files in this language.
virtual const string& getSourceFileExtension() const = 0;
/// Return the array suffix to use for declaring an array type.
virtual string getArrayTypeSuffix(const TypeDesc*, const Value&) const { return EMPTY_STRING; };
/// Return the array suffix to use for declaring an array variable.
virtual string getArrayVariableSuffix(const TypeDesc* type, const Value& value) const;
/// Query if given type is suppored in the syntax.
/// By default all types are assumed to be supported.
virtual bool typeSupported(const TypeDesc* type) const;
/// Modify the given name string to remove any invalid characters or tokens.
virtual void makeValidName(string& name) const;
/// Make sure the given name is a unique identifier,
/// updating it if needed to make it unique.
virtual void makeIdentifier(string& name, IdentifierMap& identifiers) const;
/// Create a unique identifier for the given variable name and type.
/// The method is used for naming variables (inputs and outputs) in generated code.
/// Derived classes can override this method to have a custom naming strategy.
/// Default implementation adds a number suffix, or increases an existing number suffix,
/// on the name string if there is a name collision.
virtual string getVariableName(const string& name, const TypeDesc* type, IdentifierMap& identifiers) const;
/// Given an input specification attempt to remap this to an enumeration which is accepted by
/// the shader generator. The enumeration may be converted to a different type than the input.
/// @param value The value string to remap.
/// @param type The type of the value to remap,
/// @param enumNames Type enumeration names
/// @param result Enumeration type and value (returned).
/// @return Return true if the remapping was successful.
virtual bool remapEnumeration(const string& value, const TypeDesc* type, const string& enumNames,
std::pair<const TypeDesc*, ValuePtr>& result) const;
/// Constants with commonly used strings.
static const string NEWLINE;
static const string SEMICOLON;
static const string COMMA;
protected:
/// Protected constructor
Syntax();
vector<TypeSyntaxPtr> _typeSyntaxes;
std::unordered_map<const TypeDesc*, size_t> _typeSyntaxByType;
StringSet _reservedWords;
StringMap _invalidTokens;
static const string INDENTATION;
static const string STRING_QUOTE;
static const string INCLUDE_STATEMENT;
static const string SINGLE_LINE_COMMENT;
static const string BEGIN_MULTI_LINE_COMMENT;
static const string END_MULTI_LINE_COMMENT;
static const std::unordered_map<char, size_t> CHANNELS_MAPPING;
};
/// @class TypeSyntax
/// Base class for syntax handling of types.
class MX_GENSHADER_API TypeSyntax
{
public:
virtual ~TypeSyntax() { }
/// Returns the type name.
const string& getName() const { return _name; }
/// Returns a type alias if needed to define the type in the target language.
const string& getTypeAlias() const { return _typeAlias; }
/// Returns a type definition if needed to define the type in the target language.
const string& getTypeDefinition() const { return _typeDefinition; }
/// Returns the default value for this type.
const string& getDefaultValue(bool uniform) const { return uniform ? _uniformDefaultValue : _defaultValue; }
/// Returns the syntax for accessing type members if the type
/// can be swizzled.
const StringVec& getMembers() const { return _members; }
/// Returns a value formatted according to this type syntax.
/// The value is constructed from the given shader port object.
virtual string getValue(const ShaderPort* port, bool uniform) const;
/// Returns a value formatted according to this type syntax.
/// The value is constructed from the given value object.
virtual string getValue(const Value& value, bool uniform) const = 0;
/// Returns a value formatted according to this type syntax.
/// The value is constructed from the given list of value entries
/// with one entry for each member of the type.
virtual string getValue(const StringVec& values, bool uniform) const = 0;
protected:
/// Protected constructor
TypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias, const string& typeDefinition, const StringVec& members);
string _name; // type name
string _defaultValue; // default value syntax
string _uniformDefaultValue; // default value syntax when assigned to uniforms
string _typeAlias; // type alias if needed in source code
string _typeDefinition; // custom type definition if needed in source code
StringVec _members; // syntax for member access
static const StringVec EMPTY_MEMBERS;
};
/// Specialization of TypeSyntax for scalar types.
class MX_GENSHADER_API ScalarTypeSyntax : public TypeSyntax
{
public:
ScalarTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING);
string getValue(const Value& value, bool uniform) const override;
string getValue(const StringVec& values, bool uniform) const override;
};
/// Specialization of TypeSyntax for string types.
class MX_GENSHADER_API StringTypeSyntax : public ScalarTypeSyntax
{
public:
StringTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING);
string getValue(const Value& value, bool uniform) const override;
};
/// Specialization of TypeSyntax for aggregate types.
class MX_GENSHADER_API AggregateTypeSyntax : public TypeSyntax
{
public:
AggregateTypeSyntax(const string& name, const string& defaultValue, const string& uniformDefaultValue,
const string& typeAlias = EMPTY_STRING, const string& typeDefinition = EMPTY_STRING,
const StringVec& members = EMPTY_MEMBERS);
string getValue(const Value& value, bool uniform) const override;
string getValue(const StringVec& values, bool uniform) const override;
};
MATERIALX_NAMESPACE_END
#endif