void FPendingDelete::CheckForReferences() { if ( bReferencesChecked ) { return; } bReferencesChecked = true; // Load the asset registry module FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>( TEXT( "AssetRegistry" ) ); AssetRegistryModule.Get().GetReferencers(Object->GetOutermost()->GetFName(), DiskReferences); // Check and see whether we are referenced by any objects that won't be garbage collected (*including* the undo buffer) FReferencerInformationList ReferencesIncludingUndo; bool bReferencedInMemoryOrUndoStack = IsReferenced(Object, GARBAGE_COLLECTION_KEEPFLAGS, true, &ReferencesIncludingUndo); // Determine the in-memory references, *excluding* the undo buffer GEditor->Trans->DisableObjectSerialization(); bIsReferencedInMemoryByNonUndo = IsReferenced(Object, GARBAGE_COLLECTION_KEEPFLAGS, true, &MemoryReferences); GEditor->Trans->EnableObjectSerialization(); // see if this object is the transaction buffer - set a flag so we know we need to clear the undo stack const int32 TotalReferenceCount = ReferencesIncludingUndo.ExternalReferences.Num() + ReferencesIncludingUndo.InternalReferences.Num(); const int32 NonUndoReferenceCount = MemoryReferences.ExternalReferences.Num() + MemoryReferences.InternalReferences.Num(); bIsReferencedInMemoryByUndo = TotalReferenceCount > NonUndoReferenceCount; }
void FPendingDelete::CheckForReferences() { if ( bReferencesChecked ) { return; } bReferencesChecked = true; // Load the asset registry module FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>( TEXT( "AssetRegistry" ) ); AssetRegistryModule.Get().GetReferencers(Object->GetOutermost()->GetFName(), DiskReferences); // Check and see whether we are referenced by any objects that won't be garbage collected (*including* the undo buffer) FReferencerInformationList ReferencesIncludingUndo; bool bReferencedInMemoryOrUndoStack = IsReferenced(Object, GARBAGE_COLLECTION_KEEPFLAGS, true, &ReferencesIncludingUndo); // Determine the in-memory references, *excluding* the undo buffer GEditor->Trans->DisableObjectSerialization(); bIsReferencedInMemoryByNonUndo = IsReferenced(Object, GARBAGE_COLLECTION_KEEPFLAGS, true, &MemoryReferences); GEditor->Trans->EnableObjectSerialization(); // see if this object is the transaction buffer - set a flag so we know we need to clear the undo stack const int32 TotalReferenceCount = ReferencesIncludingUndo.ExternalReferences.Num() + ReferencesIncludingUndo.InternalReferences.Num(); const int32 NonUndoReferenceCount = MemoryReferences.ExternalReferences.Num() + MemoryReferences.InternalReferences.Num(); bIsReferencedInMemoryByUndo = TotalReferenceCount > NonUndoReferenceCount; // If the object itself isn't in the transaction buffer, check to see if it's a Blueprint asset. We might have instances of the // Blueprint in the transaction buffer, in which case we also want to both alert the user and clear it prior to deleting the asset. if ( !bIsReferencedInMemoryByUndo ) { UBlueprint* Blueprint = Cast<UBlueprint>( Object ); if ( Blueprint && Blueprint->GeneratedClass ) { TArray<FReferencerInformation> ExternalMemoryReferences = MemoryReferences.ExternalReferences; for ( auto RefIt = ExternalMemoryReferences.CreateIterator(); RefIt && !bIsReferencedInMemoryByUndo; ++RefIt ) { FReferencerInformation& RefInfo = *RefIt; if ( RefInfo.Referencer->IsA( Blueprint->GeneratedClass ) ) { if ( IsReferenced( RefInfo.Referencer, GARBAGE_COLLECTION_KEEPFLAGS, true, &ReferencesIncludingUndo ) ) { GEditor->Trans->DisableObjectSerialization(); FReferencerInformationList ReferencesExcludingUndo; if ( IsReferenced( RefInfo.Referencer, GARBAGE_COLLECTION_KEEPFLAGS, true, &ReferencesExcludingUndo ) ) { bIsReferencedInMemoryByUndo = ( ReferencesIncludingUndo.InternalReferences.Num() + ReferencesIncludingUndo.ExternalReferences.Num() ) > ( ReferencesExcludingUndo.InternalReferences.Num() + ReferencesExcludingUndo.ExternalReferences.Num() ); } GEditor->Trans->EnableObjectSerialization(); } } } } } }
static bool GetExternalReferences(UObject* Obj, TArray<FReferencerInformation>& ExternalRefsOut) { CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS); bool bHasReferences = false; FReferencerInformationList Refs; if (IsReferenced(Obj, RF_Native | RF_Public, true, &Refs)) { ExternalRefsOut = Refs.ExternalReferences; bHasReferences = true; } return bHasReferences; }