Files
UnrealEngineUWP/Engine/Plugins/Runtime/Metasound/Source/MetasoundFrontend/Private/MetasoundFrontendQuerySteps.cpp
phil popp 39239bef3a Updates to Metasound Frontend Query system.
- Simplified and removed a bunch of code.
- Reworked queries to include the concept of a "Partition" mapped to a Key
- Added more unit tests to ensure it works correctly.
- Fixed some bugs around incremental updates.

#rb Rob.Gay
#jira UE-132803
#preflight 61af81f4b12ed605818b24c3

#ROBOMERGE-AUTHOR: phil.popp
#ROBOMERGE-SOURCE: CL 18400273 in //UE5/Release-5.0/... via CL 18400298
#ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v896-18170469)

[CL 18400305 by phil popp in ue5-release-engine-test branch]
2021-12-07 16:32:38 -05:00

189 lines
5.5 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MetasoundFrontendQuerySteps.h"
#include "CoreMinimal.h"
#include "MetasoundFrontend.h"
#include "MetasoundFrontendDocument.h"
#include "MetasoundFrontendRegistryTransaction.h"
namespace Metasound
{
FNodeClassRegistrationEvents::FNodeClassRegistrationEvents()
: CurrentTransactionID(Frontend::GetOriginRegistryTransactionID())
{
}
void FNodeClassRegistrationEvents::Stream(TArray<FFrontendQueryValue>& OutValues)
{
using namespace Frontend;
auto AddEntry = [&OutValues](const FNodeRegistryTransaction& InTransaction)
{
OutValues.Emplace(TInPlaceType<FNodeRegistryTransaction>(), InTransaction);
};
if (FMetasoundFrontendRegistryContainer* Registry = FMetasoundFrontendRegistryContainer::Get())
{
Registry->ForEachNodeRegistryTransactionSince(CurrentTransactionID, &CurrentTransactionID, AddEntry);
}
}
FFrontendQueryKey FMapRegistrationEventsToNodeRegistryKeys::Map(const FFrontendQueryEntry& InEntry) const
{
using namespace Frontend;
FNodeRegistryKey RegistryKey;
if (ensure(InEntry.Value.IsType<FNodeRegistryTransaction>()))
{
RegistryKey = InEntry.Value.Get<FNodeRegistryTransaction>().GetNodeRegistryKey();
}
return FFrontendQueryKey(RegistryKey);
}
void FReduceRegistrationEventsToCurrentStatus::Reduce(const FFrontendQueryKey& InKey, FFrontendQueryPartition& InOutEntries) const
{
using namespace Frontend;
int32 State = 0;
FFrontendQueryEntry* FinalEntry = nullptr;
for (FFrontendQueryEntry& Entry : InOutEntries)
{
if (ensure(Entry.Value.IsType<FNodeRegistryTransaction>()))
{
const FNodeRegistryTransaction& Transaction = Entry.Value.Get<FNodeRegistryTransaction>();
switch (Transaction.GetTransactionType())
{
case FNodeRegistryTransaction::ETransactionType::NodeRegistration:
State++;
FinalEntry = &Entry;
break;
case FNodeRegistryTransaction::ETransactionType::NodeUnregistration:
State--;
break;
default:
break;
}
}
}
if ((nullptr != FinalEntry) && (State > 0))
{
FFrontendQueryEntry Entry = *FinalEntry;
InOutEntries.Reset();
InOutEntries.Add(Entry);
}
else
{
InOutEntries.Reset();
}
}
void FTransformRegistrationEventsToClasses::Transform(FFrontendQueryEntry::FValue& InValue) const
{
using namespace Frontend;
FMetasoundFrontendClass FrontendClass;
if (ensure(InValue.IsType<FNodeRegistryTransaction>()))
{
const FNodeRegistryTransaction& Transaction = InValue.Get<FNodeRegistryTransaction>();
bool bSuccess = FMetasoundFrontendRegistryContainer::Get()->FindFrontendClassFromRegistered(Transaction.GetNodeRegistryKey(), FrontendClass);
check(bSuccess);
}
InValue.Set<FMetasoundFrontendClass>(MoveTemp(FrontendClass));
}
FFilterClassesByInputVertexDataType::FFilterClassesByInputVertexDataType(const FName& InTypeName)
: InputVertexTypeName(InTypeName)
{
}
bool FFilterClassesByInputVertexDataType::Filter(const FFrontendQueryEntry& InEntry) const
{
check(InEntry.Value.IsType<FMetasoundFrontendClass>());
return InEntry.Value.Get<FMetasoundFrontendClass>().Interface.Inputs.ContainsByPredicate(
[this](const FMetasoundFrontendClassInput& InDesc)
{
return InDesc.TypeName == InputVertexTypeName;
}
);
}
FFilterClassesByOutputVertexDataType::FFilterClassesByOutputVertexDataType(const FName& InTypeName)
: OutputVertexTypeName(InTypeName)
{
}
bool FFilterClassesByOutputVertexDataType::Filter(const FFrontendQueryEntry& InEntry) const
{
return InEntry.Value.Get<FMetasoundFrontendClass>().Interface.Outputs.ContainsByPredicate(
[this](const FMetasoundFrontendClassOutput& InDesc)
{
return InDesc.TypeName == OutputVertexTypeName;
}
);
}
FFrontendQueryKey FMapClassesToClassName::Map(const FFrontendQueryEntry& InEntry) const
{
return FFrontendQueryKey(InEntry.Value.Get<FMetasoundFrontendClass>().Metadata.GetClassName().GetFullName());
}
FFilterClassesByClassID::FFilterClassesByClassID(const FGuid InClassID)
: ClassID(InClassID)
{
}
bool FFilterClassesByClassID::Filter(const FFrontendQueryEntry& InEntry) const
{
return InEntry.Value.Get<FMetasoundFrontendClass>().ID == ClassID;
}
FFrontendQueryKey FMapToFullClassName::Map(const FFrontendQueryEntry& InEntry) const
{
const FMetasoundFrontendClass& FrontendClass = InEntry.Value.Get<FMetasoundFrontendClass>();
return FFrontendQueryKey(FrontendClass.Metadata.GetClassName().GetFullName());
}
void FReduceClassesToHighestVersion::Reduce(const FFrontendQueryKey& InKey, FFrontendQueryPartition& InOutEntries) const
{
FFrontendQueryEntry* HighestVersionEntry = nullptr;
FMetasoundFrontendVersionNumber HighestVersion;
for (FFrontendQueryEntry& Entry : InOutEntries)
{
const FMetasoundFrontendVersionNumber& Version = Entry.Value.Get<FMetasoundFrontendClass>().Metadata.GetVersion();
if (!HighestVersionEntry || HighestVersion < Version)
{
HighestVersionEntry = &Entry;
HighestVersion = Version;
}
}
if (HighestVersionEntry)
{
FFrontendQueryEntry Entry = *HighestVersionEntry;
InOutEntries.Reset();
InOutEntries.Add(Entry);
}
}
bool FSortClassesByVersion::Sort(const FFrontendQueryEntry& InEntryLHS, const FFrontendQueryEntry& InEntryRHS) const
{
const FMetasoundFrontendVersionNumber& VersionLHS = InEntryLHS.Value.Get<FMetasoundFrontendClass>().Metadata.GetVersion();
const FMetasoundFrontendVersionNumber& VersionRHS = InEntryRHS.Value.Get<FMetasoundFrontendClass>().Metadata.GetVersion();
return VersionLHS > VersionRHS;
}
}