Files
UnrealEngineUWP/Engine/Plugins/Runtime/Metasound/Source/MetasoundFrontend/Public/MetasoundSendNode.h
rob gay e26ac0345b - Migrate MetaSound InputLiterals to DefaultLiterals housed on FrontendNodes
- Add FrontendGraphBuilder support for generating VariableNodes for DefaultLiterals if no connection is provided on External/Output nodes
- Move node names to be guids (they're never seen by the user and this will be easier to migrate later)
- Fix DisplayName logic to be unique against one another SEPARATELY from node name logic
- Fix for MetaSounds not compiling if trigger outputs do not have input connected
- MetaSound Document Transform Support
- Fix for for MetaSound Generators not stopping source if failed to create generator due to build errors
#rb phil.popp
#jira UE-112951
#jira UE-116172
#jira UE-116174
#jira UE-116176
#jira UE-116178
#preflight 60b11e7b7e4e6a0001b81c21
#preflight 60b1292d072a1d000164b470

#ROBOMERGE-SOURCE: CL 16502735 in //UE5/Private-Frosty/...
#ROBOMERGE-BOT: STARSHIP (Private-Frosty -> Main) (v826-16501804)

[CL 16502750 by rob gay in ue5-main branch]
2021-05-28 14:09:45 -04:00

194 lines
5.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "MetasoundBuilderInterface.h"
#include "MetasoundNode.h"
#include "MetasoundNodeInterface.h"
#include "MetasoundOperatorInterface.h"
#include "MetasoundDataReference.h"
#include "MetasoundExecutableOperator.h"
#include "MetasoundRouter.h"
#include <type_traits>
#define LOCTEXT_NAMESPACE "MetasoundFrontend"
namespace Metasound
{
template<typename TDataType>
class TSendNode : public FNode
{
public:
static const FString& GetAddressInputName()
{
static const FString InputName = TEXT("Address");
return InputName;
}
static const FString& GetSendInputName()
{
static const FString& SendInput = GetMetasoundDataTypeString<TDataType>();
return SendInput;
}
static FVertexInterface DeclareVertexInterface()
{
return FVertexInterface(
FInputVertexInterface(
TInputDataVertexModel<FSendAddress>(GetAddressInputName(), FText::GetEmpty()),
TInputDataVertexModel<TDataType>(GetSendInputName(), FText::GetEmpty())
),
FOutputVertexInterface(
)
);
}
static const FNodeClassMetadata& GetNodeInfo()
{
auto InitNodeInfo = []() -> FNodeClassMetadata
{
const FString& InputName = GetSendInputName();
FNodeClassMetadata Info;
Info.ClassName = {TEXT("Send"), GetMetasoundDataTypeName<TDataType>(), TEXT("")};
Info.MajorVersion = 1;
Info.MinorVersion = 0;
Info.DisplayName = FText::Format(LOCTEXT("Metasound_SendNodeDisplayNameFormat", "Send {0}"), FText::FromName(GetMetasoundDataTypeName<TDataType>()));
Info.Description = LOCTEXT("Metasound_SendNodeDescription", "Sends data from a send node with the same name.");
Info.Author = PluginAuthor;
Info.PromptIfMissing = PluginNodeMissingPrompt;
Info.DefaultInterface = DeclareVertexInterface();
Info.CategoryHierarchy = { LOCTEXT("Metasound_TransmissionNodeCategory", "Transmission") };
Info.Keywords = { "Send", GetMetasoundDataTypeName<TDataType>()};
return Info;
};
static const FNodeClassMetadata Info = InitNodeInfo();
return Info;
}
private:
class TSendOperator : public TExecutableOperator<TSendOperator>
{
public:
TSendOperator(TDataReadReference<TDataType> InInputData, TDataReadReference<FSendAddress> InSendAddress, const FOperatorSettings& InOperatorSettings)
: InputData(InInputData)
, SendAddress(InSendAddress)
, CachedSendAddress(*InSendAddress)
, CachedSenderParams({InOperatorSettings, 0.0f})
, Sender(FDataTransmissionCenter::Get().RegisterNewSender<TDataType>(CachedSendAddress, CachedSenderParams))
{
}
virtual ~TSendOperator()
{
ResetSenderAndCleanupChannel();
}
virtual FDataReferenceCollection GetInputs() const override
{
FDataReferenceCollection Inputs;
Inputs.AddDataReadReference<FSendAddress>(GetAddressInputName(), SendAddress);
Inputs.AddDataReadReference<TDataType>(GetSendInputName(), TDataReadReference<TDataType>(InputData));
return Inputs;
}
virtual FDataReferenceCollection GetOutputs() const override
{
return {};
}
void Execute()
{
if (SendAddress->ChannelName != CachedSendAddress.ChannelName)
{
ResetSenderAndCleanupChannel();
CachedSendAddress = *SendAddress;
Sender = FDataTransmissionCenter::Get().RegisterNewSender<TDataType>(CachedSendAddress, CachedSenderParams);
check(Sender.IsValid());
}
Sender->Push(*InputData);
}
private:
void ResetSenderAndCleanupChannel()
{
Sender.Reset();
FDataTransmissionCenter::Get().UnregisterDataChannelIfUnconnected(GetMetasoundDataTypeName<TDataType>(), CachedSendAddress);
}
TDataReadReference<TDataType> InputData;
TDataReadReference<FSendAddress> SendAddress;
FSendAddress CachedSendAddress;
FSenderInitParams CachedSenderParams;
TSenderPtr<TDataType> Sender;
};
class FSendOperatorFactory : public IOperatorFactory
{
public:
FSendOperatorFactory() = default;
virtual TUniquePtr<IOperator> CreateOperator(const FCreateOperatorParams& InParams, FBuildErrorArray& OutErrors) override
{
if (InParams.InputDataReferences.ContainsDataReadReference<TDataType>(GetSendInputName()))
{
return MakeUnique<TSendOperator>(InParams.InputDataReferences.GetDataReadReference<TDataType>(GetSendInputName()),
InParams.InputDataReferences.GetDataReadReferenceOrConstruct<FSendAddress>(GetAddressInputName()),
InParams.OperatorSettings
);
}
else
{
// No input hook up to send, so this node can no-op
return MakeUnique<FNoOpOperator>();
}
}
};
public:
TSendNode(const FNodeInitData& InInitData)
: FNode(InInitData.InstanceName, InInitData.InstanceID, GetNodeInfo())
, Interface(DeclareVertexInterface())
, Factory(MakeOperatorFactoryRef<FSendOperatorFactory>())
{
}
virtual ~TSendNode() = default;
virtual const FVertexInterface& GetVertexInterface() const override
{
return Interface;
}
virtual bool SetVertexInterface(const FVertexInterface& InInterface) override
{
return Interface == InInterface;
}
virtual bool IsVertexInterfaceSupported(const FVertexInterface& InInterface) const override
{
return Interface == InInterface;
}
virtual FOperatorFactorySharedRef GetDefaultOperatorFactory() const override
{
return Factory;
}
private:
FVertexInterface Interface;
FOperatorFactorySharedRef Factory;
};
}
#undef LOCTEXT_NAMESPACE