2021-01-11 22:57:56 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundTriggerDelayNode.h"
# 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"
2021-01-28 19:02:51 -04:00
# include "MetasoundStandardNodesNames.h"
2021-01-11 22:57:56 -04:00
# define LOCTEXT_NAMESPACE "MetasoundStandardNodes"
namespace Metasound
{
METASOUND_REGISTER_NODE ( FTriggerDelayNode )
class FTriggerDelayOperator : public TExecutableOperator < FTriggerDelayOperator >
{
public :
2021-01-28 19:02:51 -04:00
static const FNodeClassMetadata & GetNodeInfo ( ) ;
2021-02-03 15:40:56 -04:00
static const FVertexInterface & GetVertexInterface ( ) ;
2021-01-11 22:57:56 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors ) ;
FTriggerDelayOperator ( const FOperatorSettings & InSettings , const FTriggerReadRef & InTriggerReset , const FTriggerReadRef & InTriggerIn , const FFloatTimeReadRef & InDelay ) ;
virtual FDataReferenceCollection GetInputs ( ) const override ;
virtual FDataReferenceCollection GetOutputs ( ) const override ;
void Execute ( ) ;
private :
2021-02-03 14:36:36 -04:00
int32 SamplesUntilTrigger = - 1 ;
int32 LastFrameReset = - 1 ;
2021-01-11 22:57:56 -04:00
FTriggerReadRef TriggerIn ;
FTriggerReadRef TriggerReset ;
FTriggerWriteRef TriggerOut ;
FFloatTimeReadRef Delay ;
float FramesPerBlock ;
float SampleRate ;
} ;
FTriggerDelayOperator : : FTriggerDelayOperator ( const FOperatorSettings & InSettings , const FTriggerReadRef & InTriggerReset , const FTriggerReadRef & InTriggerIn , const FFloatTimeReadRef & InDelay )
: SamplesUntilTrigger ( - 1 )
2021-02-03 14:36:36 -04:00
, LastFrameReset ( - 1 )
2021-01-11 22:57:56 -04:00
, TriggerIn ( InTriggerIn )
, TriggerReset ( InTriggerReset )
, TriggerOut ( FTriggerWriteRef : : CreateNew ( InSettings ) )
, Delay ( InDelay )
, FramesPerBlock ( InSettings . GetNumFramesPerBlock ( ) )
, SampleRate ( InSettings . GetSampleRate ( ) )
{
}
FDataReferenceCollection FTriggerDelayOperator : : GetInputs ( ) const
{
FDataReferenceCollection InputDataReferences ;
InputDataReferences . AddDataReadReference ( TEXT ( " Delay " ) , FFloatTimeReadRef ( Delay ) ) ;
InputDataReferences . AddDataReadReference ( TEXT ( " In " ) , FTriggerReadRef ( TriggerIn ) ) ;
InputDataReferences . AddDataReadReference ( TEXT ( " Reset " ) , FTriggerReadRef ( TriggerIn ) ) ;
return InputDataReferences ;
}
FDataReferenceCollection FTriggerDelayOperator : : GetOutputs ( ) const
{
FDataReferenceCollection OutputDataReferences ;
OutputDataReferences . AddDataReadReference ( TEXT ( " Out " ) , FTriggerReadRef ( TriggerOut ) ) ;
return OutputDataReferences ;
}
void FTriggerDelayOperator : : Execute ( )
{
// Advance internal counter to get rid of old triggers.
TriggerOut - > AdvanceBlock ( ) ;
2021-02-03 14:36:36 -04:00
LastFrameReset = - 1 ;
TriggerReset - > ExecuteBlock (
[ & ] ( int32 StartFrame , int32 EndFrame )
{
} ,
[ this ] ( int32 StartFrame , int32 EndFrame )
{
LastFrameReset = StartFrame ;
}
) ;
TriggerIn - > ExecuteBlock (
[ & ] ( int32 StartFrame , int32 EndFrame )
{
} ,
[ this ] ( int32 StartFrame , int32 EndFrame )
{
if ( StartFrame > LastFrameReset )
{
SamplesUntilTrigger = Delay - > GetNumSamples ( SampleRate ) ;
LastFrameReset = - 1 ;
}
else
{
SamplesUntilTrigger = - 1 ;
}
}
) ;
if ( SamplesUntilTrigger > = 0 )
2021-01-11 22:57:56 -04:00
{
int32 SamplesRemaining = SamplesUntilTrigger - FramesPerBlock ;
if ( SamplesRemaining > 0.0f )
{
SamplesUntilTrigger - = FramesPerBlock ;
}
else
{
2021-01-27 15:54:01 -04:00
TriggerOut - > TriggerFrame ( SamplesRemaining + ( int32 ) FramesPerBlock ) ;
2021-02-03 14:36:36 -04:00
SamplesUntilTrigger = - 1 ;
2021-01-11 22:57:56 -04:00
}
}
}
TUniquePtr < IOperator > FTriggerDelayOperator : : CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors )
{
const FTriggerDelayNode & DelayNode = static_cast < const FTriggerDelayNode & > ( InParams . Node ) ;
2021-02-03 15:40:56 -04:00
const FInputVertexInterface & InputInterface = GetVertexInterface ( ) . GetInputInterface ( ) ;
FFloatTimeReadRef Delay = InParams . InputDataReferences . GetDataReadReferenceOrConstructWithVertexDefault < FFloatTime , float > ( InputInterface , TEXT ( " Delay " ) ) ;
2021-01-11 22:57:56 -04:00
FTriggerReadRef TriggerIn = InParams . InputDataReferences . GetDataReadReferenceOrConstruct < FTrigger > ( TEXT ( " In " ) , InParams . OperatorSettings ) ;
FTriggerReadRef TriggerReset = InParams . InputDataReferences . GetDataReadReferenceOrConstruct < FTrigger > ( TEXT ( " Reset " ) , InParams . OperatorSettings ) ;
return MakeUnique < FTriggerDelayOperator > ( InParams . OperatorSettings , TriggerReset , TriggerIn , Delay ) ;
}
2021-02-03 15:40:56 -04:00
const FVertexInterface & FTriggerDelayOperator : : GetVertexInterface ( )
2021-01-11 22:57:56 -04:00
{
static const FVertexInterface Interface (
FInputVertexInterface (
2021-02-03 14:36:36 -04:00
TInputDataVertexModel < FFloatTime > ( TEXT ( " Delay " ) , LOCTEXT ( " TriggerDelayTooltip " , " Time to delay and execute deferred trigger in seconds. " ) , 1.0f ) ,
2021-01-11 22:57:56 -04:00
TInputDataVertexModel < FTrigger > ( TEXT ( " In " ) , LOCTEXT ( " TriggerDelayInTooltip " , " Triggers delay. " ) ) ,
TInputDataVertexModel < FTrigger > ( TEXT ( " Reset " ) , LOCTEXT ( " TriggerDelayResetInTooltip " , " Resets the trigger delay, clearing the execution task if pending. " ) )
) ,
FOutputVertexInterface (
TOutputDataVertexModel < FTrigger > ( TEXT ( " Out " ) , LOCTEXT ( " TriggerOutTooltip " , " The deferred output trigger " ) )
)
) ;
return Interface ;
}
2021-01-28 19:02:51 -04:00
const FNodeClassMetadata & FTriggerDelayOperator : : GetNodeInfo ( )
2021-01-11 22:57:56 -04:00
{
2021-01-28 19:02:51 -04:00
auto InitNodeInfo = [ ] ( ) - > FNodeClassMetadata
2021-01-11 22:57:56 -04:00
{
2021-01-28 19:02:51 -04:00
FNodeClassMetadata Info ;
Info . ClassName = { Metasound : : StandardNodes : : Namespace , TEXT ( " Trigger Delay " ) , TEXT ( " " ) } ;
2021-01-11 22:57:56 -04:00
Info . MajorVersion = 1 ;
Info . MinorVersion = 0 ;
2021-01-28 19:02:51 -04:00
Info . DisplayName = LOCTEXT ( " Metasound_TriggerDelayNodeDisplayName " , " Trigger Delay " ) ;
2021-01-11 22:57:56 -04:00
Info . Description = LOCTEXT ( " Metasound_TriggerDelayNodeDescription " , " Executes output trigger after the given delay time from the most recent execution of the input trigger . " ) ;
Info . Author = PluginAuthor ;
Info . PromptIfMissing = PluginNodeMissingPrompt ;
2021-02-03 15:40:56 -04:00
Info . DefaultInterface = GetVertexInterface ( ) ;
2021-01-11 22:57:56 -04:00
return Info ;
} ;
2021-01-28 19:02:51 -04:00
static const FNodeClassMetadata Info = InitNodeInfo ( ) ;
2021-01-11 22:57:56 -04:00
return Info ;
}
FTriggerDelayNode : : FTriggerDelayNode ( const FNodeInitData & InInitData )
2021-02-03 14:36:36 -04:00
: FNodeFacade ( InInitData . InstanceName , InInitData . InstanceID , TFacadeOperatorClass < FTriggerDelayOperator > ( ) )
2021-01-11 22:57:56 -04:00
{
}
}
# undef LOCTEXT_NAMESPACE // MetasoundTriggerDelayNode