void FRedirectCollector::ResolveStringAssetReference() { while (StringAssetReferences.Num()) { TMultiMap<FString, FString>::TIterator First(StringAssetReferences); FString ToLoad = First.Key(); FString RefFilename = First.Value(); First.RemoveCurrent(); if (ToLoad.Len() > 0) { UE_LOG(LogRedirectors, Log, TEXT("String Asset Reference '%s'"), *ToLoad); StringAssetRefFilenameStack.Push(RefFilename); UObject *Loaded = LoadObject<UObject>(NULL, *ToLoad, NULL, LOAD_None, NULL); StringAssetRefFilenameStack.Pop(); UObjectRedirector* Redirector = dynamic_cast<UObjectRedirector*>(Loaded); if (Redirector) { UE_LOG(LogRedirectors, Log, TEXT(" Found redir '%s'"), *Redirector->GetFullName()); FRedirection Redir; Redir.PackageFilename = RefFilename; Redir.RedirectorName = Redirector->GetFullName(); Redir.RedirectorPackageFilename = Redirector->GetLinker()->Filename; CA_SUPPRESS(28182) Redir.DestinationObjectName = Redirector->DestinationObject->GetFullName(); Redirections.AddUnique(Redir); Loaded = Redirector->DestinationObject; } if (Loaded) { FString Dest = Loaded->GetPathName(); UE_LOG(LogRedirectors, Log, TEXT(" Resolved to '%s'"), *Dest); if (Dest != ToLoad) { StringAssetRemap.Add(ToLoad, Dest); } } else { UE_LOG(LogRedirectors, Log, TEXT(" Not Found!")); } } } }
void FRedirectCollector::ResolveStringAssetReference(FString FilterPackage) { SCOPE_REDIRECT_TIMER(ResolveTimeTotal); FName FilterPackageFName = NAME_None; if (!FilterPackage.IsEmpty()) { FilterPackageFName = FName(*FilterPackage); } TMultiMap<FName, FPackagePropertyPair> SkippedReferences; SkippedReferences.Empty(StringAssetReferences.Num()); while ( StringAssetReferences.Num()) { TMultiMap<FName, FPackagePropertyPair> CurrentReferences; Swap(StringAssetReferences, CurrentReferences); for (const auto& CurrentReference : CurrentReferences) { const FName& ToLoadFName = CurrentReference.Key; const FPackagePropertyPair& RefFilenameAndProperty = CurrentReference.Value; if ((FilterPackageFName != NAME_None) && // not using a filter (FilterPackageFName != RefFilenameAndProperty.GetCachedPackageName()) && // this is the package we are looking for (RefFilenameAndProperty.GetCachedPackageName() != NAME_None) // if we have an empty package name then process it straight away ) { // If we have a valid filter and it doesn't match, skip this reference SkippedReferences.Add(ToLoadFName, RefFilenameAndProperty); continue; } const FString ToLoad = ToLoadFName.ToString(); if (FCoreDelegates::LoadStringAssetReferenceInCook.IsBound()) { SCOPE_REDIRECT_TIMER(ResolveTimeDelegate); if (FCoreDelegates::LoadStringAssetReferenceInCook.Execute(ToLoad) == false) { // Skip this reference continue; } } if (ToLoad.Len() > 0 ) { SCOPE_REDIRECT_TIMER(ResolveTimeLoad); UE_LOG(LogRedirectors, Verbose, TEXT("String Asset Reference '%s'"), *ToLoad); UE_CLOG(RefFilenameAndProperty.GetProperty().ToString().Len(), LogRedirectors, Verbose, TEXT(" Referenced by '%s'"), *RefFilenameAndProperty.GetProperty().ToString()); StringAssetRefFilenameStack.Push(RefFilenameAndProperty.GetPackage().ToString()); UObject *Loaded = LoadObject<UObject>(NULL, *ToLoad, NULL, RefFilenameAndProperty.GetReferencedByEditorOnlyProperty() ? LOAD_EditorOnly : LOAD_None, NULL); StringAssetRefFilenameStack.Pop(); UObjectRedirector* Redirector = dynamic_cast<UObjectRedirector*>(Loaded); if (Redirector) { UE_LOG(LogRedirectors, Verbose, TEXT(" Found redir '%s'"), *Redirector->GetFullName()); FRedirection Redir; Redir.PackageFilename = RefFilenameAndProperty.GetPackage().ToString(); Redir.RedirectorName = Redirector->GetFullName(); Redir.RedirectorPackageFilename = Redirector->GetLinker()->Filename; CA_SUPPRESS(28182) Redir.DestinationObjectName = Redirector->DestinationObject->GetFullName(); Redirections.AddUnique(Redir); Loaded = Redirector->DestinationObject; } if (Loaded) { if (FCoreUObjectDelegates::PackageLoadedFromStringAssetReference.IsBound()) { FCoreUObjectDelegates::PackageLoadedFromStringAssetReference.Broadcast(Loaded->GetOutermost()->GetFName()); } FString Dest = Loaded->GetPathName(); UE_LOG(LogRedirectors, Verbose, TEXT(" Resolved to '%s'"), *Dest); if (Dest != ToLoad) { StringAssetRemap.Add(ToLoad, Dest); } } else { const FString Referencer = RefFilenameAndProperty.GetProperty().ToString().Len() ? RefFilenameAndProperty.GetProperty().ToString() : TEXT("Unknown"); int32 DotIndex = ToLoad.Find(TEXT(".")); FString PackageName = DotIndex != INDEX_NONE ? ToLoad.Left(DotIndex) : ToLoad; if (FLinkerLoad::IsKnownMissingPackage(FName(*PackageName)) == false) { UE_LOG(LogRedirectors, Warning, TEXT("String Asset Reference '%s' was not found! (Referencer '%s')"), *ToLoad, *Referencer); } } } } } check(StringAssetReferences.Num() == 0); // Add any skipped references back into the map for the next time this is called Swap(StringAssetReferences, SkippedReferences); // we shouldn't have any references left if we decided to resolve them all check((StringAssetReferences.Num() == 0) || (FilterPackageFName != NAME_None)); }
void FRedirectCollector::ResolveStringAssetReference(FString FilterPackage) { TMultiMap<FString, FPackagePropertyPair> SkippedReferences; while (StringAssetReferences.Num()) { TMultiMap<FString, FPackagePropertyPair>::TIterator First(StringAssetReferences); FString ToLoad = First.Key(); FPackagePropertyPair RefFilenameAndProperty = First.Value(); First.RemoveCurrent(); if (FCoreDelegates::LoadStringAssetReferenceInCook.IsBound()) { if (FCoreDelegates::LoadStringAssetReferenceInCook.Execute(ToLoad) == false) { // Skip this reference continue; } } if (!FilterPackage.IsEmpty() && FilterPackage != RefFilenameAndProperty.Package) { // If we have a valid filter and it doesn't match, skip this reference SkippedReferences.Add(ToLoad, RefFilenameAndProperty); continue; } if (ToLoad.Len() > 0) { UE_LOG(LogRedirectors, Verbose, TEXT("String Asset Reference '%s'"), *ToLoad); UE_CLOG(RefFilenameAndProperty.Property.Len(), LogRedirectors, Verbose, TEXT(" Referenced by '%s'"), *RefFilenameAndProperty.Property); StringAssetRefFilenameStack.Push(RefFilenameAndProperty.Package); UObject *Loaded = LoadObject<UObject>(NULL, *ToLoad, NULL, RefFilenameAndProperty.bReferencedByEditorOnlyProperty ? LOAD_EditorOnly : LOAD_None, NULL); StringAssetRefFilenameStack.Pop(); UObjectRedirector* Redirector = dynamic_cast<UObjectRedirector*>(Loaded); if (Redirector) { UE_LOG(LogRedirectors, Verbose, TEXT(" Found redir '%s'"), *Redirector->GetFullName()); FRedirection Redir; Redir.PackageFilename = RefFilenameAndProperty.Package; Redir.RedirectorName = Redirector->GetFullName(); Redir.RedirectorPackageFilename = Redirector->GetLinker()->Filename; CA_SUPPRESS(28182) Redir.DestinationObjectName = Redirector->DestinationObject->GetFullName(); Redirections.AddUnique(Redir); Loaded = Redirector->DestinationObject; } if (Loaded) { FString Dest = Loaded->GetPathName(); UE_LOG(LogRedirectors, Verbose, TEXT(" Resolved to '%s'"), *Dest); if (Dest != ToLoad) { StringAssetRemap.Add(ToLoad, Dest); } } else { const FString Referencer = RefFilenameAndProperty.Property.Len() ? RefFilenameAndProperty.Property : TEXT("Unknown"); UE_LOG(LogRedirectors, Warning, TEXT("String Asset Reference '%s' was not found! (Referencer '%s')"), *ToLoad, *Referencer); } } } // Add any skipped references back into the map for the next time this is called StringAssetReferences = SkippedReferences; }