2022-08-10 14:18:10 -04:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#include "MetasoundFrontendNodeTemplateRegistry.h"
|
|
|
|
|
|
|
|
|
|
#include "MetasoundFrontendDocument.h"
|
2024-08-13 14:58:36 -04:00
|
|
|
#include "MetasoundFrontendDocumentBuilder.h"
|
2023-12-15 13:21:12 -05:00
|
|
|
#include "MetasoundFrontendRegistryContainerImpl.h"
|
2022-08-10 14:18:10 -04:00
|
|
|
#include "MetasoundFrontendRegistryTransaction.h"
|
2024-03-07 17:53:25 -05:00
|
|
|
#include "MetasoundFrontendTransform.h"
|
2022-08-10 14:18:10 -04:00
|
|
|
#include "MetasoundLog.h"
|
|
|
|
|
#include "MetasoundTrace.h"
|
|
|
|
|
|
|
|
|
|
|
2023-09-07 11:11:22 -04:00
|
|
|
namespace Metasound::Frontend
|
2022-08-10 14:18:10 -04:00
|
|
|
{
|
2024-06-11 18:27:11 -04:00
|
|
|
#if WITH_EDITOR
|
|
|
|
|
FText INodeTemplate::ResolveMemberDisplayName(FName FullName, FText DisplayName, bool bIncludeNamespace)
|
|
|
|
|
{
|
|
|
|
|
FName Namespace;
|
|
|
|
|
FName ShortParamName;
|
|
|
|
|
Audio::FParameterPath::SplitName(FullName, Namespace, ShortParamName);
|
|
|
|
|
if (DisplayName.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
DisplayName = FText::FromName(ShortParamName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bIncludeNamespace && !Namespace.IsNone())
|
|
|
|
|
{
|
|
|
|
|
return FText::Format(NSLOCTEXT("MetasoundFrontend", "DisplayNameWithNamespaceFormat", "{0} ({1})"), DisplayName, FText::FromName(Namespace));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DisplayName;
|
|
|
|
|
}
|
|
|
|
|
#endif // WITH_EDITOR
|
|
|
|
|
|
2023-09-07 11:11:22 -04:00
|
|
|
class FNodeTemplateRegistry : public INodeTemplateRegistry
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
FNodeTemplateRegistry() = default;
|
|
|
|
|
virtual ~FNodeTemplateRegistry() = default;
|
|
|
|
|
|
|
|
|
|
virtual const INodeTemplate* FindTemplate(const FNodeRegistryKey& InKey) const override;
|
2024-03-07 17:53:25 -05:00
|
|
|
virtual const INodeTemplate* FindTemplate(const FMetasoundFrontendClassName& InClassName) const override;
|
2023-09-07 11:11:22 -04:00
|
|
|
|
|
|
|
|
void Register(TUniquePtr<INodeTemplate>&& InEntry);
|
|
|
|
|
void Unregister(const FNodeRegistryKey& InKey);
|
|
|
|
|
|
|
|
|
|
private:
|
2024-03-07 17:53:25 -05:00
|
|
|
TMap<FNodeRegistryKey, TUniquePtr<const INodeTemplate>> Templates;
|
|
|
|
|
TMultiMap<FMetasoundFrontendClassName, const INodeTemplate*> TemplateByClassName;
|
2023-09-07 11:11:22 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void FNodeTemplateRegistry::Register(TUniquePtr<INodeTemplate>&& InTemplate)
|
|
|
|
|
{
|
|
|
|
|
if (ensure(InTemplate.IsValid()))
|
2022-08-10 14:18:10 -04:00
|
|
|
{
|
2023-10-12 16:37:45 -04:00
|
|
|
const FNodeRegistryKey Key = FNodeRegistryKey(InTemplate->GetFrontendClass().Metadata);
|
|
|
|
|
if (ensure(Key.IsValid()))
|
2022-08-12 14:22:05 -04:00
|
|
|
{
|
2024-03-07 17:53:25 -05:00
|
|
|
TUniquePtr<const INodeTemplate>& Entry = Templates.Add(Key, MoveTemp(InTemplate));
|
|
|
|
|
TemplateByClassName.Add(Entry->GetFrontendClass().Metadata.GetClassName(), Entry.Get());
|
2022-08-12 14:22:05 -04:00
|
|
|
}
|
2022-08-10 14:18:10 -04:00
|
|
|
}
|
2023-09-07 11:11:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FNodeTemplateRegistry::Unregister(const FNodeRegistryKey& InKey)
|
|
|
|
|
{
|
2024-03-07 17:53:25 -05:00
|
|
|
TUniquePtr<const INodeTemplate> Removed;
|
|
|
|
|
if (ensure(Templates.RemoveAndCopyValue(InKey, Removed)))
|
|
|
|
|
{
|
|
|
|
|
ensure(TemplateByClassName.Remove(Removed->GetFrontendClass().Metadata.GetClassName()));
|
|
|
|
|
}
|
2023-09-07 11:11:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const INodeTemplate* FNodeTemplateRegistry::FindTemplate(const FNodeRegistryKey& InKey) const
|
|
|
|
|
{
|
- Fix for attempting to access EngineSubsystem during MetaSound versioning (serialization), which can assert when apparently certain commands in certain contexts can attempt to preload assets prior to the init phase.
- Minor Fix for LocText duplication
#tests BuildCookRun, -game, version MetaSounds assets in editor, PIE
[FYI] bob.tellez
Original CL Desc
-----------------------------------------------------------------
[Backout] - CL33084850
[FYI] Rob.Gay
Original CL Desc
-----------------------------------------------------------------
Version Metasound Document to include all ed data and make all Metasound EdGraph data transient
- Add input template nodes
- Add comment node data to document
- Keep references to member literal data (i.e. knob/slider ranges) in document metadata to ensure continued serialization and flexibility to add more editor-only fields and literal metadata
- Misc builder API updates, bug fixes and migration of controllers to builder API in anticipation of pages
- Sunset non-deterministic guid cvar
#rb phil.popp, helen.yang
[FYI] sondra.moyls
#tests Standard Automated Audio Tests, EngineTests, Offline QA Smoke pass, CPR, etc., extensive MetaSound Editor use, -game MetaSound qa levels, AudioUnitTests
#jira UE-194159
[CL 33102023 by rob gay in ue5-main branch]
2024-04-19 10:09:04 -04:00
|
|
|
if (const TUniquePtr<const INodeTemplate>* Template = Templates.Find(InKey))
|
2023-09-07 11:11:22 -04:00
|
|
|
{
|
- Fix for attempting to access EngineSubsystem during MetaSound versioning (serialization), which can assert when apparently certain commands in certain contexts can attempt to preload assets prior to the init phase.
- Minor Fix for LocText duplication
#tests BuildCookRun, -game, version MetaSounds assets in editor, PIE
[FYI] bob.tellez
Original CL Desc
-----------------------------------------------------------------
[Backout] - CL33084850
[FYI] Rob.Gay
Original CL Desc
-----------------------------------------------------------------
Version Metasound Document to include all ed data and make all Metasound EdGraph data transient
- Add input template nodes
- Add comment node data to document
- Keep references to member literal data (i.e. knob/slider ranges) in document metadata to ensure continued serialization and flexibility to add more editor-only fields and literal metadata
- Misc builder API updates, bug fixes and migration of controllers to builder API in anticipation of pages
- Sunset non-deterministic guid cvar
#rb phil.popp, helen.yang
[FYI] sondra.moyls
#tests Standard Automated Audio Tests, EngineTests, Offline QA Smoke pass, CPR, etc., extensive MetaSound Editor use, -game MetaSound qa levels, AudioUnitTests
#jira UE-194159
[CL 33102023 by rob gay in ue5-main branch]
2024-04-19 10:09:04 -04:00
|
|
|
return Template->Get();
|
2023-09-07 11:11:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-07 17:53:25 -05:00
|
|
|
const INodeTemplate* FNodeTemplateRegistry::FindTemplate(const FMetasoundFrontendClassName& InClassName) const
|
|
|
|
|
{
|
|
|
|
|
if (TemplateByClassName.Contains(InClassName))
|
|
|
|
|
{
|
|
|
|
|
TArray<const INodeTemplate*> FoundTemplates;
|
|
|
|
|
constexpr bool bMaintainOrder = false;
|
|
|
|
|
TemplateByClassName.MultiFind(InClassName, FoundTemplates, bMaintainOrder);
|
|
|
|
|
Algo::Sort(FoundTemplates, [](const INodeTemplate* A, const INodeTemplate* B) { return A->GetVersionNumber() < B->GetVersionNumber(); });
|
|
|
|
|
|
|
|
|
|
return FoundTemplates.Last();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-07 11:11:22 -04:00
|
|
|
INodeTemplateRegistry& INodeTemplateRegistry::Get()
|
|
|
|
|
{
|
|
|
|
|
static FNodeTemplateRegistry Registry;
|
|
|
|
|
return Registry;
|
|
|
|
|
}
|
|
|
|
|
|
- Fix for attempting to access EngineSubsystem during MetaSound versioning (serialization), which can assert when apparently certain commands in certain contexts can attempt to preload assets prior to the init phase.
- Minor Fix for LocText duplication
#tests BuildCookRun, -game, version MetaSounds assets in editor, PIE
[FYI] bob.tellez
Original CL Desc
-----------------------------------------------------------------
[Backout] - CL33084850
[FYI] Rob.Gay
Original CL Desc
-----------------------------------------------------------------
Version Metasound Document to include all ed data and make all Metasound EdGraph data transient
- Add input template nodes
- Add comment node data to document
- Keep references to member literal data (i.e. knob/slider ranges) in document metadata to ensure continued serialization and flexibility to add more editor-only fields and literal metadata
- Misc builder API updates, bug fixes and migration of controllers to builder API in anticipation of pages
- Sunset non-deterministic guid cvar
#rb phil.popp, helen.yang
[FYI] sondra.moyls
#tests Standard Automated Audio Tests, EngineTests, Offline QA Smoke pass, CPR, etc., extensive MetaSound Editor use, -game MetaSound qa levels, AudioUnitTests
#jira UE-194159
[CL 33102023 by rob gay in ue5-main branch]
2024-04-19 10:09:04 -04:00
|
|
|
TUniquePtr<INodeTransform> INodeTemplate::GenerateNodeTransform(FMetasoundFrontendDocument& InDocument) const
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-13 14:58:36 -04:00
|
|
|
const TArray<FMetasoundFrontendClassInputDefault>* FNodeTemplateBase::FindNodeClassInputDefaults(const FMetaSoundFrontendDocumentBuilder& InBuilder, const FGuid& InPageID, const FGuid& InNodeID, FName VertexName) const
|
|
|
|
|
{
|
|
|
|
|
if (const FMetasoundFrontendVertex* Vertex = InBuilder.FindNodeInput(InNodeID, VertexName, &InPageID))
|
|
|
|
|
{
|
|
|
|
|
const FMetasoundFrontendNode* Node = InBuilder.FindNode(InNodeID, &InPageID);
|
|
|
|
|
check(Node);
|
|
|
|
|
if (const FMetasoundFrontendClass* Class = InBuilder.FindDependency(Node->ClassID))
|
|
|
|
|
{
|
|
|
|
|
const EMetasoundFrontendClassType ClassType = Class->Metadata.GetType();
|
|
|
|
|
auto MatchesName = [&Vertex](const FMetasoundFrontendClassInput& Input) { return Input.Name == Vertex->Name; };
|
|
|
|
|
if (const FMetasoundFrontendClassInput* Input = Class->Interface.Inputs.FindByPredicate(MatchesName))
|
|
|
|
|
{
|
|
|
|
|
return &Input->GetDefaults();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-07 17:53:25 -05:00
|
|
|
#if WITH_EDITOR
|
2024-06-27 18:32:11 -04:00
|
|
|
FText FNodeTemplateBase::GetNodeDisplayName(const IMetaSoundDocumentInterface& Interface, const FGuid& InPageID, const FGuid& InNodeID) const
|
2024-03-07 17:53:25 -05:00
|
|
|
{
|
|
|
|
|
return { };
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-27 18:32:11 -04:00
|
|
|
FText FNodeTemplateBase::GetInputVertexDisplayName(const FMetaSoundFrontendDocumentBuilder& InBuilder, const FGuid& InPageID, const FGuid& InNodeID, FName InputName) const
|
2024-03-07 17:53:25 -05:00
|
|
|
{
|
2024-06-11 18:27:11 -04:00
|
|
|
return FText::FromName(InputName);
|
2024-03-07 17:53:25 -05:00
|
|
|
}
|
|
|
|
|
|
2024-06-27 18:32:11 -04:00
|
|
|
FText FNodeTemplateBase::GetOutputVertexDisplayName(const FMetaSoundFrontendDocumentBuilder& InBuilder, const FGuid& InPageID, const FGuid& InNodeID, FName OutputName) const
|
2024-03-07 17:53:25 -05:00
|
|
|
{
|
2024-06-11 18:27:11 -04:00
|
|
|
return FText::FromName(OutputName);
|
2024-03-07 17:53:25 -05:00
|
|
|
}
|
|
|
|
|
|
2024-06-27 18:32:11 -04:00
|
|
|
bool FNodeTemplateBase::HasRequiredConnections(const FMetaSoundFrontendDocumentBuilder& InBuilder, const FGuid& InPageID, const FGuid& InNodeID, FString* OutMessage) const
|
2024-03-07 17:53:25 -05:00
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#endif // WITH_EDITOR
|
|
|
|
|
|
2023-09-07 11:11:22 -04:00
|
|
|
void RegisterNodeTemplate(TUniquePtr<INodeTemplate>&& InTemplate)
|
|
|
|
|
{
|
|
|
|
|
class FTemplateRegistryEntry : public INodeRegistryTemplateEntry
|
|
|
|
|
{
|
|
|
|
|
const FNodeClassInfo ClassInfo;
|
|
|
|
|
const FMetasoundFrontendClass FrontendClass;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
FTemplateRegistryEntry(const INodeTemplate& InNodeTemplate)
|
|
|
|
|
: ClassInfo(InNodeTemplate.GetFrontendClass().Metadata)
|
|
|
|
|
, FrontendClass(InNodeTemplate.GetFrontendClass())
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual ~FTemplateRegistryEntry() = default;
|
|
|
|
|
|
|
|
|
|
virtual const FNodeClassInfo& GetClassInfo() const override
|
|
|
|
|
{
|
|
|
|
|
return ClassInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Return a FMetasoundFrontendClass which describes the node. */
|
|
|
|
|
virtual const FMetasoundFrontendClass& GetFrontendClass() const override
|
|
|
|
|
{
|
|
|
|
|
return FrontendClass;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TUniquePtr<INodeRegistryTemplateEntry> RegEntry = TUniquePtr<INodeRegistryTemplateEntry>(new FTemplateRegistryEntry(*InTemplate.Get()));
|
|
|
|
|
FRegistryContainerImpl::Get().RegisterNodeTemplate(MoveTemp(RegEntry));
|
|
|
|
|
|
|
|
|
|
static_cast<FNodeTemplateRegistry&>(INodeTemplateRegistry::Get()).Register(MoveTemp(InTemplate));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UnregisterNodeTemplate(const FMetasoundFrontendVersion& InVersion)
|
|
|
|
|
{
|
2023-10-12 16:37:45 -04:00
|
|
|
FMetasoundFrontendClassName ClassName;
|
|
|
|
|
FMetasoundFrontendClassName::Parse(InVersion.Name.ToString(), ClassName);
|
|
|
|
|
const FNodeRegistryKey Key = FNodeRegistryKey(EMetasoundFrontendClassType::Template, ClassName, InVersion.Number);
|
|
|
|
|
if (ensure(Key.IsValid()))
|
|
|
|
|
{
|
|
|
|
|
FRegistryContainerImpl::Get().UnregisterNodeTemplate(Key);
|
|
|
|
|
static_cast<FNodeTemplateRegistry&>(INodeTemplateRegistry::Get()).Unregister(Key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void UnregisterNodeTemplate(const FMetasoundFrontendClassName& InClassName, const FMetasoundFrontendVersionNumber& InTemplateVersion)
|
|
|
|
|
{
|
|
|
|
|
const FNodeRegistryKey Key = FNodeRegistryKey(EMetasoundFrontendClassType::Template, InClassName, InTemplateVersion);
|
|
|
|
|
if (ensure(Key.IsValid()))
|
2023-09-07 11:11:22 -04:00
|
|
|
{
|
|
|
|
|
FRegistryContainerImpl::Get().UnregisterNodeTemplate(Key);
|
|
|
|
|
static_cast<FNodeTemplateRegistry&>(INodeTemplateRegistry::Get()).Unregister(Key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} // namespace Metasound::Frontend
|