【UE C++】リソースの読み込み (3) 同期読み込み - LoadObject
一般的に使用される同期読み込み方法には、、、、、、LoadObject
などが含まれます。その中でも代表的なロード処理ですが、との実行処理をもとに以下のシーケンスを紹介します。他の API 実行プロセスの読者は、以下の図を参照するか、ソース コードを入力して表示できます。LoadClass
LoadPackage
FSoftObjectPath::TryLoad
FStreamableManager::RequestSyncLoad
FStreamableManager::LoadSynchronous
LoadObject
LoadObject
LoadClass
FStreamableManager::RequestSyncLoad
、FStreamableManager::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) ハードおよびソフト リファレンスのリソースの読み込み」を参照してください。