EM_Task/CoreUObject/Private/Serialization/ArchiveHasReferences.cpp

96 lines
2.9 KiB
C++
Raw Normal View History

2026-02-13 16:18:33 +08:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Serialization/ArchiveHasReferences.h"
#include "UObject/UObjectIterator.h"
FArchiveHasReferences::FArchiveHasReferences(UObject* InTarget, const TSet<UObject*>& InPotentiallyReferencedObjects)
: Target(InTarget), PotentiallyReferencedObjects(InPotentiallyReferencedObjects), Result(false)
{
check(InTarget);
ArIsObjectReferenceCollector = true;
InTarget->Serialize(*this);
class FArchiveProxyCollector: public FReferenceCollector
{
/** Archive we are a proxy for */
FArchive& Archive;
public:
FArchiveProxyCollector(FArchive& InArchive)
: Archive(InArchive)
{
}
virtual void HandleObjectReference(UObject*& Object, const UObject* ReferencingObject, const FProperty* ReferencingProperty) override
{
Archive << Object;
}
virtual void HandleObjectReferences(UObject** InObjects, const int32 ObjectNum, const UObject* InReferencingObject, const FProperty* InReferencingProperty) override
{
for (int32 ObjectIndex = 0; ObjectIndex < ObjectNum; ++ObjectIndex)
{
UObject*& Object = InObjects[ObjectIndex];
Archive << Object;
}
}
virtual bool IsIgnoringArchetypeRef() const override
{
return false;
}
virtual bool IsIgnoringTransient() const override
{
return false;
}
} ArchiveProxyCollector(*this);
if (!Result)
{
InTarget->GetClass()->CallAddReferencedObjects(InTarget, ArchiveProxyCollector);
}
}
FArchive& FArchiveHasReferences::operator<<(UObject*& Obj)
{
if (Obj != nullptr && Obj != Target)
{
if (PotentiallyReferencedObjects.Contains(Obj))
{
Result = true;
}
}
return *this;
}
TArray<UObject*> FArchiveHasReferences::GetAllReferencers(const TArray<UObject*>& Referencees, const TSet<UObject*>* ObjectsToIgnore)
{
return GetAllReferencers(TSet<UObject*>(Referencees), ObjectsToIgnore);
}
TArray<UObject*> FArchiveHasReferences::GetAllReferencers(const TSet<UObject*>& Referencees, const TSet<UObject*>* ObjectsToIgnore)
{
TArray<UObject*> Ret;
if (Referencees.Num() > 0)
{
for (FThreadSafeObjectIterator It; It; ++It)
{
UObject* PotentialReferencer = *It;
if (ObjectsToIgnore && ObjectsToIgnore->Contains(PotentialReferencer))
{
continue;
}
if (!Referencees.Contains(PotentialReferencer))
{
// serialize the object, looking for any to SourceObjectsSet:
FArchiveHasReferences HasReferences(PotentialReferencer, Referencees);
if (HasReferences.HasReferences())
{
Ret.Add(PotentialReferencer);
}
}
}
}
return Ret;
}