// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "MetasoundArrayNodes.h" #include "MetasoundArrayShuffleNode.h" #include "MetasoundArrayRandomNode.h" #include "MetasoundNodeRegistrationMacro.h" #include namespace Metasound { template struct TEnableArrayNodes { static constexpr bool Value = true; }; namespace MetasoundArrayNodesPrivate { // TArrayNodeSupport acts as a configuration sturct to determine whether // a particular TArrayNode can be instantiated for a specific ArrayType. // // Some ArrayNodes require that the array elements have certain properties // such as default element constructors, element copy constructors, etc. template struct TArrayNodeSupport { private: using ElementType = typename MetasoundArrayNodesPrivate::TArrayElementType::Type; static constexpr bool bIsElementParsableAndAssignable = TIsParsable::Value && std::is_copy_assignable::value; static constexpr bool bEnabled = TEnableArrayNodes::Value; public: // Array num is supported for all array types. static constexpr bool bIsArrayNumSupported = bEnabled; // Element must be default parsable to create get operator because a // value must be returned even if the index is invalid. Also values are // assigned by copy. static constexpr bool bIsArrayGetSupported = bEnabled && bIsElementParsableAndAssignable; // Element must be copy assignable to set the value. static constexpr bool bIsArraySetSupported = bEnabled && std::is_copy_assignable::value && std::is_copy_constructible::value; // Elements must be copy constructible static constexpr bool bIsArrayConcatSupported = bEnabled && std::is_copy_constructible::value; // Elements must be copy constructible static constexpr bool bIsArraySubsetSupported = bEnabled && std::is_copy_constructible::value; // Array shuffle is supported for all types that get is supported for. static constexpr bool bIsArrayShuffleSupported = bEnabled && bIsElementParsableAndAssignable; // Random get is supported for all types that get is supported for. static constexpr bool bIsArrayRandomGetSupported = bEnabled && bIsElementParsableAndAssignable; }; template::bIsArrayGetSupported, bool>::type = true> bool RegisterArrayGetNode(const Frontend::FModuleInfo& InModuleInfo) { using FNodeType = typename Metasound::TArrayGetNode; return Frontend::RegisterNode(InModuleInfo); } template::bIsArrayGetSupported, bool>::type = true> bool RegisterArrayGetNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArraySetSupported, bool>::type = true> bool RegisterArraySetNode(const Frontend::FModuleInfo& InModuleInfo) { using FNodeType = typename Metasound::TArraySetNode; static_assert(TArrayNodeSupport::bIsArraySetSupported, "TArraySetNode<> is not supported by array type"); return Frontend::RegisterNode(InModuleInfo); } template::bIsArraySetSupported, bool>::type = true> bool RegisterArraySetNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArraySubsetSupported, bool>::type = true> bool RegisterArraySubsetNode(const Frontend::FModuleInfo& InModuleInfo) { using FNodeType = typename Metasound::TArraySubsetNode; static_assert(TArrayNodeSupport::bIsArraySubsetSupported, "TArraySubsetNode<> is not supported by array type"); return Frontend::RegisterNode(InModuleInfo); } template::bIsArraySubsetSupported, bool>::type = true> bool RegisterArraySubsetNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArrayConcatSupported, bool>::type = true> bool RegisterArrayConcatNode(const Frontend::FModuleInfo& InModuleInfo) { using FNodeType = typename Metasound::TArrayConcatNode; static_assert(TArrayNodeSupport::bIsArrayConcatSupported, "TArrayConcatNode<> is not supported by array type"); return Frontend::RegisterNode(InModuleInfo); } template::bIsArrayConcatSupported, bool>::type = true> bool RegisterArrayConcatNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArrayNumSupported, bool>::type = true> bool RegisterArrayNumNode(const Frontend::FModuleInfo& InModuleInfo) { return Frontend::RegisterNode>(InModuleInfo); } template::bIsArrayNumSupported, bool>::type = true> bool RegisterArrayNumNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArrayShuffleSupported, bool>::type = true> bool RegisterArrayShuffleNode(const Frontend::FModuleInfo& InModuleInfo) { using FNodeType = typename Metasound::TArrayShuffleNode; return Frontend::RegisterNode(InModuleInfo); } template::bIsArrayShuffleSupported, bool>::type = true> bool RegisterArrayShuffleNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArrayRandomGetSupported, bool>::type = true> bool RegisterArrayRandomGetNode(const Frontend::FModuleInfo& InModuleInfo) { using FNodeType = typename Metasound::TArrayRandomGetNode; return Frontend::RegisterNode(InModuleInfo); } template::bIsArrayRandomGetSupported, bool>::type = true> bool RegisterArrayRandomGetNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } template::bIsArrayNumSupported, bool>::type = true> bool RegisterArrayLastIndexNode(const Frontend::FModuleInfo& InModuleInfo) { return Frontend::RegisterNode>(InModuleInfo); } template::bIsArrayNumSupported, bool>::type = true> bool RegisterArrayLastIndexNode(const Frontend::FModuleInfo& InModuleInfo) { // No op if not supported return true; } } namespace Frontend { /** Registers all available array nodes which can be instantiated for the given * ArrayType. Some nodes cannot be instantiated due to limitations of the * array elements. */ template bool RegisterArrayNodes(const FModuleInfo& InModuleInfo) { using namespace MetasoundArrayNodesPrivate; bool bSuccess = RegisterArrayNumNode(InModuleInfo); bSuccess = bSuccess && RegisterArrayGetNode(InModuleInfo); bSuccess = bSuccess && RegisterArraySetNode(InModuleInfo); bSuccess = bSuccess && RegisterArraySubsetNode(InModuleInfo); bSuccess = bSuccess && RegisterArrayConcatNode(InModuleInfo); bSuccess = bSuccess && RegisterArrayShuffleNode(InModuleInfo); bSuccess = bSuccess && RegisterArrayRandomGetNode(InModuleInfo); bSuccess = bSuccess && RegisterArrayLastIndexNode(InModuleInfo); return bSuccess; } } template UE_DEPRECATED(5.6, "Use Frontend::RegisterArrayNodes() instead") bool RegisterArrayNodes() { return Frontend::RegisterArrayNodes(); } }