4.7 KiB
Raw Blame History

ModuleRelativePath

  • 功能描述: 记录类型定义的的头文件路径,为其处于模块的内部相对路径。
  • 使用位置: Any
  • 引擎模块: UHT
  • 元数据类型: string="abc"
  • 常用程度: 0

记录当前元类型定义的的头文件路径,为相对模块的相对路径。

对于开发者来说一般不用管,但是引擎编辑器会用它来定位某个类型是在哪个.h里定义的从而在你双击类型的时候可以为你在VS里打开相应的头文件。具体的逻辑可以去FSourceCodeNavigation里查看。

和IncludePath的区别是ModuleRelativePath 在各种类型信息上都有而IncludePath只用于UCLASS上。另外ModuleRelativePath 的值可以包含“Classes/Public/Internal/Private”这4个以开头我们一般也确实会建议把.h.cpp划分到这4个文件夹里。而IncludeFilePath 的值就会去掉这个头。

测试代码:

UCLASS(BlueprintType)
class INSIDER_API UMyProperty_Template :public UObject
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable)
	int32 MyFunc(FString str){return 0;}
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	int32 MyProperty = 123;
};

其元类型信息打印:

可以发现ModuleRelativePath 在类,属性和函数上都有该信息。

而IncludePath只有在UCLASS上才有。

[class MyProperty_Template	Class->Struct->Field->Object	/Script/Insider.MyProperty_Template]
(BlueprintType = true, IncludePath = Property/MyProperty_Template.h, ModuleRelativePath = Property/MyProperty_Template.h)
	ObjectFlags:	RF_Public | RF_Standalone | RF_Transient 
	Outer:	Package /Script/Insider
	ClassHierarchy:	MyProperty_Template:Object
	ClassFlags:	CLASS_MatchedSerializers | CLASS_Native | CLASS_RequiredAPI | CLASS_TokenStreamAssembled | CLASS_Intrinsic | CLASS_Constructed 
	Size:	56
	Within:	Object
	ClassConfigName:	Engine
{
	(Category = MyProperty_Template, ModuleRelativePath = Property/MyProperty_Template.h)
	48-[4] int32 MyProperty;
		PropertyFlags:	CPF_Edit | CPF_BlueprintVisible | CPF_ZeroConstructor | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic 
		ObjectFlags:	RF_Public | RF_MarkAsNative | RF_Transient 
		Outer:	Class /Script/Insider.MyProperty_Template
		Path:	IntProperty /Script/Insider.MyProperty_Template:MyProperty
	[func MyFunc	Function->Struct->Field->Object	/Script/Insider.MyProperty_Template:MyFunc]
	(ModuleRelativePath = Property/MyProperty_Template.h)
		ObjectFlags:	RF_Public | RF_Transient 
		Outer:	Class /Script/Insider.MyProperty_Template
		FunctionFlags:	FUNC_Final | FUNC_Native | FUNC_Public | FUNC_BlueprintCallable 
		NumParms:	2
		ParmsSize:	20
		ReturnValueOffset:	16
		RPCId:	0
		RPCResponseId:	0
		public int32 MyFunc(FString str)final;
	{
		0-[16] FString str;
			PropertyFlags:	CPF_Parm | CPF_ZeroConstructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic 
			ObjectFlags:	RF_Public | RF_MarkAsNative | RF_Transient 
			Outer:	Function /Script/Insider.MyProperty_Template:MyFunc
			Path:	StrProperty /Script/Insider.MyProperty_Template:MyFunc:str
		16-[4] int32 ReturnValue;
			PropertyFlags:	CPF_Parm | CPF_OutParm | CPF_ZeroConstructor | CPF_ReturnParm | CPF_IsPlainOldData | CPF_NoDestructor | CPF_HasGetValueTypeHash | CPF_NativeAccessSpecifierPublic 
			ObjectFlags:	RF_Public | RF_MarkAsNative | RF_Transient 
			Outer:	Function /Script/Insider.MyProperty_Template:MyFunc
			Path:	IntProperty /Script/Insider.MyProperty_Template:MyFunc:ReturnValue
	};
};

原理:

在UHT分析的时候自动的为类型加上头文件的路径信息。

从源码逻辑可以看出ModuleRelativePath 的值可以包含“Classes/Public/Internal/Private”这4个以开头我们一般也确实会建议把.h.cpp划分到这4个文件夹里。而IncludeFilePath 的值就会去掉这个头。


public enum UhtHeaderFileType
{

	/// <summary>
	/// Classes folder
	/// </summary>
	Classes,

	/// <summary>
	/// Public folder
	/// </summary>
	Public,

	/// <summary>
	/// Internal folder
	/// </summary>
	Internal,

	/// <summary>
	/// Private folder
	/// </summary>
	Private,
}

public static void AddModuleRelativePathToMetaData(UhtMetaData metaData, UhtHeaderFile headerFile)
{
	metaData.Add(UhtNames.ModuleRelativePath, headerFile.ModuleRelativeFilePath);
}

//分析文件路径
private void StepPrepareHeaders(UhtPackage package, IEnumerable<string> headerFiles, UhtHeaderFileType headerFileType)
{
	string typeDirectory = headerFileType.ToString() + '/';
	
	headerFile.ModuleRelativeFilePath = normalizedFullFilePath[stripLength..];
	if (normalizedFullFilePath[stripLength..].StartsWith(typeDirectory, true, null))
	{
					stripLength += typeDirectory.Length;
	}
	headerFile.IncludeFilePath = normalizedFullFilePath[stripLength..];
}