InputKeys

InputKeys

#Overview

name: InputKeys

The value of this variable can be defined or overridden in .ini config files. 7 .ini config files referencing this setting variable.

It is referenced in 48 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of InputKeys is to store and manage key details for input in Unreal Engine 5. It is part of the input system and serves as a central repository for information about various input keys.

This variable is primarily used by the InputCore module, which is a core component of Unreal Engine’s input system. It’s also utilized by other subsystems that interact with input, such as the gameplay framework and UI system.

The value of InputKeys is set and modified through various functions in the EKeys class, such as AddKey(), AddPairedKey(), and RemoveKeysWithCategory(). These functions allow for dynamic manipulation of the available input keys.

InputKeys interacts closely with the FKey and FKeyDetails structures. It stores FKeyDetails objects indexed by FKey objects, allowing for quick lookup of key information.

Developers should be aware that InputKeys is a static member of the EKeys class, meaning it’s shared across the entire application. Modifying it will affect the input system globally.

Best practices when using this variable include:

  1. Initializing it properly before use (check EKeys::bInitialized).
  2. Using the provided EKeys functions to modify it rather than accessing it directly.
  3. Being cautious when adding or removing keys, as it can affect input handling throughout the engine.
  4. Considering performance implications when frequently accessing or modifying this container in performance-critical code.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/Localization/Category.ini:37, section: [GatherTextStep0]

Location: <Workspace>/Engine/Config/Localization/Editor.ini:78, section: [GatherTextStep2]

Location: <Workspace>/Engine/Config/Localization/Editor.ini:81, section: [GatherTextStep2]

Location: <Workspace>/Engine/Config/Localization/Keywords.ini:32, section: [GatherTextStep0]

Location: <Workspace>/Engine/Config/Localization/PropertyNames.ini:37, section: [GatherTextStep0]

Location: <Workspace>/Engine/Config/Localization/ToolTips.ini:37, section: [GatherTextStep0]

Location: <Workspace>/Engine/Config/Localization/ToolTips.ini:40, section: [GatherTextStep0]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/Metadata/PCGMetadataOpElementBase.cpp:302

Scope (from outer to inner):

file
namespace    PCGMetadataOpPrivate
function     void CreateAccessor

Source code excerpt:


		OperationData.InputAccessors[Index] = PCGAttributeAccessorHelpers::CreateConstAccessor(InputData.Data, InputSource);
		OperationData.InputKeys[Index] = PCGAttributeAccessorHelpers::CreateConstKeys(InputData.Data, InputSource);
	}

	bool ValidateAccessor(const FPCGContext* Context, const UPCGMetadataSettingsBase* Settings, const FPCGTaggedData& InputData, PCGMetadataOps::FOperationData& OperationData, int32 Index)
	{
		const FPCGAttributePropertyInputSelector& InputSource = OperationData.InputSources[Index];
		const FText InputSourceText = InputSource.GetDisplayText();

		if (!OperationData.InputAccessors[Index].IsValid() || !OperationData.InputKeys[Index].IsValid())
		{
			PCGE_LOG_C(Error, GraphAndLog, Context, FText::Format(LOCTEXT("AttributeDoesNotExist", "Attribute/Property '{0}' from pin {1} does not exist"), InputSourceText, FText::FromName(InputData.Pin)));
			return false;
		}

		const uint16 AttributeTypeId = OperationData.InputAccessors[Index]->GetUnderlyingType();

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/Metadata/PCGMetadataOpElementBase.cpp:504

Scope (from outer to inner):

file
function     bool FPCGMetadataElementBase::PrepareDataInternal
lambda-function

Source code excerpt:

		OperationData.Settings = Settings;
		OperationData.InputAccessors.SetNum(OperandNum);
		OperationData.InputKeys.SetNum(OperandNum);
		OperationData.InputSources.SetNum(OperandNum);
		OperationData.MostComplexInputType = static_cast<uint16>(EPCGMetadataTypes::Unknown);

		const FPCGTaggedData& PrimaryPinData = InputTaggedData[PrimaryPinIndex];

		// First create an accessor for the input to forward (it's our control data)

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/Metadata/PCGMetadataOpElementBase.cpp:518

Scope (from outer to inner):

file
function     bool FPCGMetadataElementBase::PrepareDataInternal
lambda-function

Source code excerpt:


		// Update the number of elements to process
		OperationData.NumberOfElementsToProcess = OperationData.InputKeys[PrimaryPinIndex]->GetNum();
		if (OperationData.NumberOfElementsToProcess == 0)
		{
			PCGE_LOG(Verbose, LogOnly, FText::Format(LOCTEXT("NoElementsInForwardedInput", "No elements in data from forwarded pin '{0}'."), FText::FromName(PrimaryPinData.Pin)));
			return EPCGTimeSliceInitResult::NoOperation;
		}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/Metadata/PCGMetadataOpElementBase.cpp:544

Scope (from outer to inner):

file
function     bool FPCGMetadataElementBase::PrepareDataInternal
lambda-function

Source code excerpt:

				}

				const int32 ElementNum = OperationData.InputKeys[Index]->GetNum();

				// No elements on secondary pin, early out for no operation
				if (ElementNum == 0)
				{
					PCGE_LOG(Verbose, LogOnly, FText::Format(LOCTEXT("NoElementsInInput", "No elements in data from secondary pin '{0}'."), FText::FromName(PrimaryPinData.Pin)));
					return EPCGTimeSliceInitResult::NoOperation;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGAttributeNoise.cpp:304

Scope (from outer to inner):

file
function     bool FPCGAttributeNoiseElement::ExecuteInternal

Source code excerpt:

			// Then create the accessor/keys
			Context->InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(InputData, Context->InputSource);
			Context->InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(InputData, Context->InputSource);

			// It won't fail because we validated on the input data and output is initialized from input.
			check(Context->InputAccessor && Context->InputKeys);

			Context->OutputTarget = Settings->OutputTarget.CopyAndFixSource(&Context->InputSource, Input.Data);

			Context->OutputAccessor = PCGAttributeAccessorHelpers::CreateAccessor(OutputData, Context->OutputTarget);
			if (!Context->OutputAccessor && Context->OutputTarget.IsBasicAttribute())
			{

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGAttributeNoise.cpp:360

Scope (from outer to inner):

file
function     bool FPCGAttributeNoiseElement::ExecuteInternal
lambda-function

Source code excerpt:

			using AttributeType = std::decay_t<decltype(Dummy)>;
			constexpr int32 ChunkSize = 64;
			const int32 NumIterations = Context->InputKeys->GetNum();

			// No init
			auto Initialize = []() {};
			// It's a 1 for 1 operation, should never move
			auto MoveDataRange = [](int32, int32, int32) { ensure(false); };
			// It's finished if we processed all elements.

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGAttributeNoise.cpp:374

Scope (from outer to inner):

file
lambda-function
lambda-function

Source code excerpt:

				Values.SetNumUninitialized(Count);

				if (Context->InputAccessor->GetRange<AttributeType>(Values, StartReadIndex, *Context->InputKeys))
				{
					for (int32 i = 0; i < Count; ++i)
					{
						// Use the point seed if we have points, otherwise the index. Don't start at 0 (that's why there is a +1)
						// Warning: It makes it order independant for points, but order dependant for the rest.
						const int32 ElementSeed = InputPoints ? (*InputPoints)[StartReadIndex + i].Seed : StartReadIndex + i + 1;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGAttributeTransferElement.cpp:259

Scope (from outer to inner):

file
function     bool FPCGAttributeTransferElement::ExecuteInternal

Source code excerpt:


	TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(SourceData, SourceAttributeProperty);
	TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(SourceData, SourceAttributeProperty);

	if (!InputAccessor.IsValid() || !InputKeys.IsValid())
	{
		PCGE_LOG(Error, GraphAndLog, LOCTEXT("FailedToCreateInputAccessor", "Failed to create input accessor or iterator"));
		return true;
	}

	// If the target is an attribute, only create a new one if the attribute doesn't already exist or we have any extra.

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGAttributeTransferElement.cpp:300

Scope (from outer to inner):

file
function     bool FPCGAttributeTransferElement::ExecuteInternal
lambda-function

Source code excerpt:


	// At this point, we are ready.
	auto Operation = [&InputAccessor, &InputKeys, &OutputAccessor, &OutputKeys, Context](auto Dummy)
	{
		using OutputType = decltype(Dummy);
		OutputType Value{};

		EPCGAttributeAccessorFlags Flags = EPCGAttributeAccessorFlags::AllowBroadcast | EPCGAttributeAccessorFlags::AllowConstructible;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGAttributeTransferElement.cpp:321

Scope (from outer to inner):

file
function     bool FPCGAttributeTransferElement::ExecuteInternal
lambda-function

Source code excerpt:

			TArrayView<OutputType> View(TempValues.GetData(), Range);

			if (!InputAccessor->GetRange<OutputType>(View, StartIndex, *InputKeys, Flags)
				|| !OutputAccessor->SetRange<OutputType>(View, StartIndex, *OutputKeys, Flags))
			{
				PCGE_LOG_C(Error, GraphAndLog, Context, LOCTEXT("ConversionFailed", "Source attribute/property cannot be converted to target attribute/property"));
				return false;
			}
		}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGMatchAndSetAttributes.cpp:353

Scope (from outer to inner):

file
class        class FPCGAttributeSetPartition
function     TArray<int32> GetMatchingPartitionDataIndices

Source code excerpt:

	bool IsValid() const { return bIsValid; }

	TArray<int32> GetMatchingPartitionDataIndices(const TUniquePtr<const IPCGAttributeAccessor>& InputAttribute, const TUniquePtr<const IPCGAttributeAccessorKeys>& InputKeys, int32 PointsNum) const
	{
		TArray<int32> MatchingPartitionDataIndices;

		if (InputAttribute && Attribute)
		{
			check(InputKeys.IsValid() && InputKeys->GetNum() == PointsNum);
			auto FindMatchingValueKeyIndex = [this, &InputAttribute, &InputKeys, &MatchingPartitionDataIndices](auto AttributeDummyValue) -> bool
			{
				using AttributeType = decltype(AttributeDummyValue);

				// Get threshold value if we need it.
				void* ThresholdValuesPtr = nullptr;
				int ConstKeyCount = ConstantKey.IsValid() ? FMath::Max(1, ConstantKey->GetNum()) : 0;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGMatchAndSetAttributes.cpp:403

Scope (from outer to inner):

file
class        class FPCGAttributeSetPartition
function     TArray<int32> GetMatchingPartitionDataIndices
lambda-function

Source code excerpt:

				}

				bool bApplyOk = PCGMetadataElementCommon::ApplyOnAccessor<AttributeType>(*InputKeys, *InputAttribute, [this, &AttributeValues, &MatchingPartitionDataIndices, ThresholdValuesPtr, ConstKeyCount](const AttributeType& InValue, int32 InIndex)
				{
					int32 MatchingPartitionDataIndex = INDEX_NONE;
					bool bFoundEqualMatch = false;
					for (int32 AttributeValueIndex = 0; AttributeValueIndex < AttributeValues.Num(); ++AttributeValueIndex)
					{
						if (PCG::Private::MetadataTraits<AttributeType>::Equal(InValue, AttributeValues[AttributeValueIndex]))

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGMatchAndSetAttributes.cpp:468

Scope (from outer to inner):

file
class        class FPCGAttributeSetPartition
function     TArray<int32> GetMatchingPartitionDataIndices

Source code excerpt:

			{
				// Attribute isn't able to retrieve & compare - reset values
				MatchingPartitionDataIndices.Init(INDEX_NONE, InputKeys->GetNum());
			}
		}
		else if (!PartitionData.IsEmpty())
		{
			// There is only one entry
			MatchingPartitionDataIndices.Init(0, PointsNum);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGSampleTexture.cpp:68

Scope (from outer to inner):

file
function     bool FPCGSampleTextureElement::ExecuteInternal

Source code excerpt:


		TUniquePtr<const IPCGAttributeAccessor> InputAccessor = nullptr;
		TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = nullptr;

		if (Settings->TextureMappingMethod == EPCGTextureMappingMethod::UVCoordinates)
		{
			const FPCGAttributePropertyInputSelector UVSource = Settings->UVCoordinatesAttribute.CopyAndFixLast(PointData);
	
			InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(PointData, UVSource);
			InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(PointData, UVSource);
			if (!InputAccessor || !InputKeys)
			{
				PCGE_LOG(Warning, GraphAndLog, FText::Format(LOCTEXT("InvalidUVAccessor", "Could not create coordinate accessor {0} for Point Input {1}."), FText::FromName(UVSource.GetName()), i));
				continue;
			}

			if (!PCG::Private::IsOfTypes<FVector, FVector2D>(InputAccessor->GetUnderlyingType()))

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Elements/PCGSampleTexture.cpp:92

Scope (from outer to inner):

file
function     bool FPCGSampleTextureElement::ExecuteInternal
lambda-function

Source code excerpt:

		OutPointData->InitializeFromData(PointData);

		auto ProcessPoint = [Settings, BaseTextureData, &InputAccessor, &InputKeys, &InputPoints, OutPointData](int32 Index, FPCGPoint& OutPoint)
		{
			OutPoint = InputPoints[Index];

			if (Settings->TextureMappingMethod == EPCGTextureMappingMethod::UVCoordinates)
			{
				FVector OutSamplePosition;
				InputAccessor->Get(OutSamplePosition, Index, *InputKeys, EPCGAttributeAccessorFlags::AllowBroadcast | EPCGAttributeAccessorFlags::AllowConstructible);

				if (Settings->TilingMode == EPCGTextureAddressMode::Clamp)
				{
					OutSamplePosition.X = FMath::Clamp(OutSamplePosition.X, 0.0, 1.0);
					OutSamplePosition.Y = FMath::Clamp(OutSamplePosition.Y, 0.0, 1.0);
				}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Helpers/PCGMetadataHelpers.cpp:176

Scope (from outer to inner):

file
namespace    PCGMetadataHelpers
function     bool CopyAttributes

Source code excerpt:

			{
				TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(SourceData, InputSource);
				TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(SourceData, InputSource);

				if (!InputAccessor.IsValid() || !InputKeys.IsValid())
				{
					PCGLog::LogWarningOnGraph(LOCTEXT("FailedToCreateInputAccessor", "Failed to create input accessor or iterator"), OptionalContext);
					continue;
				}

				const uint16 OutputType = bOutputTypeCast ? static_cast<uint16>(RequestedOutputType) : InputAccessor->GetUnderlyingType();

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Helpers/PCGMetadataHelpers.cpp:247

Scope (from outer to inner):

file
namespace    PCGMetadataHelpers
function     bool CopyAttributes

Source code excerpt:

				// At this point, we are ready.
				PCGMetadataElementCommon::FCopyFromAccessorToAccessorParams Params;
				Params.InKeys = InputKeys.Get();
				Params.InAccessor = InputAccessor.Get();
				Params.OutKeys = OutputKeys.Get();
				Params.OutAccessor = OutputAccessor.Get();
				Params.IterationCount = PCGMetadataElementCommon::FCopyFromAccessorToAccessorParams::Out;
				Params.Flags = EPCGAttributeAccessorFlags::AllowBroadcast | EPCGAttributeAccessorFlags::AllowConstructible;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/MatchAndSet/PCGMatchAndSetByAttribute.cpp:145

Scope (from outer to inner):

file
function     void UPCGMatchAndSetByAttribute::MatchAndSet_Implementation

Source code excerpt:

	//TODO: implement async loop?
	TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(InPointData, InputSource);
	TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(InPointData, InputSource);

	if (!InputAccessor.IsValid() || !InputKeys.IsValid())
	{
		PCGE_LOG_C(Warning, GraphAndLog, &Context, LOCTEXT("InputAccessorCreationFailed", "Failed to create input accessor or iterator in MatchAndSet"));
		return;
	}

	// TODO: this should be more complex type - see what's done in the compare element

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/MatchAndSet/PCGMatchAndSetByAttribute.cpp:169

Scope (from outer to inner):

file
function     void UPCGMatchAndSetByAttribute::MatchAndSet_Implementation
lambda-function

Source code excerpt:

	}

	auto MatchAndSetOperation = [&InputAccessor, &InputKeys, &EntryMatchSourceAccessors, &EntrySetValueAccessors, &EntryKeys, &SetTargetAccessor, &SetTargetKeys](auto MatchDummy)
	{
		using MatchType = decltype(MatchDummy);
		auto GetValueIndex = [&InputAccessor, &InputKeys, &EntryMatchSourceAccessors, &EntryKeys](int32 Index) -> int32
		{
			MatchType Value{};
			EPCGAttributeAccessorFlags Flags = EPCGAttributeAccessorFlags::AllowBroadcast;

			InputAccessor->Get<MatchType>(Value, Index, *InputKeys, Flags);

			for (int32 SourceIndex = 0; SourceIndex < EntryMatchSourceAccessors.Num(); ++SourceIndex)
			{
				MatchType SourceValue{};
				EntryMatchSourceAccessors[SourceIndex]->Get<MatchType>(SourceValue, *EntryKeys, Flags);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/MatchAndSet/PCGMatchAndSetWeightedByCategory.cpp:204

Scope (from outer to inner):

file
function     void UPCGMatchAndSetWeightedByCategory::MatchAndSet_Implementation

Source code excerpt:


	TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(InPointData, InputSource);
	TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(InPointData, InputSource);

	if (!InputAccessor.IsValid() || !InputKeys.IsValid())
	{
		PCGE_LOG_C(Warning, GraphAndLog, &Context, LOCTEXT("InputAccessorFailed", "Failed to create input accessor or iterator in MatchAndSet"));
		return;
	}

	TUniquePtr<IPCGAttributeAccessor> SetTargetAccessor = PCGAttributeAccessorHelpers::CreateAccessor(OutPointData, SetTarget);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/MatchAndSet/PCGMatchAndSetWeightedByCategory.cpp:252

Scope (from outer to inner):

file
function     void UPCGMatchAndSetWeightedByCategory::MatchAndSet_Implementation
lambda-function

Source code excerpt:

	};

	auto MatchAndSetOperation = [&GetValueIndex, &InputAccessor, &InputKeys, &EntryCategoryAccessors, &EntryValueAccessors, &EntryKeys, DefaultCategoryIndex, &SetTargetAccessor, &SetTargetKeys](auto MatchDummy)
	{
		using MatchType = decltype(MatchDummy);
		auto GetCategoryIndex = [&InputAccessor, &InputKeys, &EntryCategoryAccessors, &EntryKeys, DefaultCategoryIndex](int32 Index) -> int32
		{
			EPCGAttributeAccessorFlags Flags = EPCGAttributeAccessorFlags::AllowBroadcast;

			MatchType Value{};
			InputAccessor->Get<MatchType>(Value, Index, *InputKeys, Flags);

			for (int32 CategoryIndex = 0; CategoryIndex < EntryCategoryAccessors.Num(); ++CategoryIndex)
			{
				MatchType SourceValue{};
				EntryCategoryAccessors[CategoryIndex]->Get<MatchType>(SourceValue, *EntryKeys, Flags);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Metadata/PCGObjectPropertyOverride.cpp:58

Scope (from outer to inner):

file
function     void FPCGObjectSingleOverride::Initialize

Source code excerpt:

void FPCGObjectSingleOverride::Initialize(const FPCGAttributePropertySelector& InputSelector, const FString& OutputProperty, const UStruct* TemplateClass, const UPCGData* SourceData, FPCGContext* Context)
{
	InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(SourceData, InputSelector);
	ObjectOverrideInputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(SourceData, InputSelector);

	if (!ObjectOverrideInputAccessor.IsValid())
	{
		PCGLog::LogWarningOnGraph(FText::Format(NSLOCTEXT("PCGObjectPropertyOverride", "OverrideInputInvalid", "ObjectOverride for input '{0}' is invalid or unsupported. Check the attribute or property selection."), InputSelector.GetDisplayText()), Context);
		return;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Metadata/PCGObjectPropertyOverride.cpp:121

Scope (from outer to inner):

file
function     bool FPCGObjectSingleOverride::IsValid

Source code excerpt:

bool FPCGObjectSingleOverride::IsValid() const
{
	return InputKeys.IsValid() && ObjectOverrideInputAccessor.IsValid() && ObjectOverrideOutputAccessor.IsValid() && ObjectOverrideFunction;
}

bool FPCGObjectSingleOverride::Apply(int32 InputKeyIndex, IPCGAttributeAccessorKeys& OutputKey)
{
	return Invoke(ObjectOverrideFunction, this, InputKeyIndex, OutputKey);
}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/PCGParamData.cpp:44

Scope (from outer to inner):

file
function     void UPCGParamData::AddToCrc

Source code excerpt:


		TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(this, InputSource);
		TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(this, InputSource);

		auto Callback = [&InputAccessor, &InputKeys, &Ar](auto && Dummy)
		{
			using AttributeType = std::decay_t<decltype(Dummy)>;
			TArray<AttributeType> Values;
			Values.SetNum(InputKeys->GetNum());
			InputAccessor->GetRange<AttributeType>(Values, 0, *InputKeys);

			for (AttributeType Value : Values)
			{
				// Add value to Crc
				PCG::Private::Serialize(Ar, Value);
			}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakTransformTest.cpp:123

Scope (from outer to inner):

file
function     bool FPCGMetadataBreakTransformTest::RunTest
lambda-function

Source code excerpt:


		TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(Input.Data, Settings->InputSource);
		TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(Input.Data, Settings->InputSource);

		if (!TestTrue("InputSource was found", InputAccessor.IsValid() && InputKeys.IsValid()))
		{
			return false;
		}

		auto ValidateComponentOutput = [this, &bTestPassed, &InputKeys, &InputAccessor](const FPCGTaggedData& Output, const FPCGAttributePropertySelector& OutSelector, PCGBreakTransformTest::EPCGComponentToCheck ComponentToCheck, auto DummyValue)
		{
			using OutType = decltype(DummyValue);

			if (!TestTrue("Valid output data", Output.Data != nullptr))
			{
				bTestPassed = false;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakTransformTest.cpp:155

Scope (from outer to inner):

file
function     bool FPCGMetadataBreakTransformTest::RunTest
lambda-function
lambda-function

Source code excerpt:

			}

			if (!TestEqual("Identical EntryKeys count", InputKeys->GetNum(), OutputKeys->GetNum()))
			{
				bTestPassed = false;
				return;
			}

			for (int32 i = 0; i < OutputKeys->GetNum(); ++i)
			{
				FTransform SourceValue{};
				if (!InputAccessor->Get<FTransform>(SourceValue, i, *InputKeys))
				{
					bTestPassed = false;
					return;
				}

				OutType OutValue{};

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakVectorTest.cpp:141

Scope (from outer to inner):

file
function     bool FPCGMetadataBreakVectorTest::RunTest
lambda-function

Source code excerpt:


		TUniquePtr<const IPCGAttributeAccessor> InputAccessor = PCGAttributeAccessorHelpers::CreateConstAccessor(Input.Data, Settings->InputSource);
		TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys = PCGAttributeAccessorHelpers::CreateConstKeys(Input.Data, Settings->InputSource);

		if (!TestTrue("InputSource was found", InputAccessor.IsValid() && InputKeys.IsValid()))
		{
			return false;
		}

		auto ValidateComponentOutput = [this, &bTestPassed, &InputKeys, &InputAccessor](const FPCGTaggedData& Output, const FPCGAttributePropertySelector& OutSelector, PCGBreakVectorTest::EPCGComponentToCheck ComponentToCheck)
		{
			if (!TestTrue("Valid output data", Output.Data != nullptr))
			{
				bTestPassed = false;
				return;
			}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakVectorTest.cpp:171

Scope (from outer to inner):

file
function     bool FPCGMetadataBreakVectorTest::RunTest
lambda-function
lambda-function

Source code excerpt:

			}

			if (!TestEqual("Identical EntryKeys count", InputKeys->GetNum(), OutputKeys->GetNum()))
			{
				bTestPassed = false;
				return;
			}

			for (int32 i = 0; i < OutputKeys->GetNum(); ++i)

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakVectorTest.cpp:183

Scope (from outer to inner):

file
function     bool FPCGMetadataBreakVectorTest::RunTest
lambda-function
lambda-function

Source code excerpt:

				{
					FVector TempValue{};
					if (!InputAccessor->Get<FVector>(TempValue, i, *InputKeys))
					{
						bTestPassed = false;
						return;
					}

					SourceValue = FVector4(TempValue);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakVectorTest.cpp:194

Scope (from outer to inner):

file
lambda-function
lambda-function

Source code excerpt:

				{
					FVector2D TempValue{};
					if (!InputAccessor->Get<FVector2D>(TempValue, i, *InputKeys))
					{
						bTestPassed = false;
						return;
					}

					SourceValue = FVector4(TempValue.X, TempValue.Y);

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Private/Tests/Elements/Metadata/PCGMetadataBreakVectorTest.cpp:204

Scope (from outer to inner):

file
lambda-function
lambda-function

Source code excerpt:

				else if (InputAccessor->GetUnderlyingType() == PCG::Private::MetadataTypes<FVector4>::Id)
				{
					if (!InputAccessor->Get<FVector4>(SourceValue, i, *InputKeys))
					{
						bTestPassed = false;
						return;
					}
				}
				else //if (InputAccessor->GetUnderlyingType() == PCG::Private::MetadataTypes<FRotator>::Id)
				{
					FRotator TempValue{};
					if (!InputAccessor->Get<FRotator>(TempValue, i, *InputKeys))
					{
						bTestPassed = false;
						return;
					}

					SourceValue.X = TempValue.Roll;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Public/Elements/Metadata/PCGMetadataOpElementBase.h:176

Scope (from outer to inner):

file
namespace    PCGMetadataOps

Source code excerpt:

		TArray<FPCGAttributePropertyInputSelector> InputSources;

		TArray<TUniquePtr<const IPCGAttributeAccessorKeys>> InputKeys;
		TArray<TUniquePtr<IPCGAttributeAccessorKeys>> OutputKeys;

		TArray<TUniquePtr<const IPCGAttributeAccessor>> InputAccessors;
		TArray<TUniquePtr<IPCGAttributeAccessor>> OutputAccessors;

		template <int32 NbInputs, int32 NbOutputs>

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Public/Elements/Metadata/PCGMetadataOpElementBase.h:361

Scope (from outer to inner):

file
namespace    PCG
namespace    Private
namespace    NAryOperation
function     bool Gather

Source code excerpt:

		else
		{
			bSuccess = InOperationData.InputAccessors[InputIndex]->GetRange<InputType>(InputValues, StartIndex, *InOperationData.InputKeys[InputIndex], InOptions.GetFlags);
		}

		if (!bSuccess)
		{
			return false;
		}

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Public/Elements/Metadata/PCGMetadataOpElementBase.h:394

Scope (from outer to inner):

file
function     void PCGMetadataOps::FOperationData::Validate

Source code excerpt:

	{
		check(InputAccessors[i].IsValid());
		check(InputKeys[i].IsValid());
	}

	for (int32 j = 0; j < NbOutputs; ++j)
	{
		check(OutputAccessors[j].IsValid());
		check(OutputKeys[j].IsValid());

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Public/Elements/PCGAttributeNoise.h:118

Scope: file

Source code excerpt:

	TUniquePtr<const IPCGAttributeAccessor> InputAccessor;
	TUniquePtr<IPCGAttributeAccessor> OutputAccessor;
	TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys;
	TUniquePtr<IPCGAttributeAccessorKeys> OutputKeys;
};

class FPCGAttributeNoiseElement : public IPCGElement
{
protected:

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Public/Metadata/PCGObjectPropertyOverride.h:58

Scope: file

Source code excerpt:

* and write its value to the OutputAccessor.
* 
* The InputAccessor's InputKeys are created from the given SourceData and InputSelector.
*/
struct FPCGObjectSingleOverride
{
	/** Initialize the single object override. Call before using Apply(InputKeyIndex, OutputKey). */
	void Initialize(const FPCGAttributePropertySelector& InputSelector, const FString& OutputProperty, const UStruct* TemplateClass, const UPCGData* SourceData, FPCGContext* Context);

	/** Returns true if initialization succeeded in creating the accessors and accessor keys. */
	bool IsValid() const;

	/** Applies a single property override to the object by reading from the InputAccessor at the given KeyIndex, and writing to the OutputKey which represents the object property. */
	bool Apply(int32 InputKeyIndex, IPCGAttributeAccessorKeys& OutputKey);

private:
	TUniquePtr<const IPCGAttributeAccessorKeys> InputKeys;
	TUniquePtr<const IPCGAttributeAccessor> ObjectOverrideInputAccessor;
	TUniquePtr<IPCGAttributeAccessor> ObjectOverrideOutputAccessor;

	// InputKeyIndex, OutputKeys
	using ApplyOverrideFunction = bool(FPCGObjectSingleOverride::*)(int32, IPCGAttributeAccessorKeys&);
	ApplyOverrideFunction ObjectOverrideFunction = nullptr;

#Loc: <Workspace>/Engine/Plugins/PCG/Source/PCG/Public/Metadata/PCGObjectPropertyOverride.h:90

Scope (from outer to inner):

file
function     bool ApplyImpl

Source code excerpt:

		Type Value{};
		check(ObjectOverrideInputAccessor.IsValid());
		if (ObjectOverrideInputAccessor->Get<Type>(Value, InputKeyIndex, *InputKeys.Get(), EPCGAttributeAccessorFlags::AllowBroadcast | EPCGAttributeAccessorFlags::AllowConstructible))
		{
			check(ObjectOverrideOutputAccessor.IsValid());
			if (ObjectOverrideOutputAccessor->Set<Type>(Value, OutputKey))
			{
				return true;
			}

#Loc: <Workspace>/Engine/Source/Developer/Localization/Private/LocalizationConfigurationScript.cpp:428

Scope (from outer to inner):

file
namespace    LocalizationConfigurationScript
function     FLocalizationConfigurationScript GenerateGatherTextConfigFile

Source code excerpt:

			for (const FMetaDataKeyGatherSpecification& Specification : Target->Settings.GatherFromMetaData.KeySpecifications)
			{
				ConfigSection.Add( TEXT("InputKeys"), Specification.MetaDataKey.Name );
				ConfigSection.Add( TEXT("OutputNamespaces"), Specification.TextNamespace );
				ConfigSection.Add( TEXT("OutputKeys"), Specification.TextKeyPattern.Pattern );
			}

			// Field Type Filters
			for (const FString& FieldTypeToInclude : Target->Settings.GatherFromMetaData.FieldTypesToInclude)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Commandlets/GatherTextFromMetadataCommandlet.h:26

Scope (from outer to inner):

file
class        class UGatherTextFromMetaDataCommandlet : public UGatherTextCommandletBase

Source code excerpt:

	struct FGatherParameters
	{
		TArray<FString> InputKeys;
		TArray<FString> OutputNamespaces;
		TArray<FString> OutputKeys;
	};

private:
	void GatherTextFromUObjects(const TArray<FString>& IncludePaths, const TArray<FString>& ExcludePaths, const FGatherParameters& Arguments);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Commandlets/GatherTextFromMetadataCommandlet.cpp:262

Scope (from outer to inner):

file
function     int32 UGatherTextFromMetaDataCommandlet::Main

Source code excerpt:


	FGatherParameters Arguments;
	GetStringArrayFromConfig(*SectionName, TEXT("InputKeys"), Arguments.InputKeys, GatherTextConfigPath);
	GetStringArrayFromConfig(*SectionName, TEXT("OutputNamespaces"), Arguments.OutputNamespaces, GatherTextConfigPath);
	GetStringArrayFromConfig(*SectionName, TEXT("OutputKeys"), Arguments.OutputKeys, GatherTextConfigPath);

	// Execute gather.
	GatherTextFromUObjects(IncludePathFilters, ExcludePathFilters, Arguments);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Commandlets/GatherTextFromMetadataCommandlet.cpp:350

Scope (from outer to inner):

file
function     void UGatherTextFromMetaDataCommandlet::GatherTextFromField

Source code excerpt:

				}

				for (int32 j = 0; j < Arguments.InputKeys.Num(); ++j)
				{
					FStringFormatNamedArguments PatternArguments;
					PatternArguments.Add(TEXT("FieldPath"), Enum->GetFullGroupName(false) + TEXT(".") + Enum->GetNameStringByIndex(i));

					if (Enum->HasMetaData(*Arguments.InputKeys[j], i))
					{
						const FString& MetaDataValue = Enum->GetMetaData(*Arguments.InputKeys[j], i);
						if (!MetaDataValue.IsEmpty())
						{
							PatternArguments.Add(TEXT("MetaDataValue"), MetaDataValue);

							const FString Namespace = Arguments.OutputNamespaces[j];
							FLocItem LocItem(MetaDataValue);
							FManifestContext Context;
							Context.Key = FString::Format(*Arguments.OutputKeys[j], PatternArguments);
							Context.SourceLocation = FString::Printf(TEXT("Meta-data for key %s of enum value %s of enum %s in %s"), *Arguments.InputKeys[j], *Enum->GetNameStringByIndex(i), *Enum->GetName(), *Enum->GetFullGroupName(true));
							Context.PlatformName = InPlatformName;
							GatherManifestHelper->AddSourceText(Namespace, LocItem, Context);
						}
					}
				}
			}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Commandlets/GatherTextFromMetadataCommandlet.cpp:438

Scope (from outer to inner):

file
function     void UGatherTextFromMetaDataCommandlet::GatherTextFromFieldImpl

Source code excerpt:

void UGatherTextFromMetaDataCommandlet::GatherTextFromFieldImpl(FieldType* Field, const FGatherParameters& Arguments, const FName InPlatformName)
{
	for (int32 i = 0; i < Arguments.InputKeys.Num(); ++i)
	{
		FStringFormatNamedArguments PatternArguments;
		PatternArguments.Add(TEXT("FieldPath"), Field->GetFullGroupName(false));

		if (Field->HasMetaData(*Arguments.InputKeys[i]))
		{
			const FString& MetaDataValue = Field->GetMetaData(*Arguments.InputKeys[i]);
			if (!MetaDataValue.IsEmpty())
			{
				PatternArguments.Add(TEXT("MetaDataValue"), MetaDataValue);

				const UStruct* FieldOwnerType = Field->GetOwnerStruct();
				const FString Namespace = Arguments.OutputNamespaces[i];

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Commandlets/GatherTextFromMetadataCommandlet.cpp:455

Scope (from outer to inner):

file
function     void UGatherTextFromMetaDataCommandlet::GatherTextFromFieldImpl

Source code excerpt:

				FManifestContext Context;
				Context.Key = FString::Format(*Arguments.OutputKeys[i], PatternArguments);
				Context.SourceLocation = FString::Printf(TEXT("Meta-data for key %s of member %s in %s (type: %s, owner: %s)"), *Arguments.InputKeys[i], *Field->GetName(), *Field->GetFullGroupName(true), *Field->GetClass()->GetName(), FieldOwnerType ? *FieldOwnerType->GetName() : TEXT("<null>"));
				Context.PlatformName = InPlatformName;
				GatherManifestHelper->AddSourceText(Namespace, LocItem, Context);
			}
		}
	}
}

#Loc: <Workspace>/Engine/Source/Runtime/InputCore/Classes/InputCoreTypes.h:729

Scope: file

Source code excerpt:

	};

	static INPUTCORE_API TMap<FKey, TSharedPtr<FKeyDetails> > InputKeys;
	static INPUTCORE_API TMap<FName, FCategoryDisplayInfo> MenuCategoryDisplayInfo;
	static INPUTCORE_API bool bInitialized;

};

/** Various states of touch inputs. */

#Loc: <Workspace>/Engine/Source/Runtime/InputCore/Private/InputCoreTypes.cpp:448

Scope: file

Source code excerpt:


bool EKeys::bInitialized = false;
TMap<FKey, TSharedPtr<FKeyDetails> > EKeys::InputKeys;
TMap<FName, EKeys::FCategoryDisplayInfo> EKeys::MenuCategoryDisplayInfo;

FKeyDetails::FKeyDetails(const FKey InKey, const TAttribute<FText>& InLongDisplayName, const TAttribute<FText>& InShortDisplayName, const uint32 InKeyFlags, const FName InMenuCategory)
	: Key(InKey)
	, MenuCategory(InMenuCategory)
	, LongDisplayName(InLongDisplayName)

#Loc: <Workspace>/Engine/Source/Runtime/InputCore/Private/InputCoreTypes.cpp:993

Scope (from outer to inner):

file
function     void EKeys::AddKey

Source code excerpt:

{
	const FKey& Key = KeyDetails.GetKey();
	ensureMsgf(!InputKeys.Contains(Key), TEXT("Adding duplicate key '%s'"), *Key.ToString());
	Key.KeyDetails = MakeShareable(new FKeyDetails(KeyDetails));
	InputKeys.Add(Key, Key.KeyDetails);
}


void EKeys::AddPairedKey(const FKeyDetails& PairedKeyDetails, FKey KeyX, FKey KeyY)
{
	// Validate pairing meets all the necessary conditions.
	if (!ensureMsgf(PairedKeyDetails.IsAxis2D(), TEXT("Paired key '%s' must be a 2D axis"), *PairedKeyDetails.GetKey().ToString()) ||
		!ensureMsgf(InputKeys.Contains(KeyX), TEXT("Failed to locate key '%s' for pairing. Make sure you've bound it with AddKey before calling AddPairedKey."), *KeyX.ToString()) ||
		!ensureMsgf(InputKeys.Contains(KeyY), TEXT("Failed to locate key '%s' for pairing. Make sure you've bound it with AddKey before calling AddPairedKey."), *KeyY.ToString()) ||
		!ensureMsgf(KeyX.IsAxis1D(), TEXT("Key '%s' is not a 1D axis"), *KeyX.ToString()) ||	// TODO: Would be good to be able to pair a 2D axis to 1D axis to make a 3D axis. Possibly via another helper function?
		!ensureMsgf(KeyY.IsAxis1D(), TEXT("Key '%s' is not a 1D axis"), *KeyY.ToString()) ||
		!ensureMsgf(KeyX.GetPairedAxis() == EPairedAxis::Unpaired, TEXT("Key '%s' has been already been paired as key '%s'. Only a single pairing is permitted."), *KeyX.ToString(), *KeyX.GetPairedAxisKey().ToString()) ||
		!ensureMsgf(KeyY.GetPairedAxis() == EPairedAxis::Unpaired, TEXT("Key '%s' has been already been paired as key '%s'. Only a single pairing is permitted."), *KeyY.ToString(), *KeyY.GetPairedAxisKey().ToString())
		)
	{

#Loc: <Workspace>/Engine/Source/Runtime/InputCore/Private/InputCoreTypes.cpp:1020

Scope (from outer to inner):

file
function     void EKeys::AddPairedKey

Source code excerpt:

	// TODO: Do we want a reverse lookup from vector version to the single axis versions?

	InputKeys[KeyX]->PairedAxis = EPairedAxis::X;
	InputKeys[KeyY]->PairedAxis = EPairedAxis::Y;
	InputKeys[KeyX]->PairedAxisKey = InputKeys[KeyY]->PairedAxisKey = PairedKeyDetails.GetKey();
}

void EKeys::GetAllKeys(TArray<FKey>& OutKeys)
{
	InputKeys.GetKeys(OutKeys);
}

void EKeys::RemoveKeysWithCategory(const FName InCategory)
{
	for (TMap<FKey, TSharedPtr<FKeyDetails> >::TConstIterator It(InputKeys); It; ++It)
	{

#Loc: <Workspace>/Engine/Source/Runtime/InputCore/Private/InputCoreTypes.cpp:1037

Scope (from outer to inner):

file
function     void EKeys::RemoveKeysWithCategory

Source code excerpt:

		if (KeyCategory.IsEqual(InCategory))
		{
			InputKeys.Remove(It.Key());
		}
	}
}

TSharedPtr<FKeyDetails> EKeys::GetKeyDetails(const FKey Key)
{
	TSharedPtr<FKeyDetails>* KeyDetails = InputKeys.Find(Key);
	if (KeyDetails == NULL)
	{
		return TSharedPtr<FKeyDetails>();
	}
	return *KeyDetails;
}