Files
UnrealEngineUWP/Engine/Source/Editor/UnrealEd/Private/Subsystems/ImportSubsystem.cpp
julien stjean 0af64fa975 Stop interchange from being use when using asset tool api by defaul (when interchange is on). (Otherwise this would break some licensees made code and scripts). Those who want an async import should use the interchange api preferably.
Added a setting to turn on interchange import only for textures.

The selection of the asset in the content is now only done after all the asset are imported when using interchange.

#jira UETOOL-4291
#rb Alexis.Matte
#preflight 619e34820141b3c6da5b98d0

#ROBOMERGE-AUTHOR: julien.stjean
#ROBOMERGE-SOURCE: CL 18282733 in //UE5/Release-5.0/... via CL 18282735
#ROBOMERGE-BOT: STARSHIP (Release-Engine-Staging -> Release-Engine-Test) (v895-18170469)

[CL 18282740 by julien stjean in ue5-release-engine-test branch]
2021-11-24 08:15:47 -05:00

215 lines
6.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Subsystems/ImportSubsystem.h"
#include "Editor.h"
#include "AssetToolsModule.h"
#include "ObjectTools.h"
#include "FileHelpers.h"
#include "EditorReimportHandler.h"
#include "Misc/NamePermissionList.h"
#include "InterchangeManager.h"
#include "InterchangeFactoryBase.h"
class FImportFilesByPath : public IImportSubsystemTask
{
public:
FImportFilesByPath(const TArray<FString>& InFiles, const FString& InRootDestinationPath) :
Files(InFiles),
RootDestinationPath(InRootDestinationPath)
{
}
virtual void Run() override
{
TArray<FString> ImportFiles;
TMap<FString, UObject*> ReimportFiles;
FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools");
TArray<TPair<FString, FString>> FilesAndDestinations;
AssetToolsModule.Get().ExpandDirectories(Files, RootDestinationPath, FilesAndDestinations);
TArray<int32> ReImportIndexes;
for (int32 FileIdx = 0; FileIdx < FilesAndDestinations.Num(); ++FileIdx)
{
const FString& Filename = FilesAndDestinations[FileIdx].Key;
const FString& DestinationPath = FilesAndDestinations[FileIdx].Value;
FString Name = ObjectTools::SanitizeObjectName(FPaths::GetBaseFilename(Filename));
FString PackageName = ObjectTools::SanitizeInvalidChars(DestinationPath + TEXT("/") + Name, INVALID_LONGPACKAGE_CHARACTERS);
// We can not create assets that share the name of a map file in the same location
if (FEditorFileUtils::IsMapPackageAsset(PackageName))
{
//The error message will be log in the import process
ImportFiles.Add(Filename);
continue;
}
//Check if package exist in memory
UPackage* Pkg = FindPackage(nullptr, *PackageName);
bool IsPkgExist = Pkg != nullptr;
//check if package exist on file
if (!IsPkgExist && !FPackageName::DoesPackageExist(PackageName))
{
ImportFiles.Add(Filename);
continue;
}
if (Pkg == nullptr)
{
Pkg = CreatePackage( *PackageName);
if (Pkg == nullptr)
{
//Cannot create a package that don't exist on disk or in memory!!!
//The error message will be log in the import process
ImportFiles.Add(Filename);
continue;
}
}
// Make sure the destination package is loaded
Pkg->FullyLoad();
// Check for an existing object
UObject* ExistingObject = StaticFindObject(UObject::StaticClass(), Pkg, *Name);
if (ExistingObject != nullptr)
{
ReimportFiles.Add(Filename, ExistingObject);
ReImportIndexes.Add(FileIdx);
}
else
{
ImportFiles.Add(Filename);
}
}
//Reimport
for (auto kvp : ReimportFiles)
{
FReimportManager::Instance()->Reimport(kvp.Value, false, true, kvp.Key);
}
//Import
if (ImportFiles.Num() > 0)
{
//Remove it in reverse so the smaller index are still valid
for (int32 IndexToRemove = ReImportIndexes.Num() - 1; IndexToRemove >= 0; --IndexToRemove)
{
FilesAndDestinations.RemoveAt(ReImportIndexes[IndexToRemove]);
}
AssetToolsModule.Get().ImportAssets(ImportFiles, RootDestinationPath, nullptr, true, &FilesAndDestinations, true);
}
}
private:
TArray<FString> Files;
FString RootDestinationPath;
};
UImportSubsystem::UImportSubsystem()
: UEditorSubsystem()
{
}
void UImportSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
auto AttachDelegates = [this]()
{
//Hook on Interchange manager to know when to broadcast import/reimport
UInterchangeManager& InterchangeManager = UInterchangeManager::GetInterchangeManager();
InterchangeManager.OnAssetPostImport.AddUObject(this, &UImportSubsystem::InterchangeBroadcastAssetPostImport);
InterchangeManager.OnAssetPostReimport.AddUObject(this, &UImportSubsystem::InterchangeBroadcastAssetPostReimport);
};
if (GEngine)
{
AttachDelegates();
}
else
{
FCoreDelegates::OnPostEngineInit.AddLambda(AttachDelegates);
}
//Unregister before the Interchange manager get destroy
UInterchangeManager& InterchangeManager = UInterchangeManager::GetInterchangeManager();
InterchangeManager.OnPreDestroyInterchangeManager.AddLambda([this]()
{
//Unhook interchange manager import/reimport delegates
UInterchangeManager& InterchangeManager = UInterchangeManager::GetInterchangeManager();
InterchangeManager.OnAssetPostImport.RemoveAll(this);
InterchangeManager.OnAssetPostReimport.RemoveAll(this);
});
}
void UImportSubsystem::Deinitialize()
{
}
void UImportSubsystem::ImportNextTick(const TArray<FString>& Files, const FString& DestinationPath)
{
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
if (!AssetToolsModule.Get().GetWritableFolderPermissionList()->PassesStartsWithFilter(DestinationPath))
{
AssetToolsModule.Get().NotifyBlockedByWritableFolderFilter();
return;
}
PendingTasks.Enqueue(MakeShared<FImportFilesByPath>(Files, DestinationPath));
GEditor->GetTimerManager()->SetTimerForNextTick(this, &UImportSubsystem::HandleNextTick);
}
void UImportSubsystem::HandleNextTick()
{
if (!PendingTasks.IsEmpty())
{
TSharedPtr<IImportSubsystemTask> Task;
while (PendingTasks.Dequeue(Task))
{
if (Task.IsValid())
{
Task->Run();
}
}
}
}
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void UImportSubsystem::BroadcastAssetPreImport(UFactory* InFactory, UClass* InClass, UObject* InParent, const FName& Name, const TCHAR* Type)
{
FEditorDelegates::OnAssetPreImport.Broadcast(InFactory, InClass, InParent, Name, Type);
OnAssetPreImport.Broadcast(InFactory, InClass, InParent, Name, Type);
OnAssetPreImport_BP.Broadcast(InFactory, InClass, InParent, Name, FString(Type));
}
void UImportSubsystem::BroadcastAssetPostImport(UFactory* InFactory, UObject* InCreatedObject)
{
FEditorDelegates::OnAssetPostImport.Broadcast(InFactory, InCreatedObject);
OnAssetPostImport.Broadcast(InFactory, InCreatedObject);
OnAssetPostImport_BP.Broadcast(InFactory, InCreatedObject);
}
void UImportSubsystem::BroadcastAssetReimport(UObject* InCreatedObject)
{
FEditorDelegates::OnAssetReimport.Broadcast(InCreatedObject);
OnAssetReimport.Broadcast(InCreatedObject);
OnAssetReimport_BP.Broadcast(InCreatedObject);
}
void UImportSubsystem::BroadcastAssetPostLODImport(UObject* InObject, int32 inLODIndex)
{
OnAssetPostLODImport.Broadcast(InObject, inLODIndex);
OnAssetPostLODImport_BP.Broadcast(InObject, inLODIndex);
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
void UImportSubsystem::InterchangeBroadcastAssetPostImport(UObject* InCreatedObject)
{
UFactory* NullFactory = nullptr;
BroadcastAssetPostImport(NullFactory, InCreatedObject);
}
void UImportSubsystem::InterchangeBroadcastAssetPostReimport(UObject* InCreatedObject)
{
BroadcastAssetReimport(InCreatedObject);
}