|
Unreal4源码拆解-UnrealBuildTool功能流程解析-PluginDescriptor
引擎版本4.27
4.2x功能不会差太多
功能漫谈
主要功能
- PluginDescriptor类,如其命名,插件描述信息。
- 功能上大致是以JSON的方式读取和更新 .uplugin文件 。
- 具体设计上类内变量名和JSON中项名相同。
- 注意:可读可写
.uplugin文件
首先.uplugin文件文件是JSON文件,在每个插件的主文件夹中描述插件信息的文件。举例: Engine\Plugins\2D\Paper2D\Paper2D.uplugin
{
"FileVersion" : 3,
"Version" : 1,
"VersionName" : "1.0",
"FriendlyName" : "Paper2D",
"Description" : "Paper2D adds tools and assets to help create 2D games including animated sprite assets, tilesets (experimental), 2D level editing tools, and more.",
"Category" : "2D",
"CreatedBy" : "Epic Games, Inc.",
"CreatedByURL" : "http://epicgames.com",
"DocsURL" : "",
"MarketplaceURL" : "",
"SupportURL" : "",
"EnabledByDefault" : true,
"CanContainContent" : true,
"IsBetaVersion" : false,
"Installed" : false,
"Modules" :
[
{
"Name" : "Paper2D",
"Type" : "Runtime",
"LoadingPhase" : "PreDefault"
},
{
"Name" : "Paper2DEditor",
"Type" : "Editor",
"LoadingPhase" : "Default"
},
{
"Name" : "PaperSpriteSheetImporter",
"Type" : "Editor",
"LoadingPhase" : "Default"
},
{
"Name" : "PaperTiledImporter",
"Type" : "Editor",
"LoadingPhase" : "Default"
},
{
"Name" : "SmartSnapping",
"Type" : "Editor",
"LoadingPhase" : "PostEngineInit"
}
]
}注意:此文章主要给接下来的UBT主流程做铺垫
注意:以后每更新变量的功能便会更新此文章
注意:插件以后有机会可以做专门的专栏
主要函数功能
public PluginDescriptor(JsonObject RawObject)
- 构造方法 传入JSON对象,解析每一个条目并设置到同名变量中
public static PluginDescriptor FromFile(FileReference FileName)
- 静态方法 传入文件,新建并且返回一个PluginDescriptor对象
public void Write(JsonWriter Writer)
public bool SupportsTargetPlatform(UnrealTargetPlatform Platform)
- 普通方法 输入目标平台信息,看看插件自己支不支持。
- 结果:如果插件支持平台没有配或者配了且支持该平台,返回True。
源代码
// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Tools.DotNETCommon;
namespace UnrealBuildTool
{
/// <summary>
/// The version format for .uplugin files. This rarely changes now; plugin descriptors should maintain backwards compatibility automatically.
/// </summary>
public enum PluginDescriptorVersion
{
/// <summary>
/// Invalid
/// </summary>
Invalid = 0,
/// <summary>
/// Initial version
/// </summary>
Initial = 1,
/// <summary>
/// Adding SampleNameHash
/// </summary>
NameHash = 2,
/// <summary>
/// Unifying plugin/project files (since abandoned, but backwards compatibility maintained)
/// </summary>
ProjectPluginUnification = 3,
/// <summary>
/// This needs to be the last line, so we can calculate the value of Latest below
/// </summary>
LatestPlusOne,
/// <summary>
/// The latest plugin descriptor version
/// </summary>
Latest = LatestPlusOne - 1
}
/// <summary>
/// In-memory representation of a .uplugin file
/// </summary>
public class PluginDescriptor
{
/// <summary>
/// Descriptor version number
/// </summary>
public int FileVersion;
/// <summary>
/// Version number for the plugin. The version number must increase with every version of the plugin, so that the system
/// can determine whether one version of a plugin is newer than another, or to enforce other requirements. This version
/// number is not displayed in front-facing UI. Use the VersionName for that.
/// </summary>
public int Version;
/// <summary>
/// Name of the version for this plugin. This is the front-facing part of the version number. It doesn&#39;t need to match
/// the version number numerically, but should be updated when the version number is increased accordingly.
/// </summary>
public string VersionName;
/// <summary>
/// Friendly name of the plugin
/// </summary>
public string FriendlyName;
/// <summary>
/// Description of the plugin
/// </summary>
public string Description;
/// <summary>
/// The name of the category this plugin
/// </summary>
public string Category;
/// <summary>
/// The company or individual who created this plugin. This is an optional field that may be displayed in the user interface.
/// </summary>
public string CreatedBy;
/// <summary>
/// Hyperlink URL string for the company or individual who created this plugin. This is optional.
/// </summary>
public string CreatedByURL;
/// <summary>
/// Documentation URL string.
/// </summary>
public string DocsURL;
/// <summary>
/// Marketplace URL for this plugin. This URL will be embedded into projects that enable this plugin, so we can redirect to the marketplace if a user doesn&#39;t have it installed.
/// </summary>
public string MarketplaceURL;
/// <summary>
/// Support URL/email for this plugin.
/// </summary>
public string SupportURL;
/// <summary>
/// Sets the version of the engine that this plugin is compatible with.
/// </summary>
public string EngineVersion;
/// <summary>4
/// If true, this plugin from a platform extension extending another plugin */
/// </summary>
public bool bIsPluginExtension;
/// <summary>
/// List of platforms supported by this plugin. This list will be copied to any plugin reference from a project file, to allow filtering entire plugins from staged builds.
/// </summary>
public List<UnrealTargetPlatform> SupportedTargetPlatforms;
/// <summary>
/// List of programs supported by this plugin.
/// </summary>
public string[] SupportedPrograms;
/// <summary>
/// List of all modules associated with this plugin
/// </summary>
public List<ModuleDescriptor> Modules;
/// <summary>
/// List of all localization targets associated with this plugin
/// </summary>
public LocalizationTargetDescriptor[] LocalizationTargets;
/// <summary>
/// Whether this plugin should be enabled by default for all projects
/// </summary>
public Nullable<bool> bEnabledByDefault;
/// <summary>
/// Can this plugin contain content?
/// </summary>
public bool bCanContainContent;
/// <summary>
/// Marks the plugin as beta in the UI
/// </summary>
public bool bIsBetaVersion;
/// <summary>
/// Marks the plugin as experimental in the UI
/// </summary>
public bool bIsExperimentalVersion;
/// <summary>
/// Set for plugins which are installed
/// </summary>
public bool bInstalled;
/// <summary>
/// For plugins that are under a platform folder (eg. /PS4/), determines whether compiling the plugin requires the build platform and/or SDK to be available
/// </summary>
public bool bRequiresBuildPlatform;
/// <summary>
/// When true, this plugin&#39;s modules will not be loaded automatically nor will it&#39;s content be mounted automatically. It will load/mount when explicitly requested and LoadingPhases will be ignored
/// </summary>
public bool bExplicitlyLoaded;
/// <summary>
/// Set of pre-build steps to execute, keyed by host platform name.
/// </summary>
public CustomBuildSteps PreBuildSteps;
/// <summary>
/// Set of post-build steps to execute, keyed by host platform name.
/// </summary>
public CustomBuildSteps PostBuildSteps;
/// <summary>
/// Additional plugins that this plugin depends on
/// </summary>
public List<PluginReferenceDescriptor> Plugins;
/// <summary>
/// Private constructor. This object should not be created directly; read it from disk using FromFile() instead.
/// </summary>
private PluginDescriptor()
{
FileVersion = (int)PluginDescriptorVersion.Latest;
}
/// <summary>
/// Reads a plugin descriptor from a json object
/// </summary>
/// <param name=&#34;RawObject&#34;>The object to read from</param>
/// <returns>New plugin descriptor</returns>
public PluginDescriptor(JsonObject RawObject)
{
// Read the version
if (!RawObject.TryGetIntegerField(&#34;FileVersion&#34;, out FileVersion))
{
if (!RawObject.TryGetIntegerField(&#34;PluginFileVersion&#34;, out FileVersion))
{
throw new BuildException(&#34;Plugin descriptor does not contain a valid FileVersion entry&#34;);
}
}
// Check it&#39;s not newer than the latest version we can parse
if (FileVersion > (int)PluginDescriptorVersion.Latest)
{
throw new BuildException(&#34;Plugin descriptor appears to be in a newer version ({0}) of the file format that we can load (max version: {1}).&#34;, FileVersion, (int)PluginDescriptorVersion.Latest);
}
// Read the other fields
RawObject.TryGetIntegerField(&#34;Version&#34;, out Version);
RawObject.TryGetStringField(&#34;VersionName&#34;, out VersionName);
RawObject.TryGetStringField(&#34;FriendlyName&#34;, out FriendlyName);
RawObject.TryGetStringField(&#34;Description&#34;, out Description);
if (!RawObject.TryGetStringField(&#34;Category&#34;, out Category))
{
// Category used to be called CategoryPath in .uplugin files
RawObject.TryGetStringField(&#34;CategoryPath&#34;, out Category);
}
// Due to a difference in command line parsing between Windows and Mac, we shipped a few Mac samples containing
// a category name with escaped quotes. Remove them here to make sure we can list them in the right category.
if (Category != null && Category.Length >= 2 && Category.StartsWith(&#34;\&#34;&#34;) && Category.EndsWith(&#34;\&#34;&#34;))
{
Category = Category.Substring(1, Category.Length - 2);
}
RawObject.TryGetStringField(&#34;CreatedBy&#34;, out CreatedBy);
RawObject.TryGetStringField(&#34;CreatedByURL&#34;, out CreatedByURL);
RawObject.TryGetStringField(&#34;DocsURL&#34;, out DocsURL);
RawObject.TryGetStringField(&#34;MarketplaceURL&#34;, out MarketplaceURL);
RawObject.TryGetStringField(&#34;SupportURL&#34;, out SupportURL);
RawObject.TryGetStringField(&#34;EngineVersion&#34;, out EngineVersion);
RawObject.TryGetStringArrayField(&#34;SupportedPrograms&#34;, out SupportedPrograms);
RawObject.TryGetBoolField(&#34;bIsPluginExtension&#34;, out bIsPluginExtension);
string[] SupportedTargetPlatformNames;
if (RawObject.TryGetStringArrayField(&#34;SupportedTargetPlatforms&#34;, out SupportedTargetPlatformNames))
{
SupportedTargetPlatforms = new List<UnrealTargetPlatform>();
foreach (string TargetPlatformName in SupportedTargetPlatformNames)
{
UnrealTargetPlatform Platform;
if (UnrealTargetPlatform.TryParse(TargetPlatformName, out Platform))
{
SupportedTargetPlatforms.Add(Platform);
}
else
{
Log.TraceWarning(&#34;Unknown platform {0} listed in plugin with FriendlyName {1}&#34;, TargetPlatformName, FriendlyName);
}
}
}
JsonObject[] ModulesArray;
if (RawObject.TryGetObjectArrayField(&#34;Modules&#34;, out ModulesArray))
{
Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)).ToList();
}
JsonObject[] LocalizationTargetsArray;
if (RawObject.TryGetObjectArrayField(&#34;LocalizationTargets&#34;, out LocalizationTargetsArray))
{
LocalizationTargets = Array.ConvertAll(LocalizationTargetsArray, x => LocalizationTargetDescriptor.FromJsonObject(x));
}
bool bEnabledByDefaultValue;
if(RawObject.TryGetBoolField(&#34;EnabledByDefault&#34;, out bEnabledByDefaultValue))
{
bEnabledByDefault = bEnabledByDefaultValue;
}
RawObject.TryGetBoolField(&#34;CanContainContent&#34;, out bCanContainContent);
RawObject.TryGetBoolField(&#34;IsBetaVersion&#34;, out bIsBetaVersion);
RawObject.TryGetBoolField(&#34;IsExperimentalVersion&#34;, out bIsExperimentalVersion);
RawObject.TryGetBoolField(&#34;Installed&#34;, out bInstalled);
bool bCanBeUsedWithUnrealHeaderTool;
if(RawObject.TryGetBoolField(&#34;CanBeUsedWithUnrealHeaderTool&#34;, out bCanBeUsedWithUnrealHeaderTool) && bCanBeUsedWithUnrealHeaderTool)
{
Array.Resize(ref SupportedPrograms, (SupportedPrograms == null)? 1 : SupportedPrograms.Length + 1);
SupportedPrograms[SupportedPrograms.Length - 1] = &#34;UnrealHeaderTool&#34;;
}
RawObject.TryGetBoolField(&#34;RequiresBuildPlatform&#34;, out bRequiresBuildPlatform);
RawObject.TryGetBoolField(&#34;ExplicitlyLoaded&#34;, out bExplicitlyLoaded);
CustomBuildSteps.TryRead(RawObject, &#34;PreBuildSteps&#34;, out PreBuildSteps);
CustomBuildSteps.TryRead(RawObject, &#34;PostBuildSteps&#34;, out PostBuildSteps);
JsonObject[] PluginsArray;
if(RawObject.TryGetObjectArrayField(&#34;Plugins&#34;, out PluginsArray))
{
Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)).ToList();
}
}
/// <summary>
/// Creates a plugin descriptor from a file on disk
/// </summary>
/// <param name=&#34;FileName&#34;>The filename to read</param>
/// <returns>New plugin descriptor</returns>
public static PluginDescriptor FromFile(FileReference FileName)
{
JsonObject RawObject = JsonObject.Read(FileName);
try
{
PluginDescriptor Descriptor = new PluginDescriptor(RawObject);
if (Descriptor.Modules != null)
{
foreach (ModuleDescriptor Module in Descriptor.Modules)
{
Module.Validate(FileName);
}
}
return Descriptor;
}
catch (JsonParseException ParseException)
{
throw new JsonParseException(&#34;{0} (in {1})&#34;, ParseException.Message, FileName);
}
}
/// <summary>
/// Saves the descriptor to disk
/// </summary>
/// <param name=&#34;FileName&#34;>The filename to write to</param>
public void Save(string FileName)
{
using (JsonWriter Writer = new JsonWriter(FileName))
{
Writer.WriteObjectStart();
Write(Writer);
Writer.WriteObjectEnd();
}
}
/// <summary>
/// Writes the plugin descriptor to an existing Json writer
/// </summary>
/// <param name=&#34;Writer&#34;>The writer to receive plugin data</param>
public void Write(JsonWriter Writer)
{
Writer.WriteValue(&#34;FileVersion&#34;, (int)ProjectDescriptorVersion.Latest);
Writer.WriteValue(&#34;Version&#34;, Version);
Writer.WriteValue(&#34;VersionName&#34;, VersionName);
Writer.WriteValue(&#34;FriendlyName&#34;, FriendlyName);
Writer.WriteValue(&#34;Description&#34;, Description);
Writer.WriteValue(&#34;Category&#34;, Category);
Writer.WriteValue(&#34;CreatedBy&#34;, CreatedBy);
Writer.WriteValue(&#34;CreatedByURL&#34;, CreatedByURL);
Writer.WriteValue(&#34;DocsURL&#34;, DocsURL);
Writer.WriteValue(&#34;MarketplaceURL&#34;, MarketplaceURL);
Writer.WriteValue(&#34;SupportURL&#34;, SupportURL);
if(!String.IsNullOrEmpty(EngineVersion))
{
Writer.WriteValue(&#34;EngineVersion&#34;, EngineVersion);
}
if(bEnabledByDefault.HasValue)
{
Writer.WriteValue(&#34;EnabledByDefault&#34;, bEnabledByDefault.Value);
}
Writer.WriteValue(&#34;CanContainContent&#34;, bCanContainContent);
if (bIsBetaVersion)
{
Writer.WriteValue(&#34;IsBetaVersion&#34;, bIsBetaVersion);
}
if (bIsExperimentalVersion)
{
Writer.WriteValue(&#34;IsExperimentalVersion&#34;, bIsExperimentalVersion);
}
if (bInstalled)
{
Writer.WriteValue(&#34;Installed&#34;, bInstalled);
}
if(bRequiresBuildPlatform)
{
Writer.WriteValue(&#34;RequiresBuildPlatform&#34;, bRequiresBuildPlatform);
}
if (bExplicitlyLoaded)
{
Writer.WriteValue(&#34;ExplicitlyLoaded&#34;, bExplicitlyLoaded);
}
if(SupportedTargetPlatforms != null && SupportedTargetPlatforms.Count > 0)
{
Writer.WriteStringArrayField(&#34;SupportedTargetPlatforms&#34;, SupportedTargetPlatforms.Select<UnrealTargetPlatform, string>(x => x.ToString()).ToArray());
}
if (SupportedPrograms != null && SupportedPrograms.Length > 0)
{
Writer.WriteStringArrayField(&#34;SupportedPrograms&#34;, SupportedPrograms);
}
if (bIsPluginExtension)
{
Writer.WriteValue(&#34;bIsPluginExtension&#34;, bIsPluginExtension);
}
if (Modules != null && Modules.Count > 0)
{
ModuleDescriptor.WriteArray(Writer, &#34;Modules&#34;, Modules.ToArray());
}
LocalizationTargetDescriptor.WriteArray(Writer, &#34;LocalizationTargets&#34;, LocalizationTargets);
if(PreBuildSteps != null)
{
PreBuildSteps.Write(Writer, &#34;PreBuildSteps&#34;);
}
if(PostBuildSteps != null)
{
PostBuildSteps.Write(Writer, &#34;PostBuildSteps&#34;);
}
if (Plugins != null && Plugins.Count > 0)
{
PluginReferenceDescriptor.WriteArray(Writer, &#34;Plugins&#34;, Plugins.ToArray());
}
}
/// <summary>
/// Determines if this reference enables the plugin for a given platform
/// </summary>
/// <param name=&#34;Platform&#34;>The platform to check</param>
/// <returns>True if the plugin should be enabled</returns>
public bool SupportsTargetPlatform(UnrealTargetPlatform Platform)
{
return SupportedTargetPlatforms == null || SupportedTargetPlatforms.Count == 0 || SupportedTargetPlatforms.Contains(Platform);
}
}
} |
|