2022-05-23 18:41:30 +00:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "EditorValidator_Blueprints.h"
2022-09-13 07:18:28 +00:00
# include "AssetRegistry/AssetData.h"
# include "AssetRegistry/AssetRegistryModule.h"
# include "AssetRegistry/IAssetRegistry.h"
2022-05-23 18:41:30 +00:00
# include "Blueprint/BlueprintSupport.h"
2022-09-13 07:18:28 +00:00
# include "Containers/Set.h"
# include "Containers/UnrealString.h"
# include "Engine/Blueprint.h"
# include "HAL/Platform.h"
# include "Internationalization/Text.h"
2022-05-23 18:41:30 +00:00
# include "Kismet2/BlueprintEditorUtils.h"
2022-09-13 07:18:28 +00:00
# include "Logging/LogCategory.h"
# include "Logging/LogMacros.h"
2022-05-23 18:41:30 +00:00
# include "LyraEditor.h"
2022-09-13 07:18:28 +00:00
# include "Misc/AssertionMacros.h"
# include "Misc/AssetRegistryInterface.h"
# include "Modules/ModuleManager.h"
# include "Templates/Casts.h"
# include "Templates/UnrealTemplate.h"
# include "Trace/Detail/Channel.h"
# include "UObject/NameTypes.h"
# include "UObject/Object.h"
# include "UObject/Package.h"
# include "Validation/EditorValidator.h"
# include "Validation/EditorValidator_Load.h"
2022-05-23 18:41:30 +00:00
# define LOCTEXT_NAMESPACE "EditorValidator"
UEditorValidator_Blueprints : : UEditorValidator_Blueprints ( )
: Super ( )
{
}
bool UEditorValidator_Blueprints : : CanValidateAsset_Implementation ( UObject * InAsset ) const
{
return Super : : CanValidateAsset_Implementation ( InAsset ) & & ( InAsset ? InAsset - > IsA ( UBlueprint : : StaticClass ( ) ) : false ) ;
}
EDataValidationResult UEditorValidator_Blueprints : : ValidateLoadedAsset_Implementation ( UObject * InAsset , TArray < FText > & ValidationErrors )
{
UBlueprint * Blueprint = Cast < UBlueprint > ( InAsset ) ;
check ( Blueprint ) ;
if ( UEditorValidator : : ShouldAllowFullValidation ( ) )
{
// For non-dataonly blueprints, also load and check all directly referencing non-data-only blueprints, as changes may have caused them to fail to compile
if ( ! FBlueprintEditorUtils : : IsDataOnlyBlueprint ( Blueprint ) )
{
FAssetRegistryModule & AssetRegistryModule = FModuleManager : : LoadModuleChecked < FAssetRegistryModule > ( TEXT ( " AssetRegistry " ) ) ;
IAssetRegistry & AssetRegistry = AssetRegistryModule . Get ( ) ;
TSet < FName > AllHardReferencers ;
TArray < FName > PackagesToProcess ;
PackagesToProcess . Add ( Blueprint - > GetOutermost ( ) - > GetFName ( ) ) ;
do
{
TArray < FName > NextPackagesToProcess ;
for ( FName PackageToProcess : PackagesToProcess )
{
TArray < FName > HardReferencers ;
AssetRegistry . GetReferencers ( PackageToProcess , HardReferencers , UE : : AssetRegistry : : EDependencyCategory : : Package , UE : : AssetRegistry : : EDependencyQuery : : Hard ) ;
for ( FName HardReferencer : HardReferencers )
{
if ( ! AllHardReferencers . Contains ( HardReferencer ) )
{
AllHardReferencers . Add ( HardReferencer ) ;
TArray < FAssetData > RefAssets ;
AssetRegistry . GetAssetsByPackageName ( HardReferencer , RefAssets , true ) ;
for ( const FAssetData & RefData : RefAssets )
{
if ( RefData . IsRedirector ( ) )
{
NextPackagesToProcess . Add ( RefData . PackageName ) ;
break ;
}
}
}
}
}
PackagesToProcess = MoveTemp ( NextPackagesToProcess ) ;
} while ( PackagesToProcess . Num ( ) > 0 ) ;
for ( FName HardReferencer : AllHardReferencers )
{
FString HardReferencerStr = HardReferencer . ToString ( ) ;
if ( ! IsInUncookedFolder ( HardReferencerStr ) )
{
TArray < FAssetData > ReferencerAssets ;
AssetRegistry . GetAssetsByPackageName ( HardReferencer , ReferencerAssets , true ) ;
for ( const FAssetData & ReferencerAssetData : ReferencerAssets )
{
// Skip levelscript BPs... for now
if ( ( ReferencerAssetData . PackageFlags & PKG_ContainsMap ) = = 0 )
{
bool bIsDataOnlyBP = false ;
if ( ReferencerAssetData . GetTagValue < bool > ( FBlueprintTags : : IsDataOnly , bIsDataOnlyBP ) )
{
if ( ! bIsDataOnlyBP )
{
UE_LOG ( LogLyraEditor , Display , TEXT ( " Loading referencing non-dataonly blueprint %s " ) , * HardReferencerStr ) ;
TArray < FString > WarningsAndErrors ;
if ( UEditorValidator_Load : : GetLoadWarningsAndErrorsForPackage ( HardReferencerStr , WarningsAndErrors ) )
{
for ( const FString & WarningOrError : WarningsAndErrors )
{
AssetFails ( InAsset , FText : : FromString ( WarningOrError ) , ValidationErrors ) ;
}
}
break ;
}
}
}
}
}
}
}
}
if ( GetValidationResult ( ) ! = EDataValidationResult : : Invalid )
{
AssetPasses ( InAsset ) ;
}
return GetValidationResult ( ) ;
}
# undef LOCTEXT_NAMESPACE