EM_Task/CoreUObject/Private/UObject/WeakObjectPtr.cpp

104 lines
3.2 KiB
C++
Raw Normal View History

2026-02-13 16:18:33 +08:00
// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
WeakObjectPtr.cpp: Weak pointer to UObject
=============================================================================*/
#include "UObject/WeakObjectPtr.h"
#include "UObject/Object.h"
DEFINE_LOG_CATEGORY_STATIC(LogWeakObjectPtr, Log, All);
/*-----------------------------------------------------------------------------------------------------------
Base serial number management.
-------------------------------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------------------------
FWeakObjectPtr
-------------------------------------------------------------------------------------------------------------*/
/**
* Copy from an object pointer
* @param Object object to create a weak pointer to
**/
void FWeakObjectPtr::operator=(const class UObject* Object)
{
if (Object // && UObjectInitialized() we might need this at some point, but it is a speed hit we would prefer to avoid
)
{
ObjectIndex = GUObjectArray.ObjectToIndex((UObjectBase*)Object);
ObjectSerialNumber = GUObjectArray.AllocateSerialNumber(ObjectIndex);
checkSlow(SerialNumbersMatch());
}
else
{
Reset();
}
}
bool FWeakObjectPtr::IsValid(bool bEvenIfPendingKill, bool bThreadsafeTest) const
{
// This is the external function, so we just pass through to the internal inlined method.
return Internal_IsValid(bEvenIfPendingKill, bThreadsafeTest);
}
bool FWeakObjectPtr::IsValid() const
{
// Using literals here allows the optimizer to remove branches later down the chain.
return Internal_IsValid(false, false);
}
bool FWeakObjectPtr::IsStale(bool bEvenIfPendingKill, bool bThreadsafeTest) const
{
if (ObjectSerialNumber == 0)
{
checkSlow(ObjectIndex == 0 || ObjectIndex == -1); // otherwise this is a corrupted weak pointer
return false;
}
if (ObjectIndex < 0)
{
return true;
}
FUObjectItem* ObjectItem = GUObjectArray.IndexToObject(ObjectIndex);
if (!ObjectItem)
{
return true;
}
if (!SerialNumbersMatch(ObjectItem))
{
return true;
}
if (bThreadsafeTest)
{
return false;
}
return GUObjectArray.IsStale(ObjectItem, bEvenIfPendingKill);
}
UObject* FWeakObjectPtr::Get(/*bool bEvenIfPendingKill = false*/) const
{
// Using a literal here allows the optimizer to remove branches later down the chain.
return Internal_Get(false);
}
UObject* FWeakObjectPtr::Get(bool bEvenIfPendingKill) const
{
return Internal_Get(bEvenIfPendingKill);
}
UObject* FWeakObjectPtr::GetEvenIfUnreachable() const
{
UObject* Result = nullptr;
if (Internal_IsValid(true, true))
{
FUObjectItem* ObjectItem = GUObjectArray.IndexToObject(GetObjectIndex(), true);
Result = static_cast<UObject*>(ObjectItem->Object);
}
return Result;
}
void FWeakObjectPtr::Serialize(FArchive& Ar)
{
FArchiveUObject::SerializeWeakObjectPtr(Ar, *this);
}