异步加载类:AsyncLoading.cpp。AsyncLoadingThread.h,使用FAsyncLoadingThread异步处理
int32 LoadPackageAsync(const FString& InName, const FGuid* InGuid /*= nullptr*/, const TCHAR* InPackageToLoadFrom /*= nullptr*/, FLoadPackageAsyncDelegate InCompletionDelegate /*= FLoadPackageAsyncDelegate()*/, EPackageFlags InPackageFlags /*= PKG_None*/, int32 InPIEInstanceID /*= INDEX_NONE*/, int32 InPackagePriority /*= 0*/)
{
static bool bOnce = false;
if (!bOnce && GEventDrivenLoaderEnabled)
{
bOnce = true;
FGCObject::StaticInit(); // otherwise this thing is created during async loading, but not associated with a package
}
// The comments clearly state that it should be a package name but we also handle it being a filename as this function is not perf critical
// and LoadPackage handles having a filename being passed in as well.
FString PackageName;
if (FPackageName::IsValidLongPackageName(InName, /*bIncludeReadOnlyRoots*/true))
{
PackageName = InName;
}
// PackageName got populated by the conditional function
else if (!(FPackageName::IsPackageFilename(InName) && FPackageName::TryConvertFilenameToLongPackageName(InName, PackageName)))
{
// PackageName will get populated by the conditional function
FString ClassName;
if (!FPackageName::ParseExportTextPath(PackageName, &ClassName, &PackageName))
{
UE_LOG(LogStreaming, Fatal, TEXT("LoadPackageAsync failed to begin to load a package because the supplied package name was neither a valid long package name nor a filename of a map within a content folder: '%s'"), *PackageName);
}
}
FString PackageNameToLoad(InPackageToLoadFrom);
if (PackageNameToLoad.IsEmpty())
{
PackageNameToLoad = PackageName;
}
// Make sure long package name is passed to FAsyncPackage so that it doesn't attempt to
// create a package with short name.
if (FPackageName::IsShortPackageName(PackageNameToLoad))
{
UE_LOG(LogStreaming, Fatal, TEXT("Async loading code requires long package names (%s)."), *PackageNameToLoad);
}
if ( FCoreDelegates::OnAsyncLoadPackage.IsBound() )
{
FCoreDelegates::OnAsyncLoadPackage.Broadcast(InName);
}
// Generate new request ID and add it immediately to the global request list (it needs to be there before we exit
// this function, otherwise it would be added when the packages are being processed on the async thread).
const int32 RequestID = GPackageRequestID.Increment();
FAsyncLoadingThread::Get().AddPendingRequest(RequestID);
// Allocate delegate on Game Thread, it is not safe to copy delegates by value on other threads
TUniquePtr<FLoadPackageAsyncDelegate> CompletionDelegatePtr;
if (InCompletionDelegate.IsBound())
{
CompletionDelegatePtr.Reset(new FLoadPackageAsyncDelegate(InCompletionDelegate));
}
// Add new package request
FAsyncPackageDesc PackageDesc(RequestID, *PackageName, *PackageNameToLoad, InGuid ? *InGuid : FGuid(), MoveTemp(CompletionDelegatePtr), InPackageFlags, InPIEInstanceID, InPackagePriority);
FAsyncLoadingThread::Get().QueuePackage(PackageDesc);
return RequestID;
}
所有异步加载最后应该都在这里。