void FChunkManifestGenerator::AddPackageAndDependenciesToChunk(FChunkPackageSet* ThisPackageSet, FName InPkgName, const FString& InSandboxFile, int32 ChunkID, FSandboxPlatformFile* SandboxPlatformFile) { //Add this asset ThisPackageSet->Add(InPkgName, InSandboxFile); //Only gather dependencies if we're chunking if (!bGenerateChunks) { return; } //now add any dependencies TArray<FName> DependentPackageNames; if (GatherAllPackageDependencies(InPkgName, DependentPackageNames)) { for (const auto& PkgName : DependentPackageNames) { bool bSkip = false; if (ChunkID != 0 && FinalChunkManifests[0]) { // Do not add if this asset was assigned to the 0 chunk. These assets always exist on disk bSkip = FinalChunkManifests[0]->Contains(PkgName); } if (!bSkip) { auto DependentPackageLongName = PkgName.ToString(); if (FPackageName::IsShortPackageName(PkgName)) { DependentPackageLongName = FPackageName::ConvertToLongScriptPackageName(*PkgName.ToString()); } FString DependentSandboxFile = SandboxPlatformFile->ConvertToAbsolutePathForExternalAppForWrite(*FPackageName::LongPackageNameToFilename(DependentPackageLongName)); ThisPackageSet->Add(PkgName, DependentSandboxFile); UnassignedPackageSet.Remove(PkgName); } } } }
void FChunkManifestGenerator::BuildChunkManifest(const TArray<FName>& CookedPackages, FSandboxPlatformFile* InSandboxFile, bool bGenerateStreamingInstallManifest) { bGenerateChunks = bGenerateStreamingInstallManifest; // initialize LargestChunkId, FoundIDList, PackageChunkIDMap, AssetRegistryData // Calculate the largest chunk id used by the registry to get the indices for the default chunks AssetRegistry.GetAllAssets(AssetRegistryData); int32 LargestChunkID = -1; for (int32 Index = 0; Index < AssetRegistryData.Num(); ++Index) { auto& AssetData = AssetRegistryData[Index]; auto& RegistryChunkIDs = RegistryChunkIDsMap.FindOrAdd(AssetData.PackageName); for (auto ChunkIt = AssetData.ChunkIDs.CreateConstIterator(); ChunkIt; ++ChunkIt) { int32 ChunkID = *ChunkIt; if (ChunkID < 0) { UE_LOG(LogChunkManifestGenerator, Warning, TEXT("Out of range ChunkID: %d"), ChunkID); ChunkID = 0; } else if (ChunkID > LargestChunkID) { LargestChunkID = ChunkID; } if (!RegistryChunkIDs.Contains(ChunkID)) { RegistryChunkIDs.Add(ChunkID); } auto* FoundIDList = PackageChunkIDMap.Find(AssetData.PackageName); if (!FoundIDList) { FoundIDList = &PackageChunkIDMap.Add(AssetData.PackageName); } FoundIDList->AddUnique(ChunkID); } // Now clear the original chunk id list. We will fill it with real IDs when cooking. AssetData.ChunkIDs.Empty(); // Map asset data to its package (there can be more than one asset data per package). auto& PackageData = PackageToRegistryDataMap.FindOrAdd(AssetData.PackageName); PackageData.Add(Index); } // add all the packages to the unassigned package list for (const auto& CookedPackage : CookedPackages) { const FString SandboxPath = InSandboxFile->ConvertToAbsolutePathForExternalAppForWrite(*FPackageName::LongPackageNameToFilename(CookedPackage.ToString())); AllCookedPackages.Add(CookedPackage, SandboxPath); UnassignedPackageSet.Add(CookedPackage, SandboxPath); } for (const auto& CookedPackage : StartupPackages) { const FString SandboxPath = InSandboxFile->ConvertToAbsolutePathForExternalAppForWrite(*FPackageName::LongPackageNameToFilename(CookedPackage.ToString())); AllCookedPackages.Add(CookedPackage, SandboxPath); AddPackageToManifest(SandboxPath, CookedPackage, 0); } // assign chunks for all the map packages for (const auto& CookedPackage : UnassignedPackageSet) { // ignore non map packages for now const FName MapFName = CookedPackage.Key; // this package could be missing from the map because it didn't get cooked. // the reason for this might be that it's a redirector therefore we cooked the package which actually contains the asset if (PackageToRegistryDataMap.Find(MapFName) == nullptr) continue; if (ContainsMap(MapFName) == false) continue; // get all the dependencies for this map TArray<FName> MapDependencies; ensure(GatherAllPackageDependencies(MapFName, MapDependencies)); for (const auto& RawPackageFName : MapDependencies) { const FName PackageFName = GetPackageNameFromDependencyPackageName(RawPackageFName); if (PackageFName == NAME_None) { continue; } const FString PackagePathName = PackageFName.ToString(); const FString MapName = MapFName.ToString(); const FString* SandboxFilenamePtr = AllCookedPackages.Find(PackageFName); if (!SandboxFilenamePtr) { const FString SandboxPath = InSandboxFile->ConvertToAbsolutePathForExternalAppForWrite(*FPackageName::LongPackageNameToFilename(PackagePathName)); AllCookedPackages.Add(PackageFName, SandboxPath); SandboxFilenamePtr = AllCookedPackages.Find(PackageFName); check(SandboxFilenamePtr); } const FString& SandboxFilename = *SandboxFilenamePtr; GenerateChunkManifestForPackage(PackageFName, PackagePathName, SandboxFilename, MapName, InSandboxFile); } } // process the remaining unassigned packages, they don't have a map associated with them // probably a good reason for it but maybe not for (const auto& CookedPackage : UnassignedPackageSet) { const FName& PackageFName = CookedPackage.Key; const FString& SandboxFilename = AllCookedPackages.FindChecked(PackageFName); const FString PackagePathName = PackageFName.ToString(); GenerateChunkManifestForPackage(PackageFName, PackagePathName, SandboxFilename, FString(), InSandboxFile); } // anything that remains in the UnAssignedPackageSet will be put in chunk0 when we save the asset registry }