2021-03-12 02:25:30 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "CoreMinimal.h"
# include "MetasoundBuilderInterface.h"
# include "MetasoundDataReferenceCollection.h"
# include "MetasoundExecutableOperator.h"
# include "MetasoundFacade.h"
# include "MetasoundNode.h"
# include "MetasoundNodeInterface.h"
# include "MetasoundNodeRegistrationMacro.h"
# include "MetasoundOperatorInterface.h"
2022-03-17 13:14:50 -04:00
# include "MetasoundParamHelper.h"
2021-03-12 02:25:30 -04:00
# include "MetasoundPrimitives.h"
# include "MetasoundStandardNodesNames.h"
# include "MetasoundStandardNodesCategories.h"
2021-04-01 11:12:27 -04:00
# include "MetasoundAudioBuffer.h"
2021-04-01 18:31:35 -04:00
# include "MetasoundTrigger.h"
2021-03-12 02:25:30 -04:00
2021-04-07 02:57:54 -04:00
# define LOCTEXT_NAMESPACE "MetasoundStandardNodes_TriggerRouter"
2021-03-12 02:25:30 -04:00
2021-04-04 03:13:12 -04:00
# define REGISTER_TRIGGER_ROUTE_NODE(DataType, Number) \
2021-03-12 02:25:30 -04:00
using FTriggerRouteNode # # DataType # # _ # # Number = TTriggerRouteNode < DataType , Number > ; \
METASOUND_REGISTER_NODE ( FTriggerRouteNode # # DataType # # _ # # Number ) \
namespace Metasound
{
namespace TriggerRouteVertexNames
{
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( OutputTrigger , " On Set " , " Triggered when any of the input triggers are set. " )
METASOUND_PARAM ( OutputValue , " Value " , " The output value set by the input triggers. " )
2021-09-13 14:13:39 -04:00
const FVertexName GetInputTriggerName ( uint32 InIndex )
2021-03-12 02:25:30 -04:00
{
2021-09-13 14:13:39 -04:00
return * FString : : Format ( TEXT ( " Set {0} " ) , { InIndex } ) ;
2021-03-12 02:25:30 -04:00
}
2022-03-17 13:14:50 -04:00
const FText GetInputTriggerDisplayName ( uint32 InIndex )
{
return METASOUND_LOCTEXT_FORMAT ( " InputTriggerDisplayName " , " Set {0} " , InIndex ) ;
}
2021-03-12 02:25:30 -04:00
const FText GetInputTriggerDescription ( uint32 InIndex )
{
2021-04-01 18:31:35 -04:00
if ( InIndex = = 0 )
{
2022-02-10 18:36:47 -05:00
return METASOUND_LOCTEXT_FORMAT ( " TriggerRouteInputTriggerDescInit " , " The input trigger {0} to cause the corresponding input value to route to the output value. This trigger is the default output. " , InIndex ) ;
2021-04-01 18:31:35 -04:00
}
2022-02-10 18:36:47 -05:00
return METASOUND_LOCTEXT_FORMAT ( " TriggerRouteInputTriggerDesc " , " The input trigger {0} to cause the corresponding input value to route to the output value. " , InIndex ) ;
2021-03-12 02:25:30 -04:00
}
2021-09-13 14:13:39 -04:00
const FVertexName GetInputValueName ( uint32 InIndex )
2021-03-12 02:25:30 -04:00
{
2021-09-13 14:13:39 -04:00
return * FString : : Format ( TEXT ( " Value {0} " ) , { InIndex } ) ;
2021-03-12 02:25:30 -04:00
}
const FText GetInputValueDescription ( uint32 InIndex )
{
2022-02-10 18:36:47 -05:00
return METASOUND_LOCTEXT_FORMAT ( " TriggerRouteValueDesc " , " The input value ({0}) to route to the output when triggered by Set { 0 } . " , InIndex);
2021-03-12 02:25:30 -04:00
}
2022-03-17 13:14:50 -04:00
const FText GetInputValueDisplayName ( uint32 InIndex )
2021-03-12 02:25:30 -04:00
{
2022-03-17 13:14:50 -04:00
return METASOUND_LOCTEXT_FORMAT ( " InputValueDisplayName " , " Value {0} " , InIndex ) ;
2021-03-12 02:25:30 -04:00
}
}
2021-04-01 18:31:35 -04:00
namespace MetasoundTriggerRouteNodePrivate
{
FNodeClassMetadata CreateNodeClassMetadata ( const FName & InDataTypeName , const FName & InOperatorName , const FText & InDisplayName , const FText & InDescription , const FVertexInterface & InDefaultInterface )
{
FNodeClassMetadata Metadata
{
2021-08-09 15:08:37 -04:00
FNodeClassName { " TriggerRoute " , InOperatorName , InDataTypeName } ,
2021-04-01 18:31:35 -04:00
1 , // Major Version
0 , // Minor Version
InDisplayName ,
InDescription ,
PluginAuthor ,
PluginNodeMissingPrompt ,
InDefaultInterface ,
2021-08-09 15:08:37 -04:00
{ NodeCategories : : Trigger } ,
{ } ,
FNodeDisplayStyle ( )
2021-04-01 18:31:35 -04:00
} ;
return Metadata ;
}
}
template < typename ValueType , uint32 NumInputs >
class TTriggerRouteOperator : public TExecutableOperator < TTriggerRouteOperator < ValueType , NumInputs > >
{
public :
static const FVertexInterface & GetDefaultInterface ( )
{
using namespace TriggerRouteVertexNames ;
auto CreateDefaultInterface = [ ] ( ) - > FVertexInterface
{
FInputVertexInterface InputInterface ;
for ( uint32 i = 0 ; i < NumInputs ; + + i )
{
2022-03-17 13:14:50 -04:00
const FDataVertexMetadata InputTriggerMetadata
{
GetInputTriggerDescription ( i ) // description
, GetInputTriggerDisplayName ( i ) // display name
} ;
const FDataVertexMetadata InputValueMetadata
{
GetInputValueDescription ( i ) // description
, GetInputValueDisplayName ( i ) // display name
} ;
2022-03-31 16:49:59 -04:00
InputInterface . Add ( TInputDataVertex < FTrigger > ( GetInputTriggerName ( i ) , InputTriggerMetadata ) ) ;
InputInterface . Add ( TInputDataVertex < ValueType > ( GetInputValueName ( i ) , InputValueMetadata ) ) ;
2021-04-01 18:31:35 -04:00
}
FOutputVertexInterface OutputInterface ;
2022-03-31 16:49:59 -04:00
OutputInterface . Add ( TOutputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputTrigger ) ) ) ;
OutputInterface . Add ( TOutputDataVertex < ValueType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputValue ) ) ) ;
2021-04-01 18:31:35 -04:00
return FVertexInterface ( InputInterface , OutputInterface ) ;
} ;
static const FVertexInterface DefaultInterface = CreateDefaultInterface ( ) ;
return DefaultInterface ;
}
static const FNodeClassMetadata & GetNodeInfo ( )
{
auto CreateNodeClassMetadata = [ ] ( ) - > FNodeClassMetadata
{
FName DataTypeName = GetMetasoundDataTypeName < ValueType > ( ) ;
FName OperatorName = * FString : : Printf ( TEXT ( " Trigger Route (%s, %d) " ) , * DataTypeName . ToString ( ) , NumInputs ) ;
2022-02-10 18:36:47 -05:00
FText NodeDisplayName = METASOUND_LOCTEXT_FORMAT ( " TriggerRouteDisplayNamePattern " , " Trigger Route ({0}, {1}) " , GetMetasoundDataTypeDisplayText < ValueType > ( ) , NumInputs ) ;
const FText NodeDescription = METASOUND_LOCTEXT ( " TriggerRouteDescription " , " Allows routing different values to the same output pin depending on trigger inputs. " ) ;
2021-04-01 18:31:35 -04:00
FVertexInterface NodeInterface = GetDefaultInterface ( ) ;
return MetasoundTriggerRouteNodePrivate : : CreateNodeClassMetadata ( 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-04-01 18:31:35 -04:00
{
using namespace TriggerRouteVertexNames ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-04-01 18:31:35 -04:00
TArray < FTriggerReadRef > InputTriggers ;
TArray < TDataReadReference < ValueType > > InputValues ;
for ( uint32 i = 0 ; i < NumInputs ; + + i )
{
2023-10-13 19:29:51 -04:00
InputTriggers . Add ( InputData . GetOrConstructDataReadReference < FTrigger > ( GetInputTriggerName ( i ) , InParams . OperatorSettings ) ) ;
InputValues . Add ( InputData . GetOrCreateDefaultDataReadReference < ValueType > ( GetInputValueName ( i ) , InParams . OperatorSettings ) ) ;
2021-04-01 18:31:35 -04:00
}
2023-03-02 14:40:35 -05:00
return MakeUnique < TTriggerRouteOperator < ValueType , NumInputs > > ( InParams , MoveTemp ( InputTriggers ) , MoveTemp ( InputValues ) ) ;
2021-04-01 18:31:35 -04:00
}
2023-10-13 19:29:51 -04:00
TTriggerRouteOperator ( const FBuildOperatorParams & InParams , TArray < FTriggerReadRef > & & InInputTriggers , TArray < TDataReadReference < ValueType > > & & InInputValues )
2021-04-01 18:31:35 -04:00
: InputTriggers ( MoveTemp ( InInputTriggers ) )
, InputValues ( MoveTemp ( InInputValues ) )
2023-03-02 14:40:35 -05:00
, OutputTrigger ( FTriggerWriteRef : : CreateNew ( InParams . OperatorSettings ) )
, OutputValue ( TDataWriteReferenceFactory < ValueType > : : CreateAny ( InParams . OperatorSettings ) )
2021-04-01 18:31:35 -04:00
{
2023-03-02 14:40:35 -05:00
check ( InputValues . Num ( ) > 0 ) ;
2022-05-27 19:30:23 -04:00
2023-03-02 14:40:35 -05:00
// Call Update() to initialize output value and determine initial
// trigger index.
Update ( ) ;
2021-04-01 18:31:35 -04:00
}
virtual ~ TTriggerRouteOperator ( ) = default ;
2023-05-22 13:28:27 -04:00
virtual void BindInputs ( FInputVertexInterfaceData & InOutVertexData ) override
{
using namespace TriggerRouteVertexNames ;
for ( uint32 i = 0 ; i < NumInputs ; + + i )
{
InOutVertexData . BindReadVertex ( GetInputTriggerName ( i ) , InputTriggers [ i ] ) ;
InOutVertexData . BindReadVertex ( GetInputValueName ( i ) , InputValues [ i ] ) ;
}
}
virtual void BindOutputs ( FOutputVertexInterfaceData & InOutVertexData ) override
{
using namespace TriggerRouteVertexNames ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputTrigger ) , OutputTrigger ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputValue ) , OutputValue ) ;
}
2021-04-01 18:31:35 -04:00
virtual FDataReferenceCollection GetInputs ( ) const override
{
2023-05-22 13:28:27 -04:00
// This should never be called. Bind(...) is called instead. This method
// exists as a stop-gap until the API can be deprecated and removed.
checkNoEntry ( ) ;
return { } ;
2021-04-01 18:31:35 -04:00
}
virtual FDataReferenceCollection GetOutputs ( ) const override
{
2023-05-22 13:28:27 -04:00
// This should never be called. Bind(...) is called instead. This method
// exists as a stop-gap until the API can be deprecated and removed.
checkNoEntry ( ) ;
return { } ;
2021-04-01 18:31:35 -04:00
}
void Execute ( )
{
OutputTrigger - > AdvanceBlock ( ) ;
2023-03-02 14:40:35 -05:00
Update ( ) ;
}
2021-04-01 18:31:35 -04:00
2023-03-02 14:40:35 -05:00
void Reset ( const IOperator : : FResetParams & InParams )
{
OutputTrigger - > Reset ( ) ;
CurrentIndex = 0 ;
Update ( ) ;
}
private :
void Update ( )
{
2021-04-01 18:31:35 -04:00
for ( uint32 i = 0 ; i < NumInputs ; + + i )
{
InputTriggers [ i ] - > ExecuteBlock (
[ & ] ( int32 StartFrame , int32 EndFrame )
{
} ,
[ this , i ] ( int32 StartFrame , int32 EndFrame )
{
CurrentIndex = i ;
OutputTrigger - > TriggerFrame ( StartFrame ) ;
}
2022-04-28 02:04:53 -04:00
) ;
2022-05-27 12:53:21 -04:00
}
* OutputValue = * InputValues [ CurrentIndex ] ;
2021-04-01 18:31:35 -04:00
}
TArray < FTriggerReadRef > InputTriggers ;
TArray < TDataReadReference < ValueType > > InputValues ;
FTriggerWriteRef OutputTrigger ;
TDataWriteReference < ValueType > OutputValue ;
int32 CurrentIndex = 0 ;
} ;
/** TTriggerRouteNode
*
* Routes values from multiple input pins to a single output pin based on trigger inputs .
*/
template < typename ValueType , uint32 NumInputs >
class METASOUNDSTANDARDNODES_API TTriggerRouteNode : public FNodeFacade
{
public :
/**
* Constructor used by the Metasound Frontend .
*/
TTriggerRouteNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < TTriggerRouteOperator < ValueType , NumInputs > > ( ) )
{ }
virtual ~ TTriggerRouteNode ( ) = default ;
} ;
2021-04-04 03:13:12 -04:00
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 2 )
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 3 )
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 4 )
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 5 )
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 6 )
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 7 )
REGISTER_TRIGGER_ROUTE_NODE ( int32 , 8 )
2021-03-12 02:25:30 -04:00
2021-04-04 03:13:12 -04:00
REGISTER_TRIGGER_ROUTE_NODE ( float , 2 )
REGISTER_TRIGGER_ROUTE_NODE ( float , 3 )
REGISTER_TRIGGER_ROUTE_NODE ( float , 4 )
REGISTER_TRIGGER_ROUTE_NODE ( float , 5 )
REGISTER_TRIGGER_ROUTE_NODE ( float , 6 )
REGISTER_TRIGGER_ROUTE_NODE ( float , 7 )
REGISTER_TRIGGER_ROUTE_NODE ( float , 8 )
2021-03-12 02:25:30 -04:00
2022-01-18 17:47:04 -05:00
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 2 )
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 3 )
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 4 )
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 5 )
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 6 )
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 7 )
REGISTER_TRIGGER_ROUTE_NODE ( FTime , 8 )
2021-04-04 03:13:12 -04:00
REGISTER_TRIGGER_ROUTE_NODE ( bool , 2 )
REGISTER_TRIGGER_ROUTE_NODE ( bool , 3 )
REGISTER_TRIGGER_ROUTE_NODE ( bool , 4 )
REGISTER_TRIGGER_ROUTE_NODE ( bool , 5 )
REGISTER_TRIGGER_ROUTE_NODE ( bool , 6 )
REGISTER_TRIGGER_ROUTE_NODE ( bool , 7 )
REGISTER_TRIGGER_ROUTE_NODE ( bool , 8 )
2021-04-01 11:12:27 -04:00
2021-04-04 03:13:12 -04:00
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 2 )
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 3 )
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 4 )
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 5 )
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 6 )
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 7 )
REGISTER_TRIGGER_ROUTE_NODE ( FAudioBuffer , 8 )
2021-03-12 02:25:30 -04:00
}
# undef LOCTEXT_NAMESPACE // MetasoundTriggerDelayNode