173 lines
6.1 KiB
C++
173 lines
6.1 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/BlacklistNames.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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
TArray<FString> Files;
|
||
|
|
FString RootDestinationPath;
|
||
|
|
};
|
||
|
|
|
||
|
|
UImportSubsystem::UImportSubsystem()
|
||
|
|
: UEditorSubsystem()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void UImportSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void UImportSubsystem::Deinitialize()
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
void UImportSubsystem::ImportNextTick(const TArray<FString>& Files, const FString& DestinationPath)
|
||
|
|
{
|
||
|
|
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
|
||
|
|
if (!AssetToolsModule.Get().GetWritableFolderBlacklist()->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
|