2021-09-28 04:00:33 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "FilePackageStore.h"
# include "IO/IoContainerId.h"
# include "Misc/CommandLine.h"
# include "IO/IoContainerHeader.h"
# include "Misc/ScopeRWLock.h"
# include "ProfilingDebugging/CountersTrace.h"
# include "Internationalization/PackageLocalizationManager.h"
2021-09-28 04:10:53 -04:00
# include "Misc/ScopeLock.h"
2022-01-19 18:28:42 -05:00
# include "Misc/PackageName.h"
2021-09-28 04:00:33 -04:00
//PRAGMA_DISABLE_OPTIMIZATION
2021-11-18 14:37:34 -05:00
DEFINE_LOG_CATEGORY_STATIC ( LogFilePackageStore , Log , All ) ;
2022-01-19 18:28:42 -05:00
thread_local int32 FFilePackageStore : : LockedOnThreadCount = 0 ;
2021-09-28 04:00:33 -04:00
FFilePackageStore : : FFilePackageStore ( )
{
2022-01-19 18:28:42 -05:00
# if WITH_EDITOR
OnContentPathMountedDelegateHandle = FPackageName : : OnContentPathMounted ( ) . AddLambda ( [ this ] ( const FString & InAssetPath , const FString & InFilesystemPath )
{
{
FScopeLock _ ( & UncookedPackageRootsLock ) ;
PendingUncookedPackageRoots . Add ( InFilesystemPath ) ;
}
{
FWriteScopeLock _ ( EntriesLock ) ;
bNeedsUpdate = true ;
}
} ) ;
# endif
}
FFilePackageStore : : ~ FFilePackageStore ( )
{
# if WITH_EDITOR
FPackageName : : OnContentPathMounted ( ) . Remove ( OnContentPathMountedDelegateHandle ) ;
# endif
2021-09-28 04:00:33 -04:00
}
void FFilePackageStore : : Initialize ( )
{
2022-01-19 18:28:42 -05:00
# if WITH_EDITOR
TArray < FString > RootPaths ;
FPackageName : : QueryRootContentPaths ( RootPaths ) ;
{
FScopeLock _ ( & UncookedPackageRootsLock ) ;
PendingUncookedPackageRoots . Append ( RootPaths ) ;
}
{
FWriteScopeLock _ ( EntriesLock ) ;
bNeedsUpdate = true ;
}
# endif
2021-09-28 04:00:33 -04:00
}
void FFilePackageStore : : Lock ( )
{
2022-01-19 18:28:42 -05:00
if ( ! LockedOnThreadCount )
2021-09-28 04:00:33 -04:00
{
2022-01-19 18:28:42 -05:00
EntriesLock . ReadLock ( ) ;
if ( bNeedsUpdate )
{
Update ( ) ;
}
2021-09-28 04:00:33 -04:00
}
2022-01-19 18:28:42 -05:00
+ + LockedOnThreadCount ;
2021-09-28 04:00:33 -04:00
}
void FFilePackageStore : : Unlock ( )
{
2022-01-19 18:28:42 -05:00
check ( LockedOnThreadCount > 0 ) ;
if ( - - LockedOnThreadCount = = 0 )
{
EntriesLock . ReadUnlock ( ) ;
}
2021-09-28 04:00:33 -04:00
}
bool FFilePackageStore : : DoesPackageExist ( FPackageId PackageId )
{
2022-01-19 18:28:42 -05:00
check ( LockedOnThreadCount ) ;
2021-09-28 04:00:33 -04:00
return PackageId . IsValid ( ) & & StoreEntriesMap . Contains ( PackageId ) ;
}
2021-10-12 21:21:22 -04:00
EPackageStoreEntryStatus FFilePackageStore : : GetPackageStoreEntry ( FPackageId PackageId , FPackageStoreEntry & OutPackageStoreEntry )
2021-09-28 04:00:33 -04:00
{
2022-01-19 18:28:42 -05:00
check ( LockedOnThreadCount ) ;
# if WITH_EDITOR
const FUncookedPackage * FindUncookedPackage = UncookedPackagesMap . Find ( PackageId ) ;
if ( FindUncookedPackage )
{
OutPackageStoreEntry . UncookedPackageName = FindUncookedPackage - > PackageName ;
OutPackageStoreEntry . UncookedPackageHeaderExtension = static_cast < uint8 > ( FindUncookedPackage - > HeaderExtension ) ;
return EPackageStoreEntryStatus : : Ok ;
}
# endif
2021-09-28 04:00:33 -04:00
const FFilePackageStoreEntry * FindEntry = StoreEntriesMap . FindRef ( PackageId ) ;
2021-10-12 21:21:22 -04:00
if ( FindEntry )
2021-09-28 04:00:33 -04:00
{
2021-10-12 21:21:22 -04:00
OutPackageStoreEntry . ExportInfo . ExportCount = FindEntry - > ExportCount ;
OutPackageStoreEntry . ExportInfo . ExportBundleCount = FindEntry - > ExportBundleCount ;
OutPackageStoreEntry . ImportedPackageIds = MakeArrayView ( FindEntry - > ImportedPackages . Data ( ) , FindEntry - > ImportedPackages . Num ( ) ) ;
OutPackageStoreEntry . ShaderMapHashes = MakeArrayView ( FindEntry - > ShaderMapHashes . Data ( ) , FindEntry - > ShaderMapHashes . Num ( ) ) ;
return EPackageStoreEntryStatus : : Ok ;
}
2022-01-19 18:28:42 -05:00
return EPackageStoreEntryStatus : : Missing ;
2021-09-28 04:00:33 -04:00
}
bool FFilePackageStore : : GetPackageRedirectInfo ( FPackageId PackageId , FName & OutSourcePackageName , FPackageId & OutRedirectedToPackageId )
{
2022-01-19 18:28:42 -05:00
check ( LockedOnThreadCount ) ;
2021-09-28 04:00:33 -04:00
TTuple < FName , FPackageId > * FindRedirect = RedirectsPackageMap . Find ( PackageId ) ;
if ( FindRedirect )
{
OutSourcePackageName = FindRedirect - > Get < 0 > ( ) ;
OutRedirectedToPackageId = FindRedirect - > Get < 1 > ( ) ;
2021-11-18 14:37:34 -05:00
UE_LOG ( LogFilePackageStore , Verbose , TEXT ( " Redirecting from %s to 0x%llx " ) , * OutSourcePackageName . ToString ( ) , OutRedirectedToPackageId . Value ( ) ) ;
2021-09-28 04:00:33 -04:00
return true ;
}
2021-11-18 14:37:34 -05:00
const FName * FindLocalizedPackageSourceName = LocalizedPackages . Find ( PackageId ) ;
if ( FindLocalizedPackageSourceName )
2021-09-28 04:00:33 -04:00
{
2021-11-18 14:37:34 -05:00
FName LocalizedPackageName = FPackageLocalizationManager : : Get ( ) . FindLocalizedPackageName ( * FindLocalizedPackageSourceName ) ;
if ( ! LocalizedPackageName . IsNone ( ) )
{
FPackageId LocalizedPackageId = FPackageId : : FromName ( LocalizedPackageName ) ;
if ( StoreEntriesMap . Find ( LocalizedPackageId ) )
{
OutSourcePackageName = * FindLocalizedPackageSourceName ;
OutRedirectedToPackageId = LocalizedPackageId ;
UE_LOG ( LogFilePackageStore , Verbose , TEXT ( " Redirecting from localized package %s to 0x%llx " ) , * OutSourcePackageName . ToString ( ) , OutRedirectedToPackageId . Value ( ) ) ;
return true ;
}
}
2021-09-28 04:00:33 -04:00
}
2021-11-18 14:37:34 -05:00
return false ;
2021-09-28 04:00:33 -04:00
}
void FFilePackageStore : : Mount ( const FIoContainerHeader * ContainerHeader , uint32 Order )
{
LLM_SCOPE ( ELLMTag : : AsyncLoading ) ;
FWriteScopeLock _ ( EntriesLock ) ;
MountedContainers . Add ( { ContainerHeader , Order } ) ;
Algo : : Sort ( MountedContainers , [ ] ( const FMountedContainer & A , const FMountedContainer & B )
{
return A . Order < B . Order ;
} ) ;
bNeedsUpdate = true ;
}
void FFilePackageStore : : Unmount ( const FIoContainerHeader * ContainerHeader )
{
FWriteScopeLock _ ( EntriesLock ) ;
for ( auto It = MountedContainers . CreateIterator ( ) ; It ; + + It )
{
if ( It - > ContainerHeader = = ContainerHeader )
{
It . RemoveCurrent ( ) ;
bNeedsUpdate = true ;
return ;
}
}
}
void FFilePackageStore : : Update ( )
{
LLM_SCOPE ( ELLMTag : : AsyncLoading ) ;
TRACE_CPUPROFILER_EVENT_SCOPE ( UpdateFilePackageStore ) ;
FScopeLock Lock ( & UpdateLock ) ;
if ( ! bNeedsUpdate )
{
return ;
}
StoreEntriesMap . Empty ( ) ;
2021-11-18 14:37:34 -05:00
LocalizedPackages . Empty ( ) ;
2021-09-28 04:00:33 -04:00
RedirectsPackageMap . Empty ( ) ;
uint32 TotalPackageCount = 0 ;
for ( const FMountedContainer & MountedContainer : MountedContainers )
{
TotalPackageCount + = MountedContainer . ContainerHeader - > PackageCount ;
}
StoreEntriesMap . Reserve ( TotalPackageCount ) ;
for ( const FMountedContainer & MountedContainer : MountedContainers )
{
const FIoContainerHeader * ContainerHeader = MountedContainer . ContainerHeader ;
TArrayView < const FFilePackageStoreEntry > ContainerStoreEntries ( reinterpret_cast < const FFilePackageStoreEntry * > ( ContainerHeader - > StoreEntries . GetData ( ) ) , ContainerHeader - > PackageCount ) ;
int32 Index = 0 ;
for ( const FFilePackageStoreEntry & StoreEntry : ContainerStoreEntries )
{
const FPackageId & PackageId = ContainerHeader - > PackageIds [ Index ] ;
check ( PackageId . IsValid ( ) ) ;
StoreEntriesMap . FindOrAdd ( PackageId , & StoreEntry ) ;
+ + Index ;
}
2021-10-12 21:21:22 -04:00
for ( const FIoContainerHeaderLocalizedPackage & LocalizedPackage : ContainerHeader - > LocalizedPackages )
2021-09-28 04:00:33 -04:00
{
2021-11-18 14:37:34 -05:00
FName & LocalizedPackageSourceName = LocalizedPackages . FindOrAdd ( LocalizedPackage . SourcePackageId ) ;
if ( LocalizedPackageSourceName . IsNone ( ) )
2021-09-28 04:00:33 -04:00
{
2021-10-12 21:21:22 -04:00
FNameEntryId NameEntry = ContainerHeader - > RedirectsNameMap [ LocalizedPackage . SourcePackageName . GetIndex ( ) ] ;
2021-11-18 14:37:34 -05:00
LocalizedPackageSourceName = FName : : CreateFromDisplayId ( NameEntry , LocalizedPackage . SourcePackageName . GetNumber ( ) ) ;
2021-09-28 04:00:33 -04:00
}
}
2021-11-18 14:37:34 -05:00
for ( const FIoContainerHeaderPackageRedirect & Redirect : ContainerHeader - > PackageRedirects )
2021-09-28 04:00:33 -04:00
{
2021-11-18 14:37:34 -05:00
FNameEntryId NameEntry = ContainerHeader - > RedirectsNameMap [ Redirect . SourcePackageName . GetIndex ( ) ] ;
FName SourcePackageName = FName : : CreateFromDisplayId ( NameEntry , Redirect . SourcePackageName . GetNumber ( ) ) ;
RedirectsPackageMap . Emplace ( Redirect . SourcePackageId , MakeTuple ( SourcePackageName , Redirect . TargetPackageId ) ) ;
2021-09-28 04:00:33 -04:00
}
}
2022-01-19 18:28:42 -05:00
# if WITH_EDITOR
{
FScopeLock _ ( & UncookedPackageRootsLock ) ;
uint64 TotalAddedCount = 0 ;
if ( ! PendingUncookedPackageRoots . IsEmpty ( ) )
{
UE_LOG ( LogFilePackageStore , Display , TEXT ( " Searching for uncooked packages in %d new roots... " ) , PendingUncookedPackageRoots . Num ( ) ) ;
for ( const FString & RootPath : PendingUncookedPackageRoots )
{
TotalAddedCount + = AddUncookedPackagesFromRoot ( RootPath ) ;
}
PendingUncookedPackageRoots . Empty ( ) ;
UE_LOG ( LogFilePackageStore , Display , TEXT ( " Found %lld uncooked packages " ) , TotalAddedCount ) ;
}
}
# endif
2021-09-28 04:00:33 -04:00
bNeedsUpdate = false ;
}
2022-01-19 18:28:42 -05:00
# if WITH_EDITOR
uint64 FFilePackageStore : : AddUncookedPackagesFromRoot ( const FString & RootPath )
{
uint64 TotalAddedCount = 0 ;
FPackageName : : IteratePackagesInDirectory ( RootPath , [ this , & RootPath , & TotalAddedCount ] ( const TCHAR * InPackageFileName ) - > bool
{
FPackagePath PackagePath = FPackagePath : : FromLocalPath ( InPackageFileName ) ;
FName PackageName = PackagePath . GetPackageFName ( ) ;
if ( ! PackageName . IsNone ( ) )
{
FPackageId PackageId = FPackageId : : FromName ( PackageName ) ;
FUncookedPackage & UncookedPackage = UncookedPackagesMap . FindOrAdd ( PackageId ) ;
UncookedPackage . PackageName = PackageName ;
UncookedPackage . HeaderExtension = PackagePath . GetHeaderExtension ( ) ;
+ + TotalAddedCount ;
}
return true ;
} ) ;
return TotalAddedCount ;
}
# endif
2021-09-28 04:00:33 -04:00
//PRAGMA_ENABLE_OPTIMIZATION