You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb Per.Larsson #jira UE-161296 #rnx #preflight 62fe3ce73d3fb466b229bcc0 - There are some usecases that require the VA system to initialize the first time it is accessed (usually the first time we attempt to pull a virtualized payload) rather than be initialized in the program start up. This change provides three different methods to achieve this: -- Setting the define 'UE_VIRTUALIZATION_SYSTEM_LAZY_INIT' to 1 in a programs .target.cs -- Setting [Core.ContentVirtualization]LazyInit=true in the Engine ini file -- Running with the commandline option -VA-LazyInit - If we detect that the source control backend is being initialized on a background thread we do not try to run the FConnect operation. The backend will still work but this does reduce the potential error checking on initialization. This is done because the FConnect operation currently only works on the main thread and to change this would be a bigger work item than we can schedule at the moment. - UE::Virtualization::Initialize functions now take a EInitializationFlags enum as a parameter. This enum allows the call to ignore all lazy init settings and force the initialization immediately. This is useful for programs like the Virtualization standalone tool which just needs to start the system when needed. -- The call to ::Initialize in LaunchEngineLoop passes in None and does not ignore lazy initialization. -- Calls to ::Initialize in the UnrealVirtualizationTool however all use EInitializationFlags::ForceInitialize and ignore lazy initialization settings. - Fixed an odd bug in UE::Virtualization::Initialize where the error path (if the config file cannot be found) was using a different start up code path. - Add asserts when assigning to GVirtualizationSystem to make sure that it is null. This is not 100% safe but should catch some potential threading issues, if any. - Add an assert after lazy initialization (IVirtualizationSystem::Get) to make sure that GVirtualizationSystem was assigned a valid object. - Improve how we check for legacy values in [Core.ContentVirtualization]. We now support multiple allowed values. - Added a way to poll if a VA system has been initialize yet or not, this allows us to avoid initializing a VA system if one has not yet been created and we try to: -- Dump VA profiling stats after cooking -- Send VA stats to studio analytics - Note that currently using lazy init loading will probably cause the VA statistics panel not to work, this will be fixed in future work where we will allow the panel to register for a callback when the system is initialized. [CL 21467510 by paul chipchase in ue5-main branch]
186 lines
5.3 KiB
C++
186 lines
5.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Commands/RehydrateCommand.h"
|
|
|
|
#include "HAL/FileManager.h"
|
|
#include "ISourceControlProvider.h"
|
|
#include "Misc/ConfigCacheIni.h"
|
|
#include "Misc/PackageName.h"
|
|
#include "Misc/Parse.h"
|
|
#include "Misc/ScopeExit.h"
|
|
#include "ProjectFiles.h"
|
|
#include "UnrealVirtualizationTool.h"
|
|
#include "Virtualization/VirtualizationSystem.h"
|
|
|
|
namespace UE::Virtualization
|
|
{
|
|
|
|
// Taken from UCommandlet
|
|
static void ParseCommandLine(const TCHAR* CmdLine, TArray<FString>& Tokens, TArray<FString>& Switches)
|
|
{
|
|
FString NextToken;
|
|
while (FParse::Token(CmdLine, NextToken, false))
|
|
{
|
|
if (**NextToken == TCHAR('-'))
|
|
{
|
|
new(Switches) FString(NextToken.Mid(1));
|
|
}
|
|
else
|
|
{
|
|
new(Tokens) FString(NextToken);
|
|
}
|
|
}
|
|
}
|
|
|
|
FRehydrateCommand::FRehydrateCommand(FStringView CommandName)
|
|
: FCommand(CommandName)
|
|
{
|
|
|
|
}
|
|
|
|
FRehydrateCommand::~FRehydrateCommand()
|
|
{
|
|
|
|
}
|
|
|
|
void FRehydrateCommand::PrintCmdLineHelp()
|
|
{
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("UnrealVirtualizationTool -ClientSpecName=<name> [optional] -Mode=Rehydrate -Package=<string> [global options]"));
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\tRehyrates the given package"));
|
|
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("UnrealVirtualizationTool -ClientSpecName=<name> [optional] -Mode=Rehydrate -PackageDir=<string> [global options]"));
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\tRehyrates all packages in the given directory and its subdirectories"));
|
|
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("UnrealVirtualizationTool -ClientSpecName=<name> [optional] -Mode=Rehydrate -Changelist=<number> [global options]"));
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\tRehyrates all packages in the given changelist"));
|
|
}
|
|
|
|
bool FRehydrateCommand::Initialize(const TCHAR* CmdLine)
|
|
{
|
|
// Note that we haven't loaded any projects config files and so don't really have
|
|
// any valid project mount points so we cannot use FPackagePath or FPackageName
|
|
// and expect to find anything!
|
|
|
|
TArray<FString> Tokens;
|
|
TArray<FString> Switches;
|
|
|
|
ParseCommandLine(CmdLine, Tokens, Switches);
|
|
|
|
Packages.Reserve(32);
|
|
|
|
for (const FString& Switch : Switches)
|
|
{
|
|
FString Path;
|
|
FString ChangelistNumber;
|
|
|
|
if (FParse::Value(*Switch, TEXT("ClientSpecName="), ClientSpecName))
|
|
{
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\tWorkspace name provided '%s'"), *ClientSpecName);
|
|
}
|
|
else if (FParse::Value(*Switch, TEXT("Package="), Path))
|
|
{
|
|
FPaths::NormalizeFilename(Path);
|
|
|
|
if (IFileManager::Get().FileExists(*Path))
|
|
{
|
|
Packages.Add(Path);
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogVirtualizationTool, Error, TEXT("Could not find the requested package file '%s'"), *Path);
|
|
return false;
|
|
}
|
|
}
|
|
else if (FParse::Value(*Switch, TEXT("PackageDir="), Path) || FParse::Value(*Switch, TEXT("PackageFolder="), Path))
|
|
{
|
|
// Note that 'PackageFolder' is the switch used by the resave commandlet, so allowing it here for compatibility purposes
|
|
FPaths::NormalizeFilename(Path);
|
|
if (IFileManager::Get().DirectoryExists(*Path))
|
|
{
|
|
IFileManager::Get().IterateDirectoryRecursively(*Path, [this](const TCHAR* Path, bool bIsDirectory)
|
|
{
|
|
if (!bIsDirectory && FPackageName::IsPackageFilename(Path))
|
|
{
|
|
FString FilePath(Path);
|
|
FPaths::NormalizeFilename(FilePath);
|
|
|
|
this->Packages.Add(MoveTemp(FilePath));
|
|
}
|
|
|
|
return true; // Continue
|
|
});
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogVirtualizationTool, Error, TEXT("Could not find the requested directory '%s'"), *Path);
|
|
return false;
|
|
}
|
|
}
|
|
else if (FParse::Value(*Switch, TEXT("Changelist="), ChangelistNumber))
|
|
{
|
|
return TryParseChangelist(ClientSpecName, ChangelistNumber, Packages);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool FRehydrateCommand::Run(const TArray<FProject>& Projects)
|
|
{
|
|
for (const FProject& Project : Projects)
|
|
{
|
|
TStringBuilder<128> ProjectName;
|
|
ProjectName << Project.GetProjectName();
|
|
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\tProcessing package(s) for the project '%s'..."), ProjectName.ToString());
|
|
|
|
FConfigFile EngineConfigWithProject;
|
|
if (!Project.TryLoadConfig(EngineConfigWithProject))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Project.RegisterMountPoints();
|
|
|
|
UE::Virtualization::FInitParams InitParams(ProjectName, EngineConfigWithProject);
|
|
UE::Virtualization::Initialize(InitParams, UE::Virtualization::EInitializationFlags::ForceInitialize);
|
|
|
|
ON_SCOPE_EXIT
|
|
{
|
|
UE::Virtualization::Shutdown();
|
|
};
|
|
|
|
const TArray<FString> ProjectPackages = Project.GetAllPackages();
|
|
|
|
if (!TryCheckOutFilesForProject(ClientSpecName, Project.GetProjectRoot(), ProjectPackages))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\t\tAttempting to rehydrate packages..."), ProjectName.ToString());
|
|
|
|
TArray<FText> Errors;
|
|
UE::Virtualization::IVirtualizationSystem::Get().TryRehydratePackages(ProjectPackages, Errors);
|
|
|
|
if (!Errors.IsEmpty())
|
|
{
|
|
UE_LOG(LogVirtualizationTool, Error, TEXT("The rehydration process failed with the following errors:"));
|
|
for (const FText& Error : Errors)
|
|
{
|
|
UE_LOG(LogVirtualizationTool, Error, TEXT("\t%s"), *Error.ToString());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Project.UnRegisterMountPoints();
|
|
|
|
UE_LOG(LogVirtualizationTool, Display, TEXT("\tRehyration of project packages complete"), ProjectName.ToString());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace UE::Virtualization
|