2021-02-19 17:05:39 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
2022-09-22 15:30:27 -04:00
# include "Interfaces/MetasoundFrontendSourceInterface.h"
2021-02-19 17:05:39 -04:00
# include "Internationalization/Text.h"
# include "MetasoundBuilderInterface.h"
# include "MetasoundDataFactory.h"
2022-09-22 15:30:27 -04:00
# include "MetasoundEnvironment.h"
2021-02-19 17:05:39 -04:00
# include "MetasoundExecutableOperator.h"
# include "MetasoundFacade.h"
# include "MetasoundLog.h"
# include "MetasoundNodeInterface.h"
2022-02-10 18:36:47 -05:00
# include "MetasoundNodeRegistrationMacro.h"
2021-02-19 17:05:39 -04:00
# include "MetasoundOperatorInterface.h"
2022-03-17 13:14:50 -04:00
# include "MetasoundParamHelper.h"
2021-02-19 17:05:39 -04:00
# include "MetasoundPrimitives.h"
# include "MetasoundTrigger.h"
2021-09-13 14:14:37 -04:00
# include "MetasoundVertex.h"
2021-02-19 17:05:39 -04:00
# include <type_traits>
# define LOCTEXT_NAMESPACE "MetasoundFrontend"
namespace Metasound
{
namespace MetasoundArrayNodesPrivate
{
// Convenience function for make FNodeClassMetadata of array nodes.
2024-05-07 16:54:01 -04:00
METASOUNDFRONTEND_API FNodeClassMetadata CreateArrayNodeClassMetadata ( const FName & InDataTypeName , const FName & InOperatorName , const FText & InDisplayName , const FText & InDescription , const FVertexInterface & InDefaultInterface , int32 MajorVersion = 1 , int32 MinorVersion = 0 , bool bIsDeprecated = false ) ;
2021-02-19 17:05:39 -04:00
// Retrieve the ElementType from an ArrayType
template < typename ArrayType >
struct TArrayElementType
{
// Default implementation has Type.
} ;
// ElementType specialization for TArray types.
template < typename ElementType >
struct TArrayElementType < TArray < ElementType > >
{
using Type = ElementType ;
} ;
}
namespace ArrayNodeVertexNames
{
2023-09-26 11:37:58 -04:00
static const FLazyName InputInitialArrayName = TEXT ( " Array " ) ;
2022-09-30 16:23:15 -04:00
# if WITH_EDITOR
static const FText InputInitialArrayTooltip = LOCTEXT ( " InitialArrayTooltip " , " Initial Array " ) ;
static const FText InputInitialArrayDisplayName = LOCTEXT ( " InitialArrayDisplayName " , " Init Array " ) ;
# else
static const FText InputInitialArrayTooltip = FText : : GetEmpty ( ) ;
static const FText InputInitialArrayDisplayName = FText : : GetEmpty ( ) ;
# endif
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( InputArray , " Array " , " Input Array. " )
METASOUND_PARAM ( InputLeftArray , " Left Array " , " Input Left Array. " )
METASOUND_PARAM ( InputRightArray , " Right Array " , " Input Right Array. " )
METASOUND_PARAM ( InputTriggerGet , " Trigger " , " Trigger to get value. " )
METASOUND_PARAM ( InputTriggerSet , " Trigger " , " Trigger to set value. " )
METASOUND_PARAM ( InputIndex , " Index " , " Index in Array. " )
METASOUND_PARAM ( InputStartIndex , " Start Index " , " First index to include. " )
METASOUND_PARAM ( InputEndIndex , " End Index " , " Last index to include. " )
METASOUND_PARAM ( InputValue , " Value " , " Value to set. " )
2021-02-19 17:05:39 -04:00
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( OutputNum , " Num " , " Number of elements in the array. " )
2022-03-30 20:06:23 -04:00
METASOUND_PARAM ( OutputValue , " Element " , " Value of element at array index. " )
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( OutputArrayConcat , " Array " , " Array after concatenation. " )
METASOUND_PARAM ( OutputArraySet , " Array " , " Array after setting. " )
METASOUND_PARAM ( OutputArraySubset , " Array " , " Subset of input array. " )
2024-04-18 01:44:09 -04:00
METASOUND_PARAM ( OutputLastIndex , " Last Index " , " Last index of the array. " )
2021-02-19 17:05:39 -04:00
} ;
/** TArrayNumOperator gets the number of elements in an Array. The operator
* uses the FNodeFacade and defines the vertex , metadata and vertex interface
* statically on the operator class . */
template < typename ArrayType >
class TArrayNumOperator : public TExecutableOperator < TArrayNumOperator < ArrayType > >
{
public :
using FArrayDataReadReference = TDataReadReference < ArrayType > ;
// Declare the vertex interface
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace ArrayNodeVertexNames ;
static const FVertexInterface DefaultInterface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputArray ) )
2021-02-19 17:05:39 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputNum ) )
2021-02-19 17:05:39 -04:00
)
) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
2021-05-10 16:56:43 -04:00
const FName DataTypeName = GetMetasoundDataTypeName < ArrayType > ( ) ;
const FName OperatorName = TEXT ( " Num " ) ;
2022-02-10 18:36:47 -05:00
const FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " ArrayOpArrayNumDisplayNamePattern " , " Num ({0}) " , GetMetasoundDataTypeDisplayText < ArrayType > ( ) ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " ArrayOpArrayNumDescription " , " Number of elements in the array " ) ;
2021-05-10 16:56:43 -04:00
const FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
2021-02-19 17:05:39 -04:00
return MetasoundArrayNodesPrivate : : CreateArrayNodeClassMetadata ( DataTypeName , OperatorName , NodeDisplayName , NodeDescription , NodeInterface ) ;
} ;
static const FNodeClassMetadata Metadata = CreateNodeClassMetadata ( ) ;
return Metadata ;
}
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
using namespace MetasoundArrayNodesPrivate ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-02-19 17:05:39 -04:00
// Get the input array or construct an empty one.
2023-10-13 19:29:51 -04:00
FArrayDataReadReference Array = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( METASOUND_GET_PARAM_NAME ( InputArray ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
return MakeUnique < TArrayNumOperator > ( Array ) ;
}
TArrayNumOperator ( FArrayDataReadReference InArray )
: Array ( InArray )
, Num ( TDataWriteReference < int32 > : : CreateNew ( ) )
{
// Initialize value for downstream nodes.
* Num = Array - > Num ( ) ;
}
virtual ~ TArrayNumOperator ( ) = default ;
virtual FDataReferenceCollection GetInputs ( ) const override
{
2023-05-30 17:07:23 -04:00
checkNoEntry ( ) ;
return { } ;
2021-02-19 17:05:39 -04:00
}
virtual FDataReferenceCollection GetOutputs ( ) const override
2023-05-30 17:07:23 -04:00
{
checkNoEntry ( ) ;
return { } ;
}
virtual void BindInputs ( FInputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputArray ) , Array ) ;
}
virtual void BindOutputs ( FOutputVertexInterfaceData & InVertexData ) override
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputNum ) , Num ) ;
2021-02-19 17:05:39 -04:00
}
void Execute ( )
{
* Num = Array - > Num ( ) ;
}
2023-02-22 17:54:26 -05:00
void Reset ( const IOperator : : FResetParams & InParams )
{
Execute ( ) ;
}
2021-02-19 17:05:39 -04:00
private :
FArrayDataReadReference Array ;
TDataWriteReference < int32 > Num ;
} ;
template < typename ArrayType >
class TArrayNumNode : public FNodeFacade
{
public :
TArrayNumNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TArrayNumOperator < ArrayType > > ( ) )
{
}
virtual ~ TArrayNumNode ( ) = default ;
} ;
/** TArrayGetOperator copies a value from the array to the output when
* a trigger occurs . Initially , the output value is default constructed and
* will remain that way until until a trigger is encountered .
*/
template < typename ArrayType >
class TArrayGetOperator : public TExecutableOperator < TArrayGetOperator < ArrayType > >
{
public :
using FArrayDataReadReference = TDataReadReference < ArrayType > ;
using ElementType = typename MetasoundArrayNodesPrivate : : TArrayElementType < ArrayType > : : Type ;
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace ArrayNodeVertexNames ;
static const FVertexInterface DefaultInterface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputTriggerGet ) ) ,
TInputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputArray ) ) ,
TInputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputIndex ) )
2021-02-19 17:05:39 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < ElementType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputValue ) )
2021-02-19 17:05:39 -04:00
)
) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
2021-05-10 16:56:43 -04:00
const FName DataTypeName = GetMetasoundDataTypeName < ArrayType > ( ) ;
const FName OperatorName = TEXT ( " Get " ) ;
2022-02-10 18:36:47 -05:00
const FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " ArrayOpArrayGetDisplayNamePattern " , " Get ({0}) " , GetMetasoundDataTypeDisplayText < ArrayType > ( ) ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " ArrayOpArrayGetDescription " , " Get element at index in array. " ) ;
2021-05-10 16:56:43 -04:00
const FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
2021-02-19 17:05:39 -04:00
return MetasoundArrayNodesPrivate : : CreateArrayNodeClassMetadata ( DataTypeName , OperatorName , NodeDisplayName , NodeDescription , NodeInterface ) ;
} ;
static const FNodeClassMetadata Metadata = CreateNodeClassMetadata ( ) ;
return Metadata ;
}
2022-09-22 15:30:27 -04:00
struct FInitParams
{
TDataReadReference < FTrigger > Trigger ;
FArrayDataReadReference Array ;
TDataReadReference < int32 > Index ;
# if WITH_METASOUND_DEBUG_ENVIRONMENT
FString GraphName ;
# endif
} ;
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
using namespace MetasoundArrayNodesPrivate ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-02-19 17:05:39 -04:00
// Input Trigger
2023-10-13 19:29:51 -04:00
TDataReadReference < FTrigger > Trigger = InputData . GetOrCreateDefaultDataReadReference < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputTriggerGet ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
// Input Array
2023-10-13 19:29:51 -04:00
FArrayDataReadReference Array = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( METASOUND_GET_PARAM_NAME ( InputArray ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
// Input Index
2023-10-13 19:29:51 -04:00
TDataReadReference < int32 > Index = InputData . GetOrCreateDefaultDataReadReference < int32 > ( METASOUND_GET_PARAM_NAME ( InputIndex ) , InParams . OperatorSettings ) ;
2022-09-22 22:19:02 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
FString GraphName ;
if ( InParams . Environment . Contains < FString > ( Frontend : : SourceInterface : : Environment : : GraphName ) )
{
GraphName = InParams . Environment . GetValue < FString > ( Frontend : : SourceInterface : : Environment : : GraphName ) ;
}
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
2022-09-22 15:30:27 -04:00
FInitParams OperatorInitParams
{
Trigger
, Array
, Index
# if WITH_METASOUND_DEBUG_ENVIRONMENT
2022-09-22 22:19:02 -04:00
, GraphName
2022-09-22 15:30:27 -04:00
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
} ;
return MakeUnique < TArrayGetOperator > ( InParams . OperatorSettings , MoveTemp ( OperatorInitParams ) ) ;
2021-02-19 17:05:39 -04:00
}
2022-09-22 15:30:27 -04:00
TArrayGetOperator ( const FOperatorSettings & InSettings , FInitParams & & InParams )
: Trigger ( InParams . Trigger )
, Array ( InParams . Array )
, Index ( InParams . Index )
2023-04-24 23:05:42 -04:00
, Value ( TDataWriteReferenceFactory < ElementType > : : CreateExplicitArgs ( InSettings ) )
2022-09-22 15:30:27 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
, GraphName ( InParams . GraphName )
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
{
2023-04-24 23:05:42 -04:00
const int32 IndexValue = * Index ;
const ArrayType & ArrayRef = * Array ;
if ( ( IndexValue > = 0 ) & & ( IndexValue < ArrayRef . Num ( ) ) )
{
* Value = ArrayRef [ IndexValue ] ;
}
2021-02-19 17:05:39 -04:00
}
virtual ~ TArrayGetOperator ( ) = default ;
virtual FDataReferenceCollection GetInputs ( ) const override
{
2023-05-30 17:07:23 -04:00
checkNoEntry ( ) ;
return { } ;
2021-02-19 17:05:39 -04:00
}
virtual FDataReferenceCollection GetOutputs ( ) const override
2023-05-30 17:07:23 -04:00
{
checkNoEntry ( ) ;
return { } ;
}
virtual void BindInputs ( FInputVertexInterfaceData & InVertexData ) override
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputTriggerGet ) , Trigger ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputArray ) , Array ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputIndex ) , Index ) ;
}
2021-02-19 17:05:39 -04:00
2023-05-30 17:07:23 -04:00
virtual void BindOutputs ( FOutputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
2021-02-19 17:05:39 -04:00
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputValue ) , Value ) ;
2021-02-19 17:05:39 -04:00
}
void Execute ( )
{
// Only perform get on trigger.
if ( * Trigger )
{
const int32 IndexValue = * Index ;
const ArrayType & ArrayRef = * Array ;
2021-03-09 21:30:41 -04:00
if ( ( IndexValue > = 0 ) & & ( IndexValue < ArrayRef . Num ( ) ) )
2021-02-19 17:05:39 -04:00
{
* Value = ArrayRef [ IndexValue ] ;
}
2022-09-22 15:30:27 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
else
{
2022-09-22 15:30:27 -04:00
UE_LOG ( LogMetaSound , Warning , TEXT ( " Attempt to get value at invalid index [ArraySize:%d, Index:%d] in MetaSound Graph \" %s \" . " ) , ArrayRef . Num ( ) , IndexValue , * GraphName ) ;
2021-02-19 17:05:39 -04:00
}
2022-09-22 15:30:27 -04:00
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
}
}
2023-02-22 17:54:26 -05:00
void Reset ( const IOperator : : FResetParams & InParams )
{
const int32 IndexValue = * Index ;
const ArrayType & ArrayRef = * Array ;
if ( ( IndexValue > = 0 ) & & ( IndexValue < ArrayRef . Num ( ) ) )
{
* Value = ArrayRef [ IndexValue ] ;
}
else
{
2023-04-24 23:05:42 -04:00
* Value = TDataTypeFactory < ElementType > : : CreateExplicitArgs ( InParams . OperatorSettings ) ;
2023-02-22 17:54:26 -05:00
}
}
2021-02-19 17:05:39 -04:00
private :
TDataReadReference < FTrigger > Trigger ;
FArrayDataReadReference Array ;
TDataReadReference < int32 > Index ;
TDataWriteReference < ElementType > Value ;
2022-09-22 15:30:27 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
FString GraphName ;
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
} ;
template < typename ArrayType >
class TArrayGetNode : public FNodeFacade
{
public :
TArrayGetNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TArrayGetOperator < ArrayType > > ( ) )
{
}
virtual ~ TArrayGetNode ( ) = default ;
} ;
/** TArraySetOperator sets an element in an array to a specific value. */
template < typename ArrayType >
class TArraySetOperator : public TExecutableOperator < TArraySetOperator < ArrayType > >
{
public :
using FArrayDataReadReference = TDataReadReference < ArrayType > ;
using FArrayDataWriteReference = TDataWriteReference < ArrayType > ;
using ElementType = typename MetasoundArrayNodesPrivate : : TArrayElementType < ArrayType > : : Type ;
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace ArrayNodeVertexNames ;
static const FVertexInterface DefaultInterface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputTriggerSet ) ) ,
2022-09-30 16:23:15 -04:00
TInputDataVertex < ArrayType > ( InputInitialArrayName , FDataVertexMetadata { InputInitialArrayTooltip , InputInitialArrayDisplayName } ) ,
2022-03-31 16:49:59 -04:00
TInputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputIndex ) ) ,
TInputDataVertex < ElementType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputValue ) )
2021-02-19 17:05:39 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputArraySet ) )
2021-02-19 17:05:39 -04:00
)
) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
2021-05-10 16:56:43 -04:00
const FName DataTypeName = GetMetasoundDataTypeName < ArrayType > ( ) ;
const FName OperatorName = TEXT ( " Set " ) ;
2022-02-10 18:36:47 -05:00
const FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " ArrayOpArraySetDisplayNamePattern " , " Set ({0}) " , GetMetasoundDataTypeDisplayText < ArrayType > ( ) ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " ArrayOpArraySetDescription " , " Set element at index in array. " ) ;
2021-05-10 16:56:43 -04:00
const FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
2021-02-19 17:05:39 -04:00
return MetasoundArrayNodesPrivate : : CreateArrayNodeClassMetadata ( DataTypeName , OperatorName , NodeDisplayName , NodeDescription , NodeInterface ) ;
} ;
static const FNodeClassMetadata Metadata = CreateNodeClassMetadata ( ) ;
return Metadata ;
}
2022-09-22 15:30:27 -04:00
struct FInitParams
{
TDataReadReference < FTrigger > Trigger ;
FArrayDataReadReference InitArray ;
FArrayDataWriteReference Array ;
TDataReadReference < int32 > Index ;
TDataReadReference < ElementType > Value ;
# if WITH_METASOUND_DEBUG_ENVIRONMENT
FString GraphName ;
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
} ;
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
using namespace MetasoundArrayNodesPrivate ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
TDataReadReference < FTrigger > Trigger = InputData . GetOrCreateDefaultDataReadReference < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputTriggerSet ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
FArrayDataReadReference InitArray = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( InputInitialArrayName , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
FArrayDataWriteReference Array = TDataWriteReferenceFactory < ArrayType > : : CreateExplicitArgs ( InParams . OperatorSettings , * InitArray ) ;
2023-10-13 19:29:51 -04:00
TDataReadReference < int32 > Index = InputData . GetOrCreateDefaultDataReadReference < int32 > ( METASOUND_GET_PARAM_NAME ( InputIndex ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
TDataReadReference < ElementType > Value = InputData . GetOrCreateDefaultDataReadReference < ElementType > ( METASOUND_GET_PARAM_NAME ( InputValue ) , InParams . OperatorSettings ) ;
2022-09-22 22:19:02 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
FString GraphName ;
if ( InParams . Environment . Contains < FString > ( Frontend : : SourceInterface : : Environment : : GraphName ) )
{
GraphName = InParams . Environment . GetValue < FString > ( Frontend : : SourceInterface : : Environment : : GraphName ) ;
}
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
2022-09-22 15:30:27 -04:00
FInitParams OperatorInitParams
{
Trigger
, InitArray
, Array
, Index
, Value
# if WITH_METASOUND_DEBUG_ENVIRONMENT
2022-09-22 22:19:02 -04:00
, GraphName
2022-09-22 15:30:27 -04:00
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
} ;
return MakeUnique < TArraySetOperator > ( InParams . OperatorSettings , MoveTemp ( OperatorInitParams ) ) ;
2021-02-19 17:05:39 -04:00
}
2022-09-22 15:30:27 -04:00
TArraySetOperator ( const FOperatorSettings & InSettings , FInitParams & & InParams )
2021-02-19 17:05:39 -04:00
: OperatorSettings ( InSettings )
2022-09-22 15:30:27 -04:00
, Trigger ( InParams . Trigger )
, InitArray ( InParams . InitArray )
, Array ( InParams . Array )
, Index ( InParams . Index )
, Value ( InParams . Value )
# if WITH_METASOUND_DEBUG_ENVIRONMENT
, GraphName ( InParams . GraphName )
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
{
}
virtual ~ TArraySetOperator ( ) = default ;
virtual FDataReferenceCollection GetInputs ( ) const override
{
2023-05-30 17:07:23 -04:00
checkNoEntry ( ) ;
return { } ;
2021-02-19 17:05:39 -04:00
}
virtual FDataReferenceCollection GetOutputs ( ) const override
2023-05-30 17:07:23 -04:00
{
checkNoEntry ( ) ;
return { } ;
}
virtual void BindInputs ( FInputVertexInterfaceData & InVertexData ) override
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputTriggerSet ) , Trigger ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputArray ) , InitArray ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputIndex ) , Index ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputValue ) , Value ) ;
}
2021-02-19 17:05:39 -04:00
2023-05-30 17:07:23 -04:00
virtual void BindOutputs ( FOutputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputArraySet ) , Array ) ;
2021-02-19 17:05:39 -04:00
}
void Execute ( )
{
if ( * Trigger )
{
const int32 IndexValue = * Index ;
ArrayType & ArrayRef = * Array ;
if ( ( IndexValue > = 0 ) & & ( IndexValue < ArrayRef . Num ( ) ) )
{
ArrayRef [ IndexValue ] = * Value ;
}
2022-09-22 15:30:27 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
else
{
2022-09-22 15:30:27 -04:00
UE_LOG ( LogMetaSound , Warning , TEXT ( " Attempt to set value at invalid index [ArraySize:%d, Index:%d] in MetaSound Graph \" %s \" . " ) , ArrayRef . Num ( ) , IndexValue , * GraphName ) ;
2021-02-19 17:05:39 -04:00
}
2022-09-22 15:30:27 -04:00
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
}
}
2023-02-22 17:54:26 -05:00
void Reset ( const IOperator : : FResetParams & Inparams )
{
* Array = * InitArray ;
}
2021-02-19 17:05:39 -04:00
private :
FOperatorSettings OperatorSettings ;
TDataReadReference < FTrigger > Trigger ;
FArrayDataReadReference InitArray ;
FArrayDataWriteReference Array ;
TDataReadReference < int32 > Index ;
TDataReadReference < ElementType > Value ;
2022-09-22 15:30:27 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
FString GraphName ;
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-02-19 17:05:39 -04:00
} ;
template < typename ArrayType >
class TArraySetNode : public FNodeFacade
{
public :
TArraySetNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TArraySetOperator < ArrayType > > ( ) )
{
}
virtual ~ TArraySetNode ( ) = default ;
} ;
/** TArrayConcatOperator concatenates two arrays on trigger. */
template < typename ArrayType >
class TArrayConcatOperator : public TExecutableOperator < TArrayConcatOperator < ArrayType > >
{
public :
using FArrayDataReadReference = TDataReadReference < ArrayType > ;
using FArrayDataWriteReference = TDataWriteReference < ArrayType > ;
using ElementType = typename MetasoundArrayNodesPrivate : : TArrayElementType < ArrayType > : : Type ;
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace ArrayNodeVertexNames ;
static const FVertexInterface DefaultInterface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputTriggerGet ) ) ,
TInputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputLeftArray ) ) ,
TInputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputRightArray ) )
2021-02-19 17:05:39 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputArrayConcat ) )
2021-02-19 17:05:39 -04:00
)
) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
2021-05-10 16:56:43 -04:00
const FName DataTypeName = GetMetasoundDataTypeName < ArrayType > ( ) ;
const FName OperatorName = TEXT ( " Concat " ) ;
2022-02-10 18:36:47 -05:00
const FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " ArrayOpArrayConcatDisplayNamePattern " , " Concatenate ({0}) " , GetMetasoundDataTypeDisplayText < ArrayType > ( ) ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " ArrayOpArrayConcatDescription " , " Concatenates two arrays on trigger. " ) ;
2021-05-10 16:56:43 -04:00
const FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
2021-02-19 17:05:39 -04:00
return MetasoundArrayNodesPrivate : : CreateArrayNodeClassMetadata ( DataTypeName , OperatorName , NodeDisplayName , NodeDescription , NodeInterface ) ;
} ;
static const FNodeClassMetadata Metadata = CreateNodeClassMetadata ( ) ;
return Metadata ;
}
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
using namespace MetasoundArrayNodesPrivate ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
TDataReadReference < FTrigger > Trigger = InputData . GetOrCreateDefaultDataReadReference < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputTriggerGet ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
FArrayDataReadReference LeftArray = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( METASOUND_GET_PARAM_NAME ( InputLeftArray ) , InParams . OperatorSettings ) ;
FArrayDataReadReference RightArray = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( METASOUND_GET_PARAM_NAME ( InputRightArray ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-02-22 17:54:26 -05:00
return MakeUnique < TArrayConcatOperator > ( Trigger , LeftArray , RightArray ) ;
2021-02-19 17:05:39 -04:00
}
2023-02-22 17:54:26 -05:00
TArrayConcatOperator ( TDataReadReference < FTrigger > InTrigger , FArrayDataReadReference InLeftArray , FArrayDataReadReference InRightArray )
2021-02-19 17:05:39 -04:00
: Trigger ( InTrigger )
, LeftArray ( InLeftArray )
, RightArray ( InRightArray )
2023-02-22 17:54:26 -05:00
, OutArray ( TDataWriteReference < ArrayType > : : CreateNew ( ) )
2021-02-19 17:05:39 -04:00
{
}
virtual ~ TArrayConcatOperator ( ) = default ;
virtual FDataReferenceCollection GetInputs ( ) const override
{
2023-05-30 17:07:23 -04:00
checkNoEntry ( ) ;
return { } ;
2021-02-19 17:05:39 -04:00
}
virtual FDataReferenceCollection GetOutputs ( ) const override
2023-05-30 17:07:23 -04:00
{
checkNoEntry ( ) ;
return { } ;
}
virtual void BindInputs ( FInputVertexInterfaceData & InVertexData ) override
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputTriggerGet ) , Trigger ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputLeftArray ) , LeftArray ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputRightArray ) , RightArray ) ;
}
2021-02-19 17:05:39 -04:00
2023-05-30 17:07:23 -04:00
virtual void BindOutputs ( FOutputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputArrayConcat ) , OutArray ) ;
2021-02-19 17:05:39 -04:00
}
void Execute ( )
{
if ( * Trigger )
{
* OutArray = * LeftArray ;
OutArray - > Append ( * RightArray ) ;
}
}
2023-02-22 17:54:26 -05:00
void Reset ( const IOperator : : FResetParams & InParams )
{
OutArray - > Reset ( ) ;
}
2021-02-19 17:05:39 -04:00
private :
TDataReadReference < FTrigger > Trigger ;
FArrayDataReadReference LeftArray ;
FArrayDataReadReference RightArray ;
FArrayDataWriteReference OutArray ;
} ;
template < typename ArrayType >
class TArrayConcatNode : public FNodeFacade
{
public :
TArrayConcatNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TArrayConcatOperator < ArrayType > > ( ) )
{
}
virtual ~ TArrayConcatNode ( ) = default ;
} ;
2021-03-09 21:30:41 -04:00
/** TArraySubsetOperator slices an array on trigger. */
2021-02-19 17:05:39 -04:00
template < typename ArrayType >
2021-03-09 21:30:41 -04:00
class TArraySubsetOperator : public TExecutableOperator < TArraySubsetOperator < ArrayType > >
2021-02-19 17:05:39 -04:00
{
public :
using FArrayDataReadReference = TDataReadReference < ArrayType > ;
using FArrayDataWriteReference = TDataWriteReference < ArrayType > ;
using ElementType = typename MetasoundArrayNodesPrivate : : TArrayElementType < ArrayType > : : Type ;
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace ArrayNodeVertexNames ;
static const FVertexInterface DefaultInterface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputTriggerGet ) ) ,
TInputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputArray ) ) ,
TInputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputStartIndex ) ) ,
TInputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputEndIndex ) )
2021-02-19 17:05:39 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputArraySubset ) )
2021-02-19 17:05:39 -04:00
)
) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
2021-05-10 16:56:43 -04:00
const FName DataTypeName = GetMetasoundDataTypeName < ArrayType > ( ) ;
const FName OperatorName = TEXT ( " Subset " ) ;
2022-02-10 18:36:47 -05:00
const FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " ArrayOpArraySubsetDisplayNamePattern " , " Subset ({0}) " , GetMetasoundDataTypeDisplayText < ArrayType > ( ) ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " ArrayOpArraySubsetDescription " , " Subset array on trigger. " ) ;
2021-05-10 16:56:43 -04:00
const FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
2021-02-19 17:05:39 -04:00
return MetasoundArrayNodesPrivate : : CreateArrayNodeClassMetadata ( DataTypeName , OperatorName , NodeDisplayName , NodeDescription , NodeInterface ) ;
} ;
static const FNodeClassMetadata Metadata = CreateNodeClassMetadata ( ) ;
return Metadata ;
}
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
using namespace MetasoundArrayNodesPrivate ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
TDataReadReference < FTrigger > Trigger = InputData . GetOrCreateDefaultDataReadReference < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputTriggerGet ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
FArrayDataReadReference InArray = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( METASOUND_GET_PARAM_NAME ( InputArray ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-10-13 19:29:51 -04:00
TDataReadReference < int32 > StartIndex = InputData . GetOrCreateDefaultDataReadReference < int32 > ( METASOUND_GET_PARAM_NAME ( InputStartIndex ) , InParams . OperatorSettings ) ;
TDataReadReference < int32 > EndIndex = InputData . GetOrCreateDefaultDataReadReference < int32 > ( METASOUND_GET_PARAM_NAME ( InputEndIndex ) , InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-02-22 17:54:26 -05:00
TDataWriteReference < ArrayType > OutputArray = TDataWriteReferenceFactory < ArrayType > : : CreateExplicitArgs ( InParams . OperatorSettings ) ;
2021-02-19 17:05:39 -04:00
2023-02-22 17:54:26 -05:00
return MakeUnique < TArraySubsetOperator > ( Trigger , InArray , StartIndex , EndIndex , OutputArray ) ;
2021-02-19 17:05:39 -04:00
}
2023-02-22 17:54:26 -05:00
TArraySubsetOperator ( TDataReadReference < FTrigger > InTrigger , FArrayDataReadReference InInputArray , TDataReadReference < int32 > InStartIndex , TDataReadReference < int32 > InEndIndex , TDataWriteReference < ArrayType > InOutputArray )
2021-02-19 17:05:39 -04:00
: Trigger ( InTrigger )
, InputArray ( InInputArray )
, StartIndex ( InStartIndex )
, EndIndex ( InEndIndex )
, OutputArray ( InOutputArray )
{
}
2021-03-09 21:30:41 -04:00
virtual ~ TArraySubsetOperator ( ) = default ;
2021-02-19 17:05:39 -04:00
virtual FDataReferenceCollection GetInputs ( ) const override
{
2023-05-30 17:07:23 -04:00
checkNoEntry ( ) ;
return { } ;
2021-02-19 17:05:39 -04:00
}
virtual FDataReferenceCollection GetOutputs ( ) const override
2023-05-30 17:07:23 -04:00
{
checkNoEntry ( ) ;
return { } ;
}
virtual void BindInputs ( FInputVertexInterfaceData & InVertexData ) override
2021-02-19 17:05:39 -04:00
{
using namespace ArrayNodeVertexNames ;
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputTriggerGet ) , Trigger ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputArray ) , InputArray ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputStartIndex ) , StartIndex ) ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputEndIndex ) , EndIndex ) ;
}
2021-02-19 17:05:39 -04:00
2023-05-30 17:07:23 -04:00
virtual void BindOutputs ( FOutputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
2021-02-19 17:05:39 -04:00
2023-05-30 17:07:23 -04:00
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputArraySubset ) , OutputArray ) ;
2021-02-19 17:05:39 -04:00
}
void Execute ( )
{
if ( * Trigger )
{
OutputArray - > Reset ( ) ;
const ArrayType & InputArrayRef = * InputArray ;
const int32 StartIndexValue = FMath : : Max ( 0 , * StartIndex ) ;
2021-03-09 21:30:41 -04:00
const int32 EndIndexValue = FMath : : Min ( InputArrayRef . Num ( ) , * EndIndex + 1 ) ;
2021-02-19 17:05:39 -04:00
if ( StartIndexValue < EndIndexValue )
{
const int32 Num = EndIndexValue - StartIndexValue ;
OutputArray - > Append ( & InputArrayRef [ StartIndexValue ] , Num ) ;
}
}
}
2023-02-22 17:54:26 -05:00
void Reset ( const IOperator : : FResetParams & InParams )
{
OutputArray - > Reset ( ) ;
}
2021-02-19 17:05:39 -04:00
private :
TDataReadReference < FTrigger > Trigger ;
FArrayDataReadReference InputArray ;
TDataReadReference < int32 > StartIndex ;
TDataReadReference < int32 > EndIndex ;
FArrayDataWriteReference OutputArray ;
} ;
template < typename ArrayType >
2021-03-09 21:30:41 -04:00
class TArraySubsetNode : public FNodeFacade
2021-02-19 17:05:39 -04:00
{
public :
2021-03-09 21:30:41 -04:00
TArraySubsetNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TArraySubsetOperator < ArrayType > > ( ) )
2021-02-19 17:05:39 -04:00
{
}
2021-03-09 21:30:41 -04:00
virtual ~ TArraySubsetNode ( ) = default ;
2021-02-19 17:05:39 -04:00
} ;
2024-04-18 01:44:09 -04:00
/** TArrayLastIndex gets last index of an array. */
template < typename ArrayType >
class TArrayLastIndexOperator : public TExecutableOperator < TArrayLastIndexOperator < ArrayType > >
{
public :
using FArrayDataReadReference = TDataReadReference < ArrayType > ;
// Declare the vertex interface
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace ArrayNodeVertexNames ;
static const FVertexInterface DefaultInterface (
FInputVertexInterface (
TInputDataVertex < ArrayType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputArray ) )
) ,
FOutputVertexInterface (
TOutputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputLastIndex ) )
)
) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
const FName DataTypeName = GetMetasoundDataTypeName < ArrayType > ( ) ;
const FName OperatorName = TEXT ( " GetLastIndex " ) ;
const FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " ArrayOpArrayLastIndexDisplayNamePattern " , " Get Last Index ({0}) " , GetMetasoundDataTypeDisplayText < ArrayType > ( ) ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " ArrayOpArrayLastIndexDescription " , " Last index of the array " ) ;
const FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
return MetasoundArrayNodesPrivate : : CreateArrayNodeClassMetadata ( DataTypeName , OperatorName , NodeDisplayName , NodeDescription , NodeInterface ) ;
} ;
static const FNodeClassMetadata Metadata = CreateNodeClassMetadata ( ) ;
return Metadata ;
}
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
{
using namespace ArrayNodeVertexNames ;
using namespace MetasoundArrayNodesPrivate ;
const FInputVertexInterfaceData & InputData = InParams . InputData ;
// Get the input array or construct an empty one.
FArrayDataReadReference Array = InputData . GetOrCreateDefaultDataReadReference < ArrayType > ( METASOUND_GET_PARAM_NAME ( InputArray ) , InParams . OperatorSettings ) ;
return MakeUnique < TArrayLastIndexOperator > ( Array ) ;
}
TArrayLastIndexOperator ( FArrayDataReadReference InArray )
: Array ( InArray )
, LastIndex ( TDataWriteReference < int32 > : : CreateNew ( ) )
{
// Initialize value for downstream nodes.
* LastIndex = Array - > Num ( ) - 1 ;
}
virtual ~ TArrayLastIndexOperator ( ) = default ;
virtual void BindInputs ( FInputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputArray ) , Array ) ;
}
virtual void BindOutputs ( FOutputVertexInterfaceData & InVertexData ) override
{
using namespace ArrayNodeVertexNames ;
InVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputLastIndex ) , LastIndex ) ;
}
void Execute ( )
{
* LastIndex = Array - > Num ( ) - 1 ;
}
void Reset ( const IOperator : : FResetParams & InParams )
{
Execute ( ) ;
}
private :
FArrayDataReadReference Array ;
TDataWriteReference < int32 > LastIndex ;
} ;
template < typename ArrayType >
class TArrayLastIndexNode : public FNodeFacade
{
public :
TArrayLastIndexNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TArrayLastIndexOperator < ArrayType > > ( ) )
{
}
virtual ~ TArrayLastIndexNode ( ) = default ;
} ;
2021-09-13 14:14:37 -04:00
} // namespace Metasound
2021-02-19 17:05:39 -04:00
# undef LOCTEXT_NAMESPACE