Files
UnrealEngineUWP/Engine/Source/Developer/DesktopPlatform/Private/PlatformInfo.cpp
Ben Marsh 0cc6e3dca6 Copying //UE4/Dev-Build to Dev-Main (//UE4/Dev-Main)
#rb none
#rnx

[CL 6631504 by Ben Marsh in Main branch]
2019-05-24 11:51:54 -04:00

357 lines
13 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "PlatformInfo.h"
#include "DesktopPlatformPrivate.h"
#include "Misc/DataDrivenPlatformInfoRegistry.h"
#include "HAL/FileManager.h"
#include "Misc/Paths.h"
#define LOCTEXT_NAMESPACE "PlatformInfo"
namespace PlatformInfo
{
TArray<FName> AllPlatformGroupNames;
TArray<FName> AllVanillaPlatformNames;
namespace
{
TArray<FPlatformInfo> AllPlatformInfoArray;
// we don't need any of this without the editor, although we would ideally not even compile this outside of the editor
// @todo platplug: Figure out why this is compiled on target devices
#if WITH_EDITOR
void BuildPlatformInfo(const FName& InPlatformInfoName, const FName& InTargetPlatformName, const FText& InDisplayName, const EPlatformType InPlatformType, const EPlatformFlags::Flags InPlatformFlags, const FPlatformIconPaths& InIconPaths, const FString& InUATCommandLine, const FString& InAutoSDKPath, EPlatformSDKStatus InStatus, const FString& InTutorial, bool InEnabled, FString InBinaryFolderName, FString InIniPlatformName, bool InUsesHostCompiler, bool InUATClosesAfterLaunch, bool InIsConfidential, const FName& InUBTTargetId, const FName& InPlatformGroupName)
{
FPlatformInfo& PlatformInfo = AllPlatformInfoArray.Emplace_GetRef();
PlatformInfo.PlatformInfoName = InPlatformInfoName;
PlatformInfo.TargetPlatformName = InTargetPlatformName;
// See if this name also contains a flavor
const FString InPlatformInfoNameString = InPlatformInfoName.ToString();
{
int32 UnderscoreLoc;
if(InPlatformInfoNameString.FindChar(TEXT('_'), UnderscoreLoc))
{
PlatformInfo.VanillaPlatformName = *InPlatformInfoNameString.Mid(0, UnderscoreLoc);
PlatformInfo.PlatformFlavor = *InPlatformInfoNameString.Mid(UnderscoreLoc + 1);
}
else
{
PlatformInfo.VanillaPlatformName = InPlatformInfoName;
}
}
if (PlatformInfo.VanillaPlatformName != NAME_None)
{
PlatformInfo::AllVanillaPlatformNames.AddUnique(PlatformInfo.VanillaPlatformName);
}
PlatformInfo.DisplayName = InDisplayName;
PlatformInfo.PlatformType = InPlatformType;
PlatformInfo.PlatformFlags = InPlatformFlags;
PlatformInfo.IconPaths = InIconPaths;
PlatformInfo.UATCommandLine = InUATCommandLine;
PlatformInfo.AutoSDKPath = InAutoSDKPath;
PlatformInfo.BinaryFolderName = InBinaryFolderName;
PlatformInfo.IniPlatformName = InIniPlatformName;
PlatformInfo.UBTTargetId = InUBTTargetId;
PlatformInfo.PlatformGroupName = InPlatformGroupName;
if (InPlatformGroupName != NAME_None)
{
PlatformInfo::AllPlatformGroupNames.AddUnique(InPlatformGroupName);
}
// Generate the icon style names for FEditorStyle
PlatformInfo.IconPaths.NormalStyleName = *FString::Printf(TEXT("Launcher.Platform_%s"), *InPlatformInfoNameString);
PlatformInfo.IconPaths.LargeStyleName = *FString::Printf(TEXT("Launcher.Platform_%s.Large"), *InPlatformInfoNameString);
PlatformInfo.IconPaths.XLargeStyleName = *FString::Printf(TEXT("Launcher.Platform_%s.XLarge"), *InPlatformInfoNameString);
// SDK data
PlatformInfo.SDKStatus = InStatus;
PlatformInfo.SDKTutorial = InTutorial;
// Distribution data
PlatformInfo.bEnabledForUse = InEnabled;
PlatformInfo.bUsesHostCompiler = InUsesHostCompiler;
PlatformInfo.bUATClosesAfterLaunch = InUATClosesAfterLaunch;
PlatformInfo.bIsConfidential = InIsConfidential;
}
void BuildHardcodedPlatforms()
{
// PlatformInfoName TargetPlatformName DisplayName PlatformType PlatformFlags IconPaths UATCommandLine AutoSDKPath SDKStatus SDKTutorial bEnabledForUse BinaryFolderName IniPlatformName FbUsesHostCompiler bUATClosesAfterLaunch bIsConfidential UBTTargetId (match UBT's UnrealTargetPlatform enum)
BuildPlatformInfo(TEXT("AllDesktop"), TEXT("AllDesktop"), LOCTEXT("DesktopTargetPlatDisplay", "Desktop (Win+Mac+Linux)"), EPlatformType::Game, EPlatformFlags::None, FPlatformIconPaths(TEXT("Launcher/Desktop/Platform_Desktop_24x"), TEXT("Launcher/Desktop/Platform_Desktop_128x")), TEXT(""), TEXT(""), EPlatformSDKStatus::Unknown, TEXT(""), PLATFORM_WINDOWS /* see note below */, TEXT(""), TEXT(""), false, true, false, TEXT("AllDesktop"), TEXT("Desktop"));
// Note: For "AllDesktop" bEnabledForUse value, see SProjectTargetPlatformSettings::Construct !!!! IsAvailableOnWindows || IsAvailableOnMac || IsAvailableOnLinux
}
// Gets a string from a section, or empty string if it didn't exist
FString GetSectionString(const FConfigSection& Section, FName Key)
{
// look for a value prefixed with host:
FName HostKey = *FString::Printf(TEXT("%s:%s"), ANSI_TO_TCHAR(FPlatformProperties::IniPlatformName()), *Key.ToString());
const FConfigValue* HostValue = Section.Find(HostKey);
return HostValue ? HostValue->GetValue() : Section.FindRef(Key).GetValue();
}
// Gets a bool from a section, or false if it didn't exist
bool GetSectionBool(const FConfigSection& Section, FName Key)
{
return FCString::ToBool(*GetSectionString(Section, Key));
}
EPlatformFlags::Flags ConvertPlatformFlags(const FString& String)
{
if (String == TEXT("") == 0 || String == TEXT("None")) { return EPlatformFlags::None; }
if (String == TEXT("CookFlavor")) { return EPlatformFlags::CookFlavor; }
if (String == TEXT("BuildFlavor")) { return EPlatformFlags::BuildFlavor; }
UE_LOG(LogInit, Fatal, TEXT("Unknown platform flag %s in PlatformInfo"), *String);
return EPlatformFlags::None;
}
void ParseDataDrivenPlatformInfo(const TCHAR* Name, const FConfigSection& Section)
{
// @todo platplug: use FNames instead of TCHAR* for keys, so we don't ahve to re-convert every time
FName TargetPlatformName = *GetSectionString(Section, TEXT("TargetPlatformName"));
FString DisplayName = GetSectionString(Section, TEXT("DisplayName"));
FString PlatformType = GetSectionString(Section, TEXT("PlatformType"));
FString PlatformFlags = GetSectionString(Section, TEXT("PlatformFlags"));
FString NormalIconPath = GetSectionString(Section, TEXT("NormalIconPath"));
FString LargeIconPath = GetSectionString(Section, TEXT("LargeIconPath"));
FString XLargeIconPath = GetSectionString(Section, TEXT("XLargeIconPath"));
// no one has an XLarge path yet, but in case they add one, this will use it
if (XLargeIconPath == TEXT(""))
{
XLargeIconPath = LargeIconPath;
}
FString UATCommandLine = GetSectionString(Section, TEXT("UATCommandLine"));
FString AutoSDKPath = GetSectionString(Section, TEXT("AutoSDKPath"));
FString TutorialPath = GetSectionString(Section, TEXT("TutorialPath"));
bool bIsEnabled = GetSectionBool(Section, TEXT("bIsEnabled"));
FString BinariesDirectoryName = GetSectionString(Section, TEXT("BinariesDirectoryName"));
FString IniPlatformName = GetSectionString(Section, TEXT("IniPlatformName"));
bool bUsesHostCompiler = GetSectionBool(Section, TEXT("bUsesHostCompiler"));
bool bUATClosesAfterLaunch = GetSectionBool(Section, TEXT("bUATClosesAfterLaunch"));
bool bIsConfidential = GetSectionBool(Section, TEXT("bIsConfidential"));
FName UBTTargetID = *GetSectionString(Section, TEXT("UBTTargetID"));
FName PlatformGroupName = *GetSectionString(Section, TEXT("PlatformGroupName"));
BuildPlatformInfo(Name, TargetPlatformName, FText::FromString(DisplayName), EPlatformTypeFromString(*PlatformType), ConvertPlatformFlags(PlatformFlags), FPlatformIconPaths(NormalIconPath, LargeIconPath, XLargeIconPath), UATCommandLine,
AutoSDKPath, PlatformInfo::EPlatformSDKStatus::Unknown, TutorialPath, bIsEnabled, BinariesDirectoryName, IniPlatformName, bUsesHostCompiler, bUATClosesAfterLaunch, bIsConfidential, UBTTargetID, PlatformGroupName);
}
void LoadDataDrivenPlatforms()
{
// look for the standard DataDriven ini files
int32 NumDDInfoFiles = FDataDrivenPlatformInfoRegistry::GetNumDataDrivenIniFiles();
for (int32 Index = 0; Index < NumDDInfoFiles; Index++)
{
FConfigFile IniFile;
FString PlatformName;
FDataDrivenPlatformInfoRegistry::LoadDataDrivenIniFile(Index, IniFile, PlatformName);
// now walk over the file, looking for ShaderPlatformInfo sections
for (auto Section : IniFile)
{
if (Section.Key.StartsWith(TEXT("PlatformInfo ")))
{
const FString& SectionName = Section.Key;
ParseDataDrivenPlatformInfo(*SectionName.Mid(13), Section.Value);
}
}
}
}
struct FPlatformInfoAutoInit
{
FPlatformInfoAutoInit()
{
FCoreDelegates::ConfigReadyForUse.AddLambda([]
{
BuildHardcodedPlatforms();
LoadDataDrivenPlatforms();
});
}
} GPlatformInfoAutoInit;
#endif
} // anonymous namespace
const FPlatformInfo* FindPlatformInfo(const FName& InPlatformName)
{
for(const FPlatformInfo& PlatformInfo : AllPlatformInfoArray)
{
if(PlatformInfo.PlatformInfoName == InPlatformName)
{
return &PlatformInfo;
}
}
return nullptr;
}
const FPlatformInfo* FindVanillaPlatformInfo(const FName& InPlatformName)
{
const FPlatformInfo* const FoundInfo = FindPlatformInfo(InPlatformName);
return (FoundInfo) ? (FoundInfo->IsVanilla()) ? FoundInfo : FindPlatformInfo(FoundInfo->VanillaPlatformName) : nullptr;
}
void UpdatePlatformSDKStatus(FString InPlatformName, EPlatformSDKStatus InStatus)
{
for(const FPlatformInfo& PlatformInfo : AllPlatformInfoArray)
{
if(PlatformInfo.VanillaPlatformName == FName(*InPlatformName))
{
const_cast<FPlatformInfo&>(PlatformInfo).SDKStatus = InStatus;
}
}
}
void UpdatePlatformDisplayName(FString InPlatformName, FText InDisplayName)
{
for (const FPlatformInfo& PlatformInfo : AllPlatformInfoArray)
{
if (PlatformInfo.TargetPlatformName == FName(*InPlatformName))
{
const_cast<FPlatformInfo&>(PlatformInfo).DisplayName = InDisplayName;
}
}
}
const TArray<FPlatformInfo>& GetPlatformInfoArray()
{
return AllPlatformInfoArray;
}
TArray<FVanillaPlatformEntry> BuildPlatformHierarchy(const EPlatformFilter InFilter)
{
TArray<FVanillaPlatformEntry> VanillaPlatforms;
// Build up a tree from the platforms we support (vanilla outers, with a list of flavors)
// PlatformInfoArray should be ordered in such a way that the vanilla platforms always appear before their flavors
for (const PlatformInfo::FPlatformInfo& PlatformInfo : AllPlatformInfoArray)
{
if(PlatformInfo.IsVanilla())
{
VanillaPlatforms.Add(FVanillaPlatformEntry(&PlatformInfo));
}
else
{
const bool bHasBuildFlavor = !!(PlatformInfo.PlatformFlags & EPlatformFlags::BuildFlavor);
const bool bHasCookFlavor = !!(PlatformInfo.PlatformFlags & EPlatformFlags::CookFlavor);
const bool bValidFlavor =
InFilter == EPlatformFilter::All ||
(InFilter == EPlatformFilter::BuildFlavor && bHasBuildFlavor) ||
(InFilter == EPlatformFilter::CookFlavor && bHasCookFlavor);
if(bValidFlavor)
{
const FName VanillaPlatformName = PlatformInfo.VanillaPlatformName;
FVanillaPlatformEntry* const VanillaEntry = VanillaPlatforms.FindByPredicate([VanillaPlatformName](const FVanillaPlatformEntry& Item) -> bool
{
return Item.PlatformInfo->PlatformInfoName == VanillaPlatformName;
});
check(VanillaEntry);
VanillaEntry->PlatformFlavors.Add(&PlatformInfo);
}
}
}
return VanillaPlatforms;
}
FVanillaPlatformEntry BuildPlatformHierarchy(const FName& InPlatformName, const EPlatformFilter InFilter)
{
FVanillaPlatformEntry VanillaPlatformEntry;
const FPlatformInfo* VanillaPlatformInfo = FindVanillaPlatformInfo(InPlatformName);
if (VanillaPlatformInfo)
{
VanillaPlatformEntry.PlatformInfo = VanillaPlatformInfo;
for (const PlatformInfo::FPlatformInfo& PlatformInfo : AllPlatformInfoArray)
{
if (!PlatformInfo.IsVanilla() && PlatformInfo.VanillaPlatformName == VanillaPlatformInfo->PlatformInfoName)
{
const bool bHasBuildFlavor = !!(PlatformInfo.PlatformFlags & EPlatformFlags::BuildFlavor);
const bool bHasCookFlavor = !!(PlatformInfo.PlatformFlags & EPlatformFlags::CookFlavor);
const bool bValidFlavor =
InFilter == EPlatformFilter::All ||
(InFilter == EPlatformFilter::BuildFlavor && bHasBuildFlavor) ||
(InFilter == EPlatformFilter::CookFlavor && bHasCookFlavor);
if (bValidFlavor)
{
VanillaPlatformEntry.PlatformFlavors.Add(&PlatformInfo);
}
}
}
}
return VanillaPlatformEntry;
}
EPlatformType EPlatformTypeFromString(const FString& PlatformTypeName)
{
if (FCString::Strcmp(*PlatformTypeName, TEXT("Game")) == 0)
{
return PlatformInfo::EPlatformType::Game;
}
else if (FCString::Strcmp(*PlatformTypeName, TEXT("Editor")) == 0)
{
return PlatformInfo::EPlatformType::Editor;
}
else if (FCString::Strcmp(*PlatformTypeName, TEXT("Client")) == 0)
{
return PlatformInfo::EPlatformType::Client;
}
else if (FCString::Strcmp(*PlatformTypeName, TEXT("Server")) == 0)
{
return PlatformInfo::EPlatformType::Server;
}
else
{
UE_LOG(LogDesktopPlatform, Warning, TEXT("Unable to read Platform Type from %s, defaulting to Game"), *PlatformTypeName);
return PlatformInfo::EPlatformType::Game;
}
}
const TArray<FName>& GetAllPlatformGroupNames()
{
return PlatformInfo::AllPlatformGroupNames;
}
const TArray<FName>& GetAllVanillaPlatformNames()
{
return PlatformInfo::AllVanillaPlatformNames;
}
} // namespace PlatformInfo
FString LexToString(const PlatformInfo::EPlatformType Value)
{
switch (Value)
{
case PlatformInfo::EPlatformType::Game:
return TEXT("Game");
case PlatformInfo::EPlatformType::Editor:
return TEXT("Editor");
case PlatformInfo::EPlatformType::Client:
return TEXT("Client");
case PlatformInfo::EPlatformType::Server:
return TEXT("Server");
}
return TEXT("");
}
#undef LOCTEXT_NAMESPACE