【UE C++】リソースの読み込み (3) 同期読み込み - LoadObject

【UE C++】リソースの読み込み (3) 同期読み込み - LoadObject

一般的に使用される同期読み込み方法には、、、、、、LoadObjectなど含まれますその中でも代表的なロード処理ですが、の実行処理をもとに以下のシーケンスを紹介します。他の API 実行プロセスの読者は、以下の図を参照するか、ソース コードを入力して表示できます。LoadClassLoadPackageFSoftObjectPath::TryLoadFStreamableManager::RequestSyncLoadFStreamableManager::LoadSynchronousLoadObjectLoadObjectLoadClass
オブジェクトのロード

FStreamableManager::RequestSyncLoadFStreamableManager::LoadSynchronousその他の同期読み込み方法については、次の記事で非同期読み込みとともに分析します。使用例は記事の最後にあります。

1. ロードオブジェクト

機能:まず、対象のリソースがメモリ上に存在するかどうかを検索し、存在する場合はそのままリターンし、存在しない場合はパスをパッケージに変換してテンプレート化しLoadPackage

LoadObjectますStaticLoadObject

template< class T > 
inline T* LoadObject( UObject* Outer, const TCHAR* Name, const TCHAR* Filename=nullptr, uint32 LoadFlags=LOAD_None, UPackageMap* Sandbox=nullptr )
{
	return (T*)StaticLoadObject( T::StaticClass(), Outer, Name, Filename, LoadFlags, Sandbox );
}

入力パラメータ:

  • 外側:リソースの外側。オブジェクトの検索/読み込みの場所を絞り込むために使用されるオプションのオブジェクト。
  • 名前:オブジェクトの文字列名。完全な参照パスではない場合は、外部パスまたはファイル名、あるいはその両方を指定する必要があります
  • ファイル名:ロードできるファイルの名前 (またはファイルの Package オブジェクトで見つかります)
  • LoadFlags:ディスクからロードされたフラグの処理方法を制御します、ELoadFlags 列挙型
  • サンドボックス:検索オブジェクト、ネットワーク通信に使用されるパラメータを制限するために使用されるパッケージのリスト

2.静的ロードオブジェクト

内部呼び出しがStaticLoadObjectInternal見つからない場合は、エラーメッセージが出力されます。

3. StaticLoadObjectInternal

最初に呼び出されますResolveName。この関数は、前の記事で説明しました。その機能は、受信パスを解析することです。このパスは、完全なパス、または受信アウターに対する相対パスである必要があります。その後、アウターは、指定されたパスに設定されますPath.Package オブジェクトによって StrName が Path が指すオブジェクトの NamePrivate に設定されます。

ここでのStaticFindObject呼び出しResolveNameとの違いは、渡された最後の 2 つの bool 値が true であることです。これは、メモリに存在しないパッケージをロードまたは作成しようとし、パッケージをロードできない場合に警告がスローされることを意味します。見つかった。

// break up the name into packages, returning the innermost name and its outer
ResolveName(InOuter, StrName, true, true, LoadFlags & (LOAD_EditorOnly | LOAD_NoVerify | LOAD_Quiet | LOAD_NoWarn | LOAD_DeferDependencyLoads), InstancingContext);

次に、 を呼び出してStaticFindObjectFastメモリ内のリソース オブジェクトを検索し、オブジェクトがロードされているかどうかを確認します。ロードが完了した場合は、戻り値を返します。

Result = StaticFindObjectFast(ObjectClass, InOuter, *StrName);
if (Result && Result->HasAnyFlags(RF_NeedLoad | RF_NeedPostLoad | RF_NeedPostLoadSubobjects | RF_WillBeLoaded))
{
    // Object needs loading so load it before returning
    Result = nullptr;
}

ターゲットのリソース オブジェクトがメモリ内に見つからない場合は、リソース オブジェクトが属するパッケージをメモリにロードすることを検討してください。

パッケージ内に複数のリソースがあり、それらがハード ディスク上の同じファイルに対応する場合は、このファイルをロードするだけで済みます。

// now that we have one asset per package, we load the entire package whenever a single object is requested
LoadPackage(NULL, *InOuter->GetOutermost()->GetName(), LoadFlags & ~LOAD_Verify, nullptr, InstancingContext);

その後、再度呼び出されてStaticFindObjectFastメモリ内のリソース オブジェクトを検索し、まだ見つからない場合は、リソース オブジェクトがリダイレクトされているかどうかを判断してFindObjectFast検索します。

// If the object was not found, check for a redirector and follow it if the class matches
if (!Result && !(LoadFlags & LOAD_NoRedirects))
{
    UObjectRedirector* Redirector = FindObjectFast<UObjectRedirector>(InOuter, *StrName);
    if (Redirector && Redirector->DestinationObject && Redirector->DestinationObject->IsA(ObjectClass))
    {
        return Redirector->DestinationObject;
    }
}

4.パッケージのロード

機能:パッケージと、コンテキスト フラグに一致するすべての含まれるオブジェクトをロードします。

内部呼び出しLoadPackageInternal、入力パラメータは次のとおりです (最初の 3 つだけがリストされています)。

  • InOuter:指定した場合は、InOuter->GetPathName() が読み込みパスとして使用され、nullptr の場合は、InLongPackageName が読み込みパスとして使用されます。
  • InLongPackageName: InOuter が nullptr の場合、InLongPackageName が読み込みパスとして使用されます。
  • LoadFlags:ディスクからロードされたフラグの処理方法を制御します、ELoadFlags 列挙型

5.LoadPackageInternal

内部実装は比較的複雑なので、私の能力不足で申し訳ありませんが、分析は行っていません。

この関数は最終的に呼び出されLoadPackageAsync、これが非同期ロードのエントリ ポイントとなり、最後にFlushAsyncLoading内部ブロッキング待機によって非同期ロードが同期に変わります。
LoadPackageAsync関数、この関数は UE4 リソース読み込みのメインの入り口であり、リソース読み込みのセット全体はこの関数の背後に隠されています。

int32 RequestID = LoadPackageAsync(InName, nullptr, *InPackageName);

if (RequestID != INDEX_NONE)
{
    FlushAsyncLoading(RequestID);
}

Result = (InOuter ? InOuter : FindObjectFast<UPackage>(nullptr, PackageFName));
return Result;

6. ロードクラス

機能:クラスリソースのロードは

テンプレート化されておりStaticLoadClass、パラメータ入力はLoadObjectまったく同じです。

template< class T > 
inline UClass* LoadClass( UObject* Outer, const TCHAR* Name, const TCHAR* Filename=nullptr, uint32 LoadFlags=LOAD_None, UPackageMap* Sandbox=nullptr )
{
	return StaticLoadClass( T::StaticClass(), Outer, Name, Filename, LoadFlags, Sandbox );
}

7. 静的ロードクラス

内部的に呼び出されLoadObject、Pathに従ってロードされたUClassの型を判定し、型が一致しない場合はエラーとなりNULLが返されます。

UClass* Class = LoadObject<UClass>( InOuter, InName, Filename, LoadFlags, Sandbox );
if( Class && !Class->IsChildOf(BaseClass) )
{
    //报错信息
    ······

    // return NULL class due to error
    Class = NULL;
}
return Class;

使用リスト

LoadObject —— 外側なし

UTexture2D* TestTexture2D = LoadObject<UTexture2D>(nullptr, TEXT("/Game/StarterContent/Textures/T_Burst_M.T_Burst_M"));

ロードパッケージ

UPackage* TestPackage = LoadPackage(nullptr, TEXT("/Game/StarterContent/Textures/T_Burst_M"), LOAD_None);

LoadObject —— 外側

UPackage* TestPackage = LoadPackage(nullptr, TEXT("/Game/StarterContent/Textures/T_Burst_M"), LOAD_None);
UTexture2D* TestTexture2D = LoadObject<UTexture2D>(TestPackage,TEXT("T_Burst_M"));

LoadClass —— 外部なし

TSubclassOf<AActor> TestClass = LoadClass<AActor>(nullptr, TEXT("Blueprint'/Game/Blueprint/BP_Test.BP_Test_C'"));

LoadClass —— 外側

UPackage* TestPackageTwo = LoadPackage(nullptr, TEXT("/Game/Blueprint/BP_Test"), LOAD_None);
TSubclassOf<AActor> TestClass = LoadClass<AActor>(TestPackageTwo, TEXT("BP_Test_C'"));

この図に含まれるその他の同期読み込みの使用方法については、「[UE C++] リソースの読み込み (1) ハードおよびソフト リファレンスのリソースの読み込み」を参照してください。

参考

おすすめ

転載: blog.csdn.net/qq_52179126/article/details/130201757