Editor.UseLegacyGetReferencersForDeletion

Editor.UseLegacyGetReferencersForDeletion

#Overview

name: Editor.UseLegacyGetReferencersForDeletion

This variable is created as a Console Variable (cvar).

It is referenced in 8 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of Editor.UseLegacyGetReferencersForDeletion is to control the algorithm used for detecting referencers of assets or objects being deleted in the Unreal Engine editor.

This setting variable is primarily used in the UnrealEd module, specifically in the ObjectTools namespace. It affects the asset deletion process and how the engine detects object references.

The value of this variable is set through a console variable (CVar) system. It’s defined as a TAutoConsoleVariable in ObjectTools.cpp, with a default value of false.

The associated variable CVarUseLegacyGetReferencersForDeletion interacts directly with Editor.UseLegacyGetReferencersForDeletion. They share the same value and purpose.

Developers must be aware that:

  1. When set to false (default), it uses an optimized version of the reference detection algorithm.
  2. When set to true, it uses a slower, legacy version of the algorithm, which is mainly kept for debugging and comparison purposes.

Best practices when using this variable include:

  1. Generally, keep it set to false for better performance.
  2. Use the legacy version (true) only when debugging reference issues or comparing results with the optimized version.
  3. Be cautious when changing this value during runtime, as it can affect the behavior of asset deletion operations.

Regarding the associated variable CVarUseLegacyGetReferencersForDeletion:

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/ObjectTools.cpp:109

Scope: file

Source code excerpt:


static TAutoConsoleVariable<bool> CVarUseLegacyGetReferencersForDeletion(
	TEXT("Editor.UseLegacyGetReferencersForDeletion"),
	false,
	TEXT("Choose the algorithm to be used when detecting referencers of any assets/objects being deleted.\n\n")
	TEXT("0: Use the most optimized version (default)\n")
	TEXT("1: Use the slower legacy version (for debug/comparison)"),
	ECVF_Default
	);

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/ObjectToolsTests.cpp:208

Scope (from outer to inner):

file
function     bool FObjectToolsTests_GatherObjectReferencersForDeletion::RunTest

Source code excerpt:


	//Make sure we do not use the legacy referencers for deletion
	static IConsoleVariable* CVarUseLegacyGetReferencersForDeletion = IConsoleManager::Get().FindConsoleVariable(TEXT("Editor.UseLegacyGetReferencersForDeletion"));
	check(CVarUseLegacyGetReferencersForDeletion);
	bool PreviousCVarUseLegacyGetReferencersForDeletionValue = CVarUseLegacyGetReferencersForDeletion->GetBool();
	CVarUseLegacyGetReferencersForDeletion->Set(0);
	//Put back the previous value when the test is done
	ON_SCOPE_EXIT
	{

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/AssetDeleteModel.cpp:678

Scope (from outer to inner):

file
function     void FPendingDelete::CheckForReferences

Source code excerpt:

	AssetRegistryModule.Get().GetReferencers(Object->GetOutermost()->GetFName(), DiskReferences);

	IConsoleVariable* UseLegacyGetReferencersForDeletion = IConsoleManager::Get().FindConsoleVariable(TEXT("Editor.UseLegacyGetReferencersForDeletion"));
	if (UseLegacyGetReferencersForDeletion == nullptr || !UseLegacyGetReferencersForDeletion->GetBool())
	{
		// This new version uses the fast reference collector to gather referencers and handles transaction referencers in a single pass
		ObjectTools::GatherObjectReferencersForDeletion(Object, bIsReferencedInMemoryByNonUndo, bIsReferencedInMemoryByUndo, &MemoryReferences);
	}
	else

#Associated Variable and Callsites

This variable is associated with another variable named CVarUseLegacyGetReferencersForDeletion. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/ObjectToolsTests.cpp:208

Scope (from outer to inner):

file
function     bool FObjectToolsTests_GatherObjectReferencersForDeletion::RunTest

Source code excerpt:


	//Make sure we do not use the legacy referencers for deletion
	static IConsoleVariable* CVarUseLegacyGetReferencersForDeletion = IConsoleManager::Get().FindConsoleVariable(TEXT("Editor.UseLegacyGetReferencersForDeletion"));
	check(CVarUseLegacyGetReferencersForDeletion);
	bool PreviousCVarUseLegacyGetReferencersForDeletionValue = CVarUseLegacyGetReferencersForDeletion->GetBool();
	CVarUseLegacyGetReferencersForDeletion->Set(0);
	//Put back the previous value when the test is done
	ON_SCOPE_EXIT
	{
		if (PreviousCVarUseLegacyGetReferencersForDeletionValue)
		{
			CVarUseLegacyGetReferencersForDeletion->Set(1);
		}
	};

	// Test direct references to ObjectInPackage
	{
		UObjectToolsTestObject* DirectRootReferencer = NewObject<UObjectToolsTestObject>(GetTransientPackage(), NAME_None, RF_Transactional);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/ObjectTools.cpp:108

Scope: file

Source code excerpt:

DEFINE_LOG_CATEGORY_STATIC(LogObjectTools, Log, All);

static TAutoConsoleVariable<bool> CVarUseLegacyGetReferencersForDeletion(
	TEXT("Editor.UseLegacyGetReferencersForDeletion"),
	false,
	TEXT("Choose the algorithm to be used when detecting referencers of any assets/objects being deleted.\n\n")
	TEXT("0: Use the most optimized version (default)\n")
	TEXT("1: Use the slower legacy version (for debug/comparison)"),
	ECVF_Default

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/ObjectTools.cpp:268

Scope (from outer to inner):

file
namespace    ObjectTools
function     void GatherObjectReferencersForDeletion

Source code excerpt:

		bOutIsReferencedInMemoryByUndo = false;
		
		if (!CVarUseLegacyGetReferencersForDeletion.GetValueOnAnyThread())
		{
			const UTransactor* Transactor = GEditor ? ToRawPtr(GEditor->Trans) : nullptr;
			bool bIsGatheringPackageRef = InObject->IsA<UPackage>();

			// Get the cluster of objects that are going to be deleted
			TArray<UObject*> ObjectsToDelete;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/ObjectTools.cpp:396

Scope (from outer to inner):

file
namespace    ObjectTools
function     void GatherObjectReferencersForDeletion

Source code excerpt:

				{
					UE_LOG(LogObjectTools, Warning, TEXT("Detected inconsistencies between reference gathering algorithms. Switching 'Editor.UseLegacyGetReferencersForDeletion' on for the remainder of this editor session."));
					CVarUseLegacyGetReferencersForDeletion->Set(1);
				}
				GEditor->Trans->EnableObjectSerialization();
			}
		}
		// This is the old/slower behavior that is kept for debug/comparison and is going to be removed in a future release
		else

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/ObjectTools.cpp:3209

Scope (from outer to inner):

file
namespace    ObjectTools
function     static void RecursiveRetrieveReferencers

Source code excerpt:

	static void RecursiveRetrieveReferencers(const TArray<UObject*>& InInterestSet, TSet<FWeakObjectPtr>& OutReferencingObjects)
	{
		if (!CVarUseLegacyGetReferencersForDeletion.GetValueOnAnyThread())
		{
			// Use the fast reference collector to recursively find referencers until no more are found
			TSet<UObject*> InterestSet;
			InterestSet.Append(InInterestSet);

			// Continue until we're not adding any more referencers to the set