2021-03-04 21:06:06 -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"
# include "MetasoundPrimitives.h"
# include "MetasoundStandardNodesNames.h"
2021-03-05 23:03:16 -04:00
# include "MetasoundStandardNodesCategories.h"
2021-04-01 20:10:37 -04:00
# include "MetasoundTrigger.h"
2021-03-24 03:22:53 -04:00
# include "MetasoundParamHelper.h"
2021-03-04 21:06:06 -04:00
2021-04-01 20:10:37 -04:00
# define LOCTEXT_NAMESPACE "MetasoundStandardNodes_CounterNode"
2021-03-04 21:06:06 -04:00
namespace Metasound
{
2021-03-24 03:22:53 -04:00
namespace TriggerCounterVertexNames
2021-03-04 21:06:06 -04:00
{
2021-03-24 03:22:53 -04:00
METASOUND_PARAM ( InputInTrigger , " In " , " Trigger Input to count. " ) ;
2021-04-01 20:10:37 -04:00
METASOUND_PARAM ( InputReset , " Reset " , " Resets the counter to zero and the value back to the start value. " ) ;
METASOUND_PARAM ( InputStartValue , " Start Value " , " The value to set the ouput to on init and reset. " ) ;
METASOUND_PARAM ( InputStepSize , " Step Size " , " The value to add to the current value for each input trigger. Can be negative. " ) ;
METASOUND_PARAM ( InputAutoResetCount , " Reset Count " , " The number of input triggers to automatically set the count back to Start Count. If 0, won't auto-reset. " ) ;
2021-03-24 03:22:53 -04:00
METASOUND_PARAM ( OutputOnTrigger , " On Trigger " , " Triggered when the input is triggered. " ) ;
METASOUND_PARAM ( OutputOnReset , " On Reset " , " Triggered when the input reset trigger is triggered or if the counter automatically resets. " ) ;
2021-04-01 20:10:37 -04:00
METASOUND_PARAM ( OutputCount , " Count " , " The current raw trigger count (i.e. number of times the input trigger has been triggered). " ) ;
METASOUND_PARAM ( OutputValue , " Value " , " The current value of the node given the starting value and step size. " ) ;
2021-03-04 21:06:06 -04:00
}
class FTriggerCounterOperator : public TExecutableOperator < FTriggerCounterOperator >
{
public :
static const FNodeClassMetadata & GetNodeInfo ( ) ;
static const FVertexInterface & GetVertexInterface ( ) ;
static TUniquePtr < IOperator > CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors ) ;
2021-03-24 03:22:53 -04:00
FTriggerCounterOperator ( const FOperatorSettings & InSettings ,
const FTriggerReadRef & InTriggerIn ,
const FTriggerReadRef & InTriggerReset ,
2021-04-01 20:10:37 -04:00
const FFloatReadRef & InStartValue ,
const FFloatReadRef & InStepSize ,
2021-03-24 03:22:53 -04:00
const FInt32ReadRef & InAutoResetCount ) ;
2021-03-04 21:06:06 -04:00
2023-05-22 13:28:27 -04:00
virtual void BindInputs ( FInputVertexInterfaceData & InOutVertexData ) override ;
virtual void BindOutputs ( FOutputVertexInterfaceData & InOutVertexData ) override ;
2021-03-04 21:06:06 -04:00
virtual FDataReferenceCollection GetInputs ( ) const override ;
virtual FDataReferenceCollection GetOutputs ( ) const override ;
void Execute ( ) ;
2023-03-02 14:40:35 -05:00
void Reset ( const IOperator : : FResetParams & InParams ) ;
2021-03-04 21:06:06 -04:00
private :
FTriggerReadRef TriggerIn ;
FTriggerReadRef TriggerReset ;
2021-04-01 20:10:37 -04:00
FFloatReadRef StartValue ;
FFloatReadRef StepSize ;
2021-03-24 03:22:53 -04:00
FInt32ReadRef AutoResetCount ;
FTriggerWriteRef TriggerOut ;
FTriggerWriteRef TriggerOnReset ;
2021-04-01 20:10:37 -04:00
FFloatWriteRef OutValue ;
FInt32WriteRef OutCount ;
2021-03-24 03:22:53 -04:00
// Internal state to do the counting math
int32 CurrentAutoResetCount = 0 ;
int32 CurrentTriggerCount = 0 ;
2021-04-01 20:10:37 -04:00
float CurrentValue = 0.0f ;
2022-02-25 09:41:54 -05:00
bool bIsFirstTrigger = true ;
2021-03-04 21:06:06 -04:00
} ;
2021-03-24 03:22:53 -04:00
FTriggerCounterOperator : : FTriggerCounterOperator ( const FOperatorSettings & InSettings ,
const FTriggerReadRef & InTriggerIn ,
const FTriggerReadRef & InTriggerReset ,
2021-04-01 20:10:37 -04:00
const FFloatReadRef & InStartValue ,
const FFloatReadRef & InStepSize ,
2021-03-24 03:22:53 -04:00
const FInt32ReadRef & InAutoResetCount )
: TriggerIn ( InTriggerIn )
, TriggerReset ( InTriggerReset )
2021-04-01 20:10:37 -04:00
, StartValue ( InStartValue )
, StepSize ( InStepSize )
2021-03-24 03:22:53 -04:00
, AutoResetCount ( InAutoResetCount )
, TriggerOut ( FTriggerWriteRef : : CreateNew ( InSettings ) )
, TriggerOnReset ( FTriggerWriteRef : : CreateNew ( InSettings ) )
2021-04-01 20:10:37 -04:00
, OutValue ( FFloatWriteRef : : CreateNew ( * StartValue ) )
, OutCount ( FInt32WriteRef : : CreateNew ( 0 ) )
2021-03-04 21:06:06 -04:00
{
2021-03-24 03:22:53 -04:00
CurrentAutoResetCount = FMath : : Max ( 0 , * AutoResetCount ) ;
2021-03-04 21:06:06 -04:00
}
2023-05-22 13:28:27 -04:00
void FTriggerCounterOperator : : BindInputs ( FInputVertexInterfaceData & InOutVertexData )
2021-03-04 21:06:06 -04:00
{
2021-03-24 03:22:53 -04:00
using namespace TriggerCounterVertexNames ;
2021-03-04 21:06:06 -04:00
FDataReferenceCollection InputDataReferences ;
2023-05-22 13:28:27 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputInTrigger ) , TriggerIn ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputReset ) , TriggerReset ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputStartValue ) , StartValue ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputStepSize ) , StepSize ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputAutoResetCount ) , AutoResetCount ) ;
2021-03-04 21:06:06 -04:00
}
2023-05-22 13:28:27 -04:00
void FTriggerCounterOperator : : BindOutputs ( FOutputVertexInterfaceData & InOutVertexData )
2021-03-04 21:06:06 -04:00
{
2021-03-24 03:22:53 -04:00
using namespace TriggerCounterVertexNames ;
2021-03-04 21:06:06 -04:00
FDataReferenceCollection OutputDataReferences ;
2023-05-22 13:28:27 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputOnTrigger ) , TriggerOut ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputOnReset ) , TriggerOnReset ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputCount ) , OutCount ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutputValue ) , OutValue ) ;
}
2021-03-04 21:06:06 -04:00
2023-05-22 13:28:27 -04:00
FDataReferenceCollection FTriggerCounterOperator : : GetInputs ( ) const
{
// 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 { } ;
}
FDataReferenceCollection FTriggerCounterOperator : : GetOutputs ( ) const
{
// 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-03-04 21:06:06 -04:00
}
void FTriggerCounterOperator : : Execute ( )
2021-03-24 03:22:53 -04:00
{
TriggerOnReset - > AdvanceBlock ( ) ;
TriggerOut - > AdvanceBlock ( ) ;
// Update the current auto reset count
CurrentAutoResetCount = FMath : : Max ( 0 , * AutoResetCount ) ;
2021-03-04 21:06:06 -04:00
TriggerReset - > ExecuteBlock (
[ & ] ( int32 StartFrame , int32 EndFrame )
{
} ,
[ this ] ( int32 StartFrame , int32 EndFrame )
{
2022-02-25 09:41:54 -05:00
* OutCount = CurrentTriggerCount = 0 ;
2021-04-01 20:10:37 -04:00
* OutValue = * StartValue ;
2021-03-24 03:22:53 -04:00
2022-02-25 19:31:19 -05:00
bIsFirstTrigger = true ;
2021-03-24 03:22:53 -04:00
TriggerOnReset - > TriggerFrame ( StartFrame ) ;
2021-03-04 21:06:06 -04:00
}
) ;
TriggerIn - > ExecuteBlock (
[ & ] ( int32 StartFrame , int32 EndFrame )
{
} ,
[ this ] ( int32 StartFrame , int32 EndFrame )
{
2021-03-24 03:22:53 -04:00
+ + CurrentTriggerCount ;
2022-02-25 09:41:54 -05:00
if ( bIsFirstTrigger )
{
CurrentTriggerCount = 1 ;
* OutValue = * StartValue ;
bIsFirstTrigger = false ;
}
else if ( CurrentAutoResetCount > 0 & & CurrentTriggerCount > CurrentAutoResetCount )
2021-03-24 03:22:53 -04:00
{
2021-05-07 14:47:54 -04:00
CurrentTriggerCount = 1 ;
2021-04-01 20:10:37 -04:00
* OutValue = * StartValue ;
2021-03-24 03:22:53 -04:00
TriggerOnReset - > TriggerFrame ( StartFrame ) ;
}
else
{
2021-04-01 20:10:37 -04:00
* OutValue + = * StepSize ;
2021-03-24 03:22:53 -04:00
}
2021-04-01 20:10:37 -04:00
* OutCount = CurrentTriggerCount ;
2021-03-24 03:22:53 -04:00
TriggerOut - > TriggerFrame ( StartFrame ) ;
2021-03-04 21:06:06 -04:00
}
) ;
2021-03-24 03:22:53 -04:00
2021-03-04 21:06:06 -04:00
}
2023-03-02 14:40:35 -05:00
void FTriggerCounterOperator : : Reset ( const IOperator : : FResetParams & InParams )
{
TriggerOut - > Reset ( ) ;
TriggerOnReset - > Reset ( ) ;
* OutValue = * StartValue ;
* OutCount = 0 ;
CurrentAutoResetCount = FMath : : Max ( 0 , * AutoResetCount ) ;
CurrentTriggerCount = 0 ;
CurrentValue = 0.0f ;
bIsFirstTrigger = true ;
}
2021-03-04 21:06:06 -04:00
TUniquePtr < IOperator > FTriggerCounterOperator : : CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors )
{
2021-03-24 03:22:53 -04:00
using namespace TriggerCounterVertexNames ;
2021-03-04 21:06:06 -04:00
2021-03-24 03:22:53 -04:00
const FInputVertexInterface & InputInterface = GetVertexInterface ( ) . GetInputInterface ( ) ;
FTriggerReadRef TriggerIn = InParams . InputDataReferences . GetDataReadReferenceOrConstruct < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputInTrigger ) , InParams . OperatorSettings ) ;
FTriggerReadRef TriggerReset = InParams . InputDataReferences . GetDataReadReferenceOrConstruct < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputReset ) , InParams . OperatorSettings ) ;
2021-04-01 20:10:37 -04:00
FFloatReadRef StartValue = InParams . InputDataReferences . GetDataReadReferenceOrConstructWithVertexDefault < float > ( InputInterface , METASOUND_GET_PARAM_NAME ( InputStartValue ) , InParams . OperatorSettings ) ;
FFloatReadRef StepSize = InParams . InputDataReferences . GetDataReadReferenceOrConstructWithVertexDefault < float > ( InputInterface , METASOUND_GET_PARAM_NAME ( InputStepSize ) , InParams . OperatorSettings ) ;
2021-03-24 03:22:53 -04:00
FInt32ReadRef AutoResetCount = InParams . InputDataReferences . GetDataReadReferenceOrConstructWithVertexDefault < int32 > ( InputInterface , METASOUND_GET_PARAM_NAME ( InputAutoResetCount ) , InParams . OperatorSettings ) ;
2021-04-01 20:10:37 -04:00
return MakeUnique < FTriggerCounterOperator > ( InParams . OperatorSettings , TriggerIn , TriggerReset , StartValue , StepSize , AutoResetCount ) ;
2021-03-04 21:06:06 -04:00
}
const FVertexInterface & FTriggerCounterOperator : : GetVertexInterface ( )
{
2021-03-24 03:22:53 -04:00
using namespace TriggerCounterVertexNames ;
2021-03-04 21:06:06 -04:00
static const FVertexInterface Interface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputInTrigger ) ) ,
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputReset ) ) ,
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputStartValue ) , 0.0f ) ,
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputStepSize ) , 1.0f ) ,
TInputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputAutoResetCount ) , 0 )
2021-03-04 21:06:06 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputOnTrigger ) ) ,
TOutputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputOnReset ) ) ,
TOutputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputCount ) ) ,
TOutputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutputValue ) )
2021-03-04 21:06:06 -04:00
)
) ;
return Interface ;
}
const FNodeClassMetadata & FTriggerCounterOperator : : GetNodeInfo ( )
{
auto InitNodeInfo = [ ] ( ) - > FNodeClassMetadata
{
FNodeClassMetadata Info ;
2021-08-09 15:08:37 -04:00
Info . ClassName = { StandardNodes : : Namespace , TEXT ( " Trigger Counter " ) , TEXT ( " " ) } ;
2021-03-04 21:06:06 -04:00
Info . MajorVersion = 1 ;
Info . MinorVersion = 0 ;
2022-02-10 18:36:47 -05:00
Info . DisplayName = METASOUND_LOCTEXT ( " Metasound_TriggerCounterNodeDisplayName " , " Trigger Counter " ) ;
Info . Description = METASOUND_LOCTEXT ( " Metasound_TriggerCounterNodeDescription " , " Counts the trigger inputs. Supports a start count value, counting by a step size, and auto resetting back to the start count. " ) ;
2021-03-04 21:06:06 -04:00
Info . Author = PluginAuthor ;
Info . PromptIfMissing = PluginNodeMissingPrompt ;
Info . DefaultInterface = GetVertexInterface ( ) ;
2021-08-09 15:08:37 -04:00
Info . CategoryHierarchy . Emplace ( NodeCategories : : Trigger ) ;
2021-03-04 21:06:06 -04:00
return Info ;
} ;
static const FNodeClassMetadata Info = InitNodeInfo ( ) ;
return Info ;
}
2021-04-01 20:10:37 -04:00
class FTriggerCounterNode : public FNodeFacade
2021-03-04 21:06:06 -04:00
{
2021-04-01 20:10:37 -04:00
public :
FTriggerCounterNode ( const FNodeInitData & InInitData )
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < FTriggerCounterOperator > ( ) )
{
}
virtual ~ FTriggerCounterNode ( ) = default ;
} ;
2021-03-04 21:06:06 -04:00
METASOUND_REGISTER_NODE ( FTriggerCounterNode )
}
# undef LOCTEXT_NAMESPACE // MetasoundTriggerDelayNode