2022-03-15 13:52:28 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
UDataLayerToAssetCommandlet . cpp : Commandlet used to convert a partionned ULevel ' s data layers to assets
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "Commandlets/WorldPartitionDataLayerToAssetCommandLet.h"
# include "Algo/Copy.h"
# include "Algo/Accumulate.h"
# include "AssetRegistry/AssetRegistryModule.h"
# include "AssetRegistry/IAssetRegistry.h"
# include "AssetToolsModule.h"
# include "DataLayer/DataLayerFactory.h"
# include "Engine/World.h"
# include "Logging/LogVerbosity.h"
# include "ProfilingDebugging/ScopedTimers.h"
# include "WorldPartition/DataLayer/DataLayerInstanceWithAsset.h"
# include "WorldPartition/DataLayer/WorldDataLayers.h"
# include "WorldPartition/WorldPartitionActorDesc.h"
# include "WorldPartition/WorldPartitionHelpers.h"
DEFINE_LOG_CATEGORY ( LogDataLayerToAssetCommandlet ) ;
// The CommandLet uses deprecated function in AACtor & AWorldDataLayers to perform the conversion of UDEPRECATED_DataLayer -> UDataInstance/UDataLayerAsset
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void UDataLayerConversionInfo : : SetDataLayerToConvert ( const UDeprecatedDataLayerInstance * InDataLayerToConvert )
{
DataLayerToConvert = InDataLayerToConvert ;
DataLayerAsset - > DataLayerType = DataLayerToConvert - > GetType ( ) ;
DataLayerAsset - > DebugColor = DataLayerToConvert - > GetDebugColor ( ) ;
}
void UDataLayerConversionInfo : : SetDataLayerInstance ( UDataLayerInstanceWithAsset * InDataLayerInstance )
{
DataLayerInstance = InDataLayerInstance ;
if ( DataLayerToConvert ! = nullptr )
{
DataLayerInstance - > DataLayerAsset = DataLayerAsset ;
DataLayerInstance - > bIsVisible = DataLayerToConvert - > bIsVisible ;
DataLayerInstance - > bIsInitiallyVisible = DataLayerToConvert - > bIsInitiallyVisible ;
DataLayerInstance - > bIsInitiallyLoadedInEditor = DataLayerToConvert - > bIsInitiallyLoadedInEditor ;
DataLayerInstance - > bIsLocked = DataLayerToConvert - > bIsLocked ;
DataLayerInstance - > InitialRuntimeState = DataLayerToConvert - > InitialRuntimeState ;
}
else
{
// Check the DataLayerInstance was already properly converted
check ( DataLayerInstance - > DataLayerAsset = = DataLayerAsset )
}
}
UDataLayerToAssetCommandletContext : : UDataLayerToAssetCommandletContext ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
{
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : GetDataLayerConversionInfo ( const UDeprecatedDataLayerInstance * DataLayer ) const
{
const TObjectPtr < UDataLayerConversionInfo > * Entry = DataLayerConversionInfo . FindByPredicate ( [ & DataLayer ] ( const TObjectPtr < UDataLayerConversionInfo > & Other ) { return DataLayer = = Other - > DataLayerToConvert ; } ) ;
return Entry ! = nullptr ? Entry - > Get ( ) : nullptr ;
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : GetDataLayerConversionInfo ( const UDataLayerAsset * DataLayerAsset ) const
{
const TObjectPtr < UDataLayerConversionInfo > * Entry = DataLayerConversionInfo . FindByPredicate ( [ & DataLayerAsset ] ( const TObjectPtr < UDataLayerConversionInfo > & Other ) { return DataLayerAsset = = Other - > DataLayerAsset ; } ) ;
return Entry ! = nullptr ? Entry - > Get ( ) : nullptr ;
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : GetDataLayerConversionInfo ( const UDataLayerInstanceWithAsset * DataLayerInstance ) const
{
const TObjectPtr < UDataLayerConversionInfo > * Entry = DataLayerConversionInfo . FindByPredicate ( [ & DataLayerInstance ] ( const TObjectPtr < UDataLayerConversionInfo > & Other ) { return DataLayerInstance = = Other - > DataLayerInstance ; } ) ;
return Entry ! = nullptr ? Entry - > Get ( ) : nullptr ;
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : GetDataLayerConversionInfo ( const FActorDataLayer & ActorDataLayer ) const
{
const TObjectPtr < UDataLayerConversionInfo > * Entry = DataLayerConversionInfo . FindByPredicate ( [ & ActorDataLayer ] ( const TObjectPtr < UDataLayerConversionInfo > & Other )
{
return Other - > DataLayerToConvert ! = nullptr & & ActorDataLayer . Name = = Other - > DataLayerToConvert - > GetDataLayerFName ( ) ;
} ) ;
return Entry ! = nullptr ? Entry - > Get ( ) : nullptr ;
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : StoreExistingDataLayer ( FAssetData & AssetData )
{
UDataLayerConversionInfo * ConversionInfo = NewObject < UDataLayerConversionInfo > ( ) ;
ConversionInfo - > DataLayerAsset = CastChecked < UDataLayerAsset > ( AssetData . GetAsset ( ) ) ;
UE_LOG ( LogDataLayerToAssetCommandlet , Verbose , TEXT ( " Data Layer Asset %s discovered. " ) ,
* ConversionInfo - > DataLayerAsset - > GetFullName ( ) ) ;
return DataLayerConversionInfo . Add_GetRef ( ConversionInfo ) . Get ( ) ;
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : StoreDataLayerAssetConversion ( const UDeprecatedDataLayerInstance * DataLayerToConvert , UDataLayerAsset * NewDataLayerAsset )
{
if ( UDataLayerConversionInfo * ConversionInfo = GetDataLayerConversionInfo ( DataLayerToConvert ) )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to assign asset %s to data Layer %s. The data layer is already associated to asset %s. " ) ,
* NewDataLayerAsset - > GetFullName ( ) , * DataLayerToConvert - > GetDataLayerShortName ( ) , * ConversionInfo - > DataLayerAsset - > GetFullName ( ) ) ;
return nullptr ;
}
UDataLayerConversionInfo * ConversionInfo = GetDataLayerConversionInfo ( NewDataLayerAsset ) ;
if ( ConversionInfo ! = nullptr )
{
if ( ConversionInfo - > DataLayerToConvert ! = nullptr )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to assign asset %s to data Layer %s. The asset is already associated to data layer %s. " ) ,
* NewDataLayerAsset - > GetFullName ( ) , * DataLayerToConvert - > GetDataLayerShortName ( ) , * ConversionInfo - > DataLayerToConvert - > GetDataLayerShortName ( ) ) ;
return nullptr ;
}
}
else
{
ConversionInfo = NewObject < UDataLayerConversionInfo > ( ) ;
ConversionInfo - > DataLayerAsset = NewDataLayerAsset ;
DataLayerConversionInfo . Add ( ConversionInfo ) ;
}
ConversionInfo - > SetDataLayerToConvert ( DataLayerToConvert ) ;
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Data Layer Asset %s is associated to Data Layer %s for conversion " ) ,
* ConversionInfo - > DataLayerAsset - > GetFullName ( ) , * ConversionInfo - > DataLayerToConvert - > GetDataLayerShortName ( ) ) ;
return ConvertingDataLayerInfo . Add_GetRef ( ConversionInfo ) . Get ( ) ;
}
UDataLayerConversionInfo * UDataLayerToAssetCommandletContext : : StoreDataLayerInstanceConversion ( const UDataLayerAsset * DataLayerAsset , UDataLayerInstanceWithAsset * NewDataLayerInstance )
{
if ( UDataLayerConversionInfo * ConversionInfo = GetDataLayerConversionInfo ( NewDataLayerInstance ) )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to assign asset %s to data layer instance %s. The instance is already associated to asset %s. " ) ,
* DataLayerAsset - > GetFullName ( ) , * NewDataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) , * ConversionInfo - > DataLayerAsset - > GetFullName ( ) ) ;
return nullptr ;
}
if ( UDataLayerConversionInfo * ConversionInfo = GetDataLayerConversionInfo ( DataLayerAsset ) )
{
check ( ConversionInfo - > DataLayerInstance = = nullptr ) ;
ConversionInfo - > SetDataLayerInstance ( NewDataLayerInstance ) ;
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Data Layer Instance %s is associated to Data Layer Asset %s for conversion " ) ,
* ConversionInfo - > DataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) , * ConversionInfo - > DataLayerAsset - > GetFullName ( ) ) ;
return ConversionInfo ;
}
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to assign asset %s to data layer instance %s. The asset was not retrieved in conversion data. " ) ,
* DataLayerAsset - > GetFullName ( ) , * NewDataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) ) ;
return nullptr ;
}
bool UDataLayerToAssetCommandletContext : : SetPreviousConversions ( UDataLayerConversionInfo * CurrentConversion , TArray < TWeakObjectPtr < UDataLayerConversionInfo > > & & PreviousConversions )
{
check ( CurrentConversion - > CurrentConvertingInfo = = nullptr ) ;
check ( CurrentConversion - > PreviousConversionsInfo . IsEmpty ( ) ) ;
CurrentConversion - > PreviousConversionsInfo = MoveTemp ( PreviousConversions ) ;
uint32 ErrorCount = 0 ;
for ( TWeakObjectPtr < UDataLayerConversionInfo > & PreviousConversion : CurrentConversion - > PreviousConversionsInfo )
{
check ( PreviousConversion - > CurrentConvertingInfo = = nullptr ) ;
check ( PreviousConversion - > PreviousConversionsInfo . IsEmpty ( ) ) ;
if ( PreviousConversion - > DataLayerInstance ! = nullptr )
{
ErrorCount + + ;
UE_LOG ( LogDataLayerToAssetCommandlet , Error ,
TEXT ( " DataLayer %s was already converted but is still to be converted. Re-Sync Data to a clean conversion or pre-conversion state and re-run the commandlet " ) ,
* CurrentConversion - > DataLayerAsset - > GetFullName ( ) ) ;
}
PreviousConversion - > CurrentConvertingInfo = CurrentConversion ;
}
ConvertingDataLayerInfo . AddUnique ( CurrentConversion ) ;
return ErrorCount = = 0 ;
}
bool UDataLayerToAssetCommandletContext : : FindDataLayerConversionInfos ( FName DataLayerAssetName , TArray < TWeakObjectPtr < UDataLayerConversionInfo > > & OutConversionInfos ) const
{
OutConversionInfos . Empty ( ) ;
FString SanitizedAssetName = DataLayerAssetName . ToString ( ) ;
const TCHAR * InvalidPackageChar = INVALID_LONGPACKAGE_CHARACTERS ;
while ( * InvalidPackageChar )
{
SanitizedAssetName . ReplaceCharInline ( * InvalidPackageChar , TCHAR ( ' _ ' ) , ESearchCase : : CaseSensitive ) ;
+ + InvalidPackageChar ;
}
for ( TObjectPtr < UDataLayerConversionInfo > const & ConversionInfo : DataLayerConversionInfo )
{
if ( ConversionInfo - > DataLayerAsset - > GetFName ( ) = = FName ( SanitizedAssetName ) )
{
OutConversionInfos . Add ( ConversionInfo . Get ( ) ) ;
}
}
return ! OutConversionInfos . IsEmpty ( ) ;
}
void UDataLayerToAssetCommandletContext : : LogConversionInfos ( ) const
{
if ( LogDataLayerToAssetCommandlet . GetVerbosity ( ) > = ELogVerbosity : : Verbose )
{
for ( const TObjectPtr < UDataLayerConversionInfo > & info : DataLayerConversionInfo )
{
FString ConflictingConversionString = TEXT ( " " ) ;
if ( ! info - > PreviousConversionsInfo . IsEmpty ( ) )
{
ConflictingConversionString = FString : : JoinBy ( info - > PreviousConversionsInfo , TEXT ( " , " ) , [ ] ( const TWeakObjectPtr < UDataLayerConversionInfo > & ConflictingInfo )
{
return ConflictingInfo - > DataLayerAsset - > GetFullName ( ) ;
} ) ;
}
UE_LOG ( LogDataLayerToAssetCommandlet , Verbose , TEXT ( " [Conversion Info] Data Layer %s \t \t Data Layer Asset: %s \t \t \t \t \t \t Data Layer Instance: %s \t \t Converting By: %s \t \t \t \t \t \t Conflicting Previous Conversion: %s " ) ,
info - > DataLayerToConvert ! = nullptr ? * info - > DataLayerToConvert - > GetDataLayerShortName ( ) : TEXT ( " None " ) ,
info - > DataLayerAsset ! = nullptr ? * info - > DataLayerAsset - > GetFullName ( ) : TEXT ( " None " ) ,
info - > DataLayerInstance ! = nullptr ? * info - > DataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) : TEXT ( " None " ) ,
info - > CurrentConvertingInfo ! = nullptr ? * info - > CurrentConvertingInfo - > DataLayerAsset - > GetFullName ( ) : TEXT ( " None " ) ,
* ConflictingConversionString ) ;
}
}
}
UDataLayerToAssetCommandlet : : UDataLayerToAssetCommandlet ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer ) ,
DataLayerFactory ( NewObject < UDataLayerFactory > ( ) )
{ }
int32 UDataLayerToAssetCommandlet : : Main ( const FString & Params )
{
TRACE_CPUPROFILER_EVENT_SCOPE ( UWorldPartitionConvertCommandlet : : Main ) ;
UE_SCOPED_TIMER ( TEXT ( " Data Layer Conversion " ) , LogDataLayerToAssetCommandlet , Display ) ;
ON_SCOPE_EXIT
{
if ( MainWorld ! = nullptr )
{
const bool bBroadcastWorldDestroyedEvent = false ;
MainWorld - > DestroyWorld ( bBroadcastWorldDestroyedEvent ) ;
}
} ;
TArray < FString > Tokens , Switches ;
TMap < FString , FString > CommandLineParams ;
ParseCommandLine ( * Params , Tokens , Switches , CommandLineParams ) ;
if ( ! InitializeFromCommandLine ( Tokens , Switches , CommandLineParams ) )
{
return EReturnCode : : CommandletInitializationError ;
}
ConversionFolder = DestinationFolder + " / " + MainWorld - > GetName ( ) ;
TStrongObjectPtr < UDataLayerToAssetCommandletContext > Context ( NewObject < UDataLayerToAssetCommandletContext > ( ) ) ;
if ( ! BuildConversionInfos ( Context ) )
{
return EReturnCode : : DataLayerConversionError ;
}
if ( ! ResolvePreviousConversionsToCurrent ( Context ) )
{
return EReturnCode : : DataLayerConversionError ;
}
Context - > LogConversionInfos ( ) ;
if ( ! CreateDataLayerInstances ( Context ) )
{
return EReturnCode : : DataLayerConversionError ;
}
if ( ! RemapActorDataLayersToAssets ( Context ) )
{
return EReturnCode : : ActorDataLayerRemappingError ;
}
if ( ! PerformProjectSpecificConversions ( Context ) )
{
return EReturnCode : : ProjectSpecificConversionError ;
}
if ( ! DeletePreviousConversionsData ( Context ) )
{
return EReturnCode : : DataLayerConversionError ;
}
if ( ! CommitConversion ( Context ) )
{
return EReturnCode : : DataLayerConversionError ;
}
return EReturnCode : : Success ;
}
bool UDataLayerToAssetCommandlet : : InitializeFromCommandLine ( TArray < FString > & Tokens , TArray < FString > const & Switches , TMap < FString , FString > const & Params )
{
constexpr TCHAR DestinationFolderSwitch [ ] = TEXT ( " DestinationFolder " ) ;
if ( FString const * DestFolderPtr = Params . Find ( DestinationFolderSwitch ) )
{
DestinationFolder = * DestFolderPtr ;
}
else
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " No \" %s \" switch specified " ) , DestinationFolderSwitch ) ;
return false ;
}
if ( Switches . Contains ( TEXT ( " Verbose " ) ) )
{
LogDataLayerToAssetCommandlet . SetVerbosity ( ELogVerbosity : : Verbose ) ;
WorldPartitionCommandletHelpers : : LogWorldParitionCommandletUtils . SetVerbosity ( ELogVerbosity : : Verbose ) ;
}
bPerformSavePackages = Switches . Contains ( TEXT ( " NoSave " ) ) = = false ;
bIgnoreActorLoadingErrors = Switches . Contains ( TEXT ( " IgnoreActorLoadingErrors " ) ) ;
MainWorld = WorldPartitionCommandletHelpers : : LoadAndInitWorld ( Tokens [ 0 ] ) ;
if ( ! MainWorld )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to Load %s, Conversion will abort " ) , * Tokens [ 0 ] ) ;
return false ;
}
return true ;
}
bool UDataLayerToAssetCommandlet : : BuildConversionInfos ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
UE_SCOPED_TIMER ( TEXT ( " Retrieving Already Converted Data Layers " ) , LogDataLayerToAssetCommandlet , Display ) ;
TArray < FAssetData > ExistingDataLayerAssets ;
IAssetRegistry & AssetRegistry = FAssetRegistryModule : : GetRegistry ( ) ;
AssetRegistry . GetAssetsByClass ( UDataLayerAsset : : StaticClass ( ) - > GetFName ( ) , ExistingDataLayerAssets ) ;
for ( FAssetData & AssetData : ExistingDataLayerAssets )
{
CommandletContext - > StoreExistingDataLayer ( AssetData ) ;
}
AWorldDataLayers * WorldDataLayers = MainWorld - > GetWorldDataLayers ( ) ;
TArray < UDataLayerInstance * > DataLayerInstances ;
Algo : : Copy ( WorldDataLayers - > DataLayerInstances , DataLayerInstances ) ;
for ( int32 i = DataLayerInstances . Num ( ) - 1 ; i > = 0 ; - - i )
{
if ( UDataLayerInstanceWithAsset * DataLayerInstance = Cast < UDataLayerInstanceWithAsset > ( DataLayerInstances [ i ] ) )
{
if ( const UDataLayerAsset * DataLayerAsset = DataLayerInstance - > GetAsset ( ) )
{
if ( UDataLayerConversionInfo * ConversionInfo = CommandletContext - > GetDataLayerConversionInfo ( DataLayerAsset ) )
{
CommandletContext - > StoreDataLayerInstanceConversion ( ConversionInfo - > DataLayerAsset , DataLayerInstance ) ;
}
}
}
}
uint32 ErrorCount = 0 ;
for ( const UDataLayerInstance * DataLayerInstance : WorldDataLayers - > DataLayerInstances )
{
if ( const UDeprecatedDataLayerInstance * DataLayerToConvert = Cast < UDeprecatedDataLayerInstance > ( DataLayerInstance ) )
{
if ( ! CreateConversionFromDataLayer ( CommandletContext , DataLayerToConvert ) )
{
ErrorCount + + ;
}
}
}
return ErrorCount = = 0 ;
}
bool UDataLayerToAssetCommandlet : : CreateConversionFromDataLayer ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext , const UDeprecatedDataLayerInstance * DataLayer )
{
if ( TObjectPtr < UDataLayerAsset > DataLayerAsset = GetOrCreateDataLayerAssetForConversion ( CommandletContext , FName ( DataLayer - > GetDataLayerShortName ( ) ) ) )
{
if ( UDataLayerConversionInfo * ConversionInfo = CommandletContext - > StoreDataLayerAssetConversion ( DataLayer , DataLayerAsset ) )
{
if ( bPerformSavePackages )
{
return WorldPartitionCommandletHelpers : : CheckoutSaveAdd ( ConversionInfo - > DataLayerAsset - > GetPackage ( ) , PackageHelper ) ;
}
return true ;
}
}
return false ;
}
TObjectPtr < UDataLayerAsset > UDataLayerToAssetCommandlet : : GetOrCreateDataLayerAssetForConversion ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext , FName DataLayerAssetName )
{
TObjectPtr < UDataLayerAsset > DataLayerAsset = nullptr ;
TArray < TWeakObjectPtr < UDataLayerConversionInfo > > ConversionInfos ;
if ( CommandletContext - > FindDataLayerConversionInfos ( DataLayerAssetName , ConversionInfos ) )
{
for ( TWeakObjectPtr < UDataLayerConversionInfo > & ConversionInfo : ConversionInfos )
{
if ( IsAssetInConversionFolder ( ConversionInfo - > DataLayerAsset ) )
{
check ( DataLayerAsset = = nullptr ) ;
return CastChecked < UDataLayerAsset > ( ConversionInfo - > DataLayerAsset ) ;
}
}
}
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Creating new Data Layer Asset %s in folder %s " ) ,
* DataLayerAssetName . ToString ( ) , * ConversionFolder ) ;
FString SanitizedAssetName = DataLayerAssetName . ToString ( ) ;
const TCHAR * InvalidPackageChar = INVALID_LONGPACKAGE_CHARACTERS ;
while ( * InvalidPackageChar )
{
SanitizedAssetName . ReplaceCharInline ( * InvalidPackageChar , TCHAR ( ' _ ' ) , ESearchCase : : CaseSensitive ) ;
+ + InvalidPackageChar ;
}
IAssetTools & AssetTools = FModuleManager : : GetModuleChecked < FAssetToolsModule > ( " AssetTools " ) . Get ( ) ;
if ( UObject * Asset = AssetTools . CreateAsset ( SanitizedAssetName , ConversionFolder , UDataLayerAsset : : StaticClass ( ) , DataLayerFactory ) )
{
DataLayerAsset = CastChecked < UDataLayerAsset > ( Asset ) ;
}
else
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to create asset for %s in folder %s. Consult log for more details " ) ,
* DataLayerAssetName . ToString ( ) , * ConversionFolder ) ;
}
return DataLayerAsset ;
}
bool UDataLayerToAssetCommandlet : : ResolvePreviousConversionsToCurrent ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
UE_SCOPED_TIMER ( TEXT ( " Resolving Conflicting Conversions " ) , LogDataLayerToAssetCommandlet , Display ) ;
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Resolving Conflicting Conversions " ) ) ;
uint32 ErrorCount = 0 ;
for ( const TObjectPtr < UDataLayerConversionInfo > & ConversionInfo : CommandletContext - > GetDataLayerConversionInfos ( ) )
{
if ( IsAssetInConversionFolder ( ConversionInfo - > DataLayerAsset ) )
{
TArray < TWeakObjectPtr < UDataLayerConversionInfo > > PreviousConversionInfos ;
if ( CommandletContext - > FindDataLayerConversionInfos ( ConversionInfo - > DataLayerAsset - > GetFName ( ) , PreviousConversionInfos ) )
{
PreviousConversionInfos . Remove ( ConversionInfo ) ;
if ( ! PreviousConversionInfos . IsEmpty ( ) )
{
if ( ! CommandletContext - > SetPreviousConversions ( ConversionInfo , MoveTemp ( PreviousConversionInfos ) ) )
{
ErrorCount + + ;
}
}
}
}
}
return ErrorCount = = 0 ;
}
bool UDataLayerToAssetCommandlet : : RemapActorDataLayersToAssets ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
UE_SCOPED_TIMER ( TEXT ( " Remapping Actors Data Layers " ) , LogDataLayerToAssetCommandlet , Display ) ;
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Starting Actor Data Layer Remapping To Data Layer Asset. This can take a while. " ) ) ;
uint32 ErrorCount = 0 ;
2022-05-09 13:41:41 -04:00
FWorldPartitionHelpers : : ForEachActorWithLoading ( MainWorld - > GetWorldPartition ( ) , [ & ErrorCount , & CommandletContext , this ] ( const FWorldPartitionActorDesc * ActorDesc )
{
uint32 ActorConversionErrors = 0 ;
if ( AActor * Actor = ActorDesc - > GetActor ( ) )
2022-03-15 13:52:28 -04:00
{
2022-05-09 13:41:41 -04:00
ActorConversionErrors + = RemapDataLayersAssetsFromPreviousConversions ( CommandletContext , Actor ) ;
ActorConversionErrors + = RemapActorDataLayers ( CommandletContext , Actor ) ;
if ( ! PerformAdditionalActorConversions ( CommandletContext , Actor ) )
2022-03-15 13:52:28 -04:00
{
2022-05-09 13:41:41 -04:00
ActorConversionErrors + + ;
2022-03-15 13:52:28 -04:00
}
2022-05-09 13:41:41 -04:00
if ( ActorConversionErrors = = 0 & & bPerformSavePackages )
{
if ( bPerformSavePackages & & Actor - > GetExternalPackage ( ) - > IsDirty ( ) )
{
if ( ! WorldPartitionCommandletHelpers : : CheckoutSaveAdd ( Actor - > GetExternalPackage ( ) , PackageHelper ) )
2022-03-15 13:52:28 -04:00
{
ActorConversionErrors + + ;
}
}
}
2022-05-09 13:41:41 -04:00
}
else
{
const TArray < FName > & ActDescDataLayers = ActorDesc - > GetDataLayerInstanceNames ( ) ;
if ( ! ActDescDataLayers . IsEmpty ( ) )
{
FString DataLayerString = FString : : JoinBy ( ActDescDataLayers , TEXT ( " , " ) , [ ] ( const FName & DataLayerName ) { return DataLayerName . ToString ( ) ; } ) ;
2022-03-15 13:52:28 -04:00
2022-05-09 13:41:41 -04:00
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Actor %s failed to load. Its data layers %s will not be remapped to a data layer asset. " ) ,
* ActorDesc - > GetActorName ( ) . ToString ( ) , * DataLayerString ) ;
if ( ! bIgnoreActorLoadingErrors )
{
ActorConversionErrors + + ;
}
}
}
ErrorCount + = ActorConversionErrors ;
return true ;
} ) ;
2022-03-15 13:52:28 -04:00
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Actor Data Layer Remapping To Data Layer Asset Done. " ) ) ;
return ErrorCount = = 0 ; ;
}
uint32 UDataLayerToAssetCommandlet : : RemapActorDataLayers ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext , AActor * Actor )
{
uint32 ErrorCount = 0 ;
const TArray < FActorDataLayer > & ActorDataLayers = Actor - > GetActorDataLayers ( ) ;
for ( int32 i = ActorDataLayers . Num ( ) - 1 ; i > = 0 ; - - i )
{
const FActorDataLayer & ActorDataLayer = ActorDataLayers [ i ] ;
if ( UDataLayerConversionInfo * DataLayerConversionInfo = CommandletContext - > GetDataLayerConversionInfo ( ActorDataLayer ) )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Verbose , TEXT ( " Data layer %s in Actor %s remapped to data layer asset %s " ) ,
* ActorDataLayer . Name . ToString ( ) , * Actor - > GetName ( ) , * DataLayerConversionInfo - > DataLayerAsset - > GetName ( ) ) ;
if ( Actor - > AddDataLayer ( DataLayerConversionInfo - > DataLayerInstance ) )
{
if ( ! Actor - > RemoveDataLayer ( DataLayerConversionInfo - > DataLayerToConvert ) )
{
ErrorCount + + ;
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to remove data layer %s in Actor %s " ) ,
* DataLayerConversionInfo - > DataLayerToConvert - > GetDataLayerShortName ( ) , * Actor - > GetName ( ) ) ;
}
}
else
{
ErrorCount + + ;
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to add data layer asset %s in Actor %s " ) ,
* DataLayerConversionInfo - > DataLayerAsset - > GetFullName ( ) , * Actor - > GetName ( ) ) ;
}
}
else
{
ErrorCount + + ;
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Actor %s is referencing data layer %s but it does not match any data layer asset. " ) ,
* Actor - > GetName ( ) , * ActorDataLayer . Name . ToString ( ) ) ;
}
}
return ErrorCount ;
}
// Multiple run of the commandlet can lead to Actors referencing Data Layer Assets in different folders. Always remap to the newly created asset.
uint32 UDataLayerToAssetCommandlet : : RemapDataLayersAssetsFromPreviousConversions ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext , AActor * Actor )
{
uint32 ErrorCount = 0 ;
const TArray < TObjectPtr < const UDataLayerAsset > > & ActorDataLayerAssets = Actor - > GetDataLayerAssets ( ) ;
for ( int32 i = ActorDataLayerAssets . Num ( ) - 1 ; i > = 0 ; - - i )
{
const TObjectPtr < const UDataLayerAsset > & ActorDataLayerAsset = ActorDataLayerAssets [ i ] ;
if ( UDataLayerConversionInfo * DataLayerConversionInfo = CommandletContext - > GetDataLayerConversionInfo ( ActorDataLayerAsset . Get ( ) ) )
{
if ( DataLayerConversionInfo - > IsAPreviousConversion ( ) )
{
if ( Actor - > AddDataLayer ( DataLayerConversionInfo - > GetCurrentConversion ( ) - > DataLayerInstance ) )
{
if ( ! Actor - > RemoveDataLayer ( DataLayerConversionInfo - > DataLayerAsset ) )
{
ErrorCount + + ;
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to remove deprecated data layer asset %s in Actor %s " ) ,
* DataLayerConversionInfo - > DataLayerAsset - > GetFullName ( ) , * Actor - > GetName ( ) ) ;
}
}
else
{
ErrorCount + + ;
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to replace data layer asset %s in Actor %s " ) ,
* DataLayerConversionInfo - > GetCurrentConversion ( ) - > DataLayerAsset - > GetFullName ( ) , * Actor - > GetName ( ) ) ;
}
}
}
}
return ErrorCount ;
}
bool UDataLayerToAssetCommandlet : : CreateDataLayerInstances ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
UE_SCOPED_TIMER ( TEXT ( " Creating Data Layer Instances " ) , LogDataLayerToAssetCommandlet , Display ) ;
uint32 ErrorCount = 0 ;
AWorldDataLayers * WorldDataLayers = MainWorld - > GetWorldDataLayers ( ) ;
for ( const TWeakObjectPtr < UDataLayerConversionInfo > & ConvertingInfo : CommandletContext - > GetConvertingDataLayerConversionInfo ( ) )
{
if ( ConvertingInfo - > DataLayerInstance = = nullptr )
{
UDataLayerInstanceWithAsset * DataLayerInstance = WorldDataLayers - > CreateDataLayer < UDataLayerInstanceWithAsset > ( ConvertingInfo - > DataLayerAsset ) ;
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Created new Data Layer Instance %s " ) ,
* DataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) ) ;
CommandletContext - > StoreDataLayerInstanceConversion ( ConvertingInfo - > DataLayerAsset , DataLayerInstance ) ;
}
WorldDataLayers - > DeprecatedDataLayerNameToDataLayerInstance . Add ( ConvertingInfo - > DataLayerToConvert - > GetDataLayerFName ( ) , ConvertingInfo - > DataLayerInstance ) ;
}
if ( ErrorCount = = 0 )
{
if ( ! RebuildDataLayerHierarchies ( CommandletContext ) )
{
ErrorCount + + ;
}
}
return ErrorCount = = 0 ;
}
bool UDataLayerToAssetCommandlet : : RebuildDataLayerHierarchies ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
UE_SCOPED_TIMER ( TEXT ( " Creating Data Layer Instances Hierarchy " ) , LogDataLayerToAssetCommandlet , Display ) ;
uint32 ErrorCount = 0 ;
for ( const TWeakObjectPtr < UDataLayerConversionInfo > & ConvertingInfo : CommandletContext - > GetConvertingDataLayerConversionInfo ( ) )
{
UDataLayerInstance * Child = ConvertingInfo - > DataLayerInstance ;
if ( Child = = nullptr )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to retrieve data layer instance when re-building hiearchy for %s " ) ,
* ConvertingInfo - > DataLayerAsset - > GetFullName ( ) ) ;
ErrorCount + + ;
continue ;
}
const UDataLayerInstance * OldParent = ConvertingInfo - > DataLayerToConvert - > GetParent ( ) ;
if ( OldParent = = nullptr )
{
// No Parent, continue
continue ;
}
const UDeprecatedDataLayerInstance * DeprecatedParent = Cast < UDeprecatedDataLayerInstance > ( OldParent ) ;
if ( DeprecatedParent = = nullptr )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Deprecated Data Layer Instance %s has %s as a parent. But %s is not depcrated. This is not permitted " ) ,
* Child - > GetDataLayerFullName ( ) , * OldParent - > GetDataLayerShortName ( ) , * OldParent - > GetDataLayerShortName ( ) ) ;
ErrorCount + + ;
continue ;
}
UDataLayerConversionInfo * ParentConversionInfo = CommandletContext - > GetDataLayerConversionInfo ( DeprecatedParent ) ;
if ( ParentConversionInfo = = nullptr )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to find conversion info for parent %s of %s while rebuilding data layer hierarchy " ) ,
* DeprecatedParent - > GetDataLayerFullName ( ) , * Child - > GetDataLayerShortName ( ) ) ;
ErrorCount + + ;
continue ;
}
if ( UDataLayerInstance * NewParent = ParentConversionInfo - > DataLayerInstance )
{
if ( ! Child - > SetParent ( NewParent ) )
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to set %s as the parent of %s " ) ,
* NewParent - > GetDataLayerFullName ( ) , * Child - > GetDataLayerShortName ( ) ) ;
ErrorCount + + ;
}
}
else
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to retrieve data layer instance for parent %s when re-building hiearchy for %s " ) ,
* DeprecatedParent - > GetDataLayerFullName ( ) , * Child - > GetDataLayerShortName ( ) ) ;
ErrorCount + + ;
}
}
return ErrorCount = = 0 ;
}
bool UDataLayerToAssetCommandlet : : DeletePreviousConversionsData ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
UE_SCOPED_TIMER ( TEXT ( " Delete Conflicting Assets " ) , LogDataLayerToAssetCommandlet , Display ) ;
uint32 ErrorCount = 0 ;
for ( const TWeakObjectPtr < UDataLayerConversionInfo > & ConvertingInfo : CommandletContext - > GetConvertingDataLayerConversionInfo ( ) )
{
for ( const TWeakObjectPtr < UDataLayerConversionInfo > & PreviousConversion : ConvertingInfo - > GetPreviousConversions ( ) )
{
if ( bPerformSavePackages )
{
if ( WorldPartitionCommandletHelpers : : Delete ( PreviousConversion - > DataLayerAsset - > GetPackage ( ) , PackageHelper ) )
{
PreviousConversion - > DataLayerAsset = nullptr ;
}
else
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to delete Data Layer Asset %s from previous conversion. (Conflicting with %s) " ) ,
* PreviousConversion - > DataLayerAsset - > GetFullName ( ) , * ConvertingInfo - > DataLayerAsset - > GetFullName ( ) ) ;
ErrorCount + + ;
}
}
}
}
return ErrorCount = = 0 ;
}
bool UDataLayerToAssetCommandlet : : CommitConversion ( TStrongObjectPtr < UDataLayerToAssetCommandletContext > & CommandletContext )
{
uint32 ErrorCount = 0 ;
AWorldDataLayers * WorldDataLayers = MainWorld - > GetWorldDataLayers ( ) ;
for ( const TWeakObjectPtr < UDataLayerConversionInfo > & ConversionInfo : CommandletContext - > GetConvertingDataLayerConversionInfo ( ) )
{
if ( ConversionInfo - > DataLayerToConvert ! = nullptr )
{
2022-03-22 23:02:22 -04:00
// Remove directly from DataLayerInstances as RemoveDataLayer method also cleans DeprecatedDataLayerNameToDataLayerInstance which is used for runtime conversion
if ( WorldDataLayers - > DataLayerInstances . Remove ( ConversionInfo - > DataLayerToConvert ) )
2022-03-15 13:52:28 -04:00
{
UE_LOG ( LogDataLayerToAssetCommandlet , Log , TEXT ( " Deleted old data layer %s, it is now converted to Data Layer Asset %s and Data Layer Instance %s " ) ,
* ConversionInfo - > DataLayerToConvert - > GetDataLayerShortName ( ) , * ConversionInfo - > DataLayerAsset - > GetFullName ( ) , * ConversionInfo - > DataLayerInstance - > GetDataLayerFName ( ) . ToString ( ) ) ;
}
else
{
UE_LOG ( LogDataLayerToAssetCommandlet , Error , TEXT ( " Failed to delete converting data layer %s. " ) ,
* ConversionInfo - > DataLayerToConvert - > GetDataLayerShortName ( ) ) ;
ErrorCount + + ;
}
}
}
if ( ErrorCount = = 0 & & bPerformSavePackages )
{
if ( ! WorldPartitionCommandletHelpers : : CheckoutSaveAdd ( WorldDataLayers - > GetExternalPackage ( ) , PackageHelper ) )
{
return false ;
}
}
return true ;
}
bool UDataLayerToAssetCommandlet : : IsAssetInConversionFolder ( const TObjectPtr < UDataLayerAsset > DataLayerAsset )
{
return FCString : : Stristr ( * DataLayerAsset - > GetPackage ( ) - > GetName ( ) , * ConversionFolder ) ! = nullptr ;
}
2022-03-22 23:02:22 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS