예제 #1
0
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

}