From b54cf556dba0ed8f8e9439757b18eff528dd90ff Mon Sep 17 00:00:00 2001 From: Michael Delva Date: Tue, 25 Feb 2025 20:46:04 +0100 Subject: [PATCH 1/3] Added calls to IsDataValid to various interactable objects --- .../Interaction/GBFInteractableComponent.cpp | 7 +++ .../Interaction/GBFInteractionOption.cpp | 47 ++++++++++++++++++- .../Interaction/GBFInteractionOptionsData.cpp | 19 +++++++- .../Private/Pickupable/GBFPickupable.cpp | 1 + .../Interaction/GBFInteractableComponent.h | 4 ++ .../Public/Interaction/GBFInteractionOption.h | 12 +++++ .../Interaction/GBFInteractionOptionsData.h | 4 ++ 7 files changed, 92 insertions(+), 2 deletions(-) diff --git a/Source/GameBaseFramework/Private/Interaction/GBFInteractableComponent.cpp b/Source/GameBaseFramework/Private/Interaction/GBFInteractableComponent.cpp index 99f2ea0d..75dfb128 100644 --- a/Source/GameBaseFramework/Private/Interaction/GBFInteractableComponent.cpp +++ b/Source/GameBaseFramework/Private/Interaction/GBFInteractableComponent.cpp @@ -10,6 +10,13 @@ UGBFInteractableComponent::UGBFInteractableComponent() bIsEnabled = true; } +#if WITH_EDITOR +EDataValidationResult UGBFInteractableComponent::IsDataValid( FDataValidationContext & context ) const +{ + return InteractionOptionContainer.IsDataValid( context ); +} +#endif + void UGBFInteractableComponent::UpdateInteractions( UGBFInteractionOptionsData * options_data ) { if ( options_data == nullptr ) diff --git a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp index b9219dda..d54126fe 100644 --- a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp +++ b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp @@ -1,5 +1,26 @@ #include "Interaction/GBFInteractionOption.h" +#include "DVEDataValidator.h" + +#if WITH_EDITOR +EDataValidationResult FGBFInteractionWidgetInfos::IsDataValid( FDataValidationContext & context ) const +{ + return FDVEDataValidator( context ) + .IsValid( VALIDATOR_GET_PROPERTY( InteractionWidgetClass ) ) + .Result(); +} +#endif + +#if WITH_EDITOR +EDataValidationResult FGBFInteractionOption::IsDataValid( FDataValidationContext & context ) const +{ + return FDVEDataValidator( context ) + .NotEmpty( VALIDATOR_GET_PROPERTY( Text ) ) + .NotNull( VALIDATOR_GET_PROPERTY( InteractionAbility ) ) + .Result(); +} +#endif + FGBFInteractionOptionContainer::FGBFInteractionOptionContainer() : InteractionsId( INDEX_NONE ) { @@ -26,4 +47,28 @@ void FGBFInteractionOptionContainer::ResetOptions() { Options.Reset(); IncrementId(); -} \ No newline at end of file +} + +#if WITH_EDITOR +EDataValidationResult FGBFInteractionOptionContainer::IsDataValid( FDataValidationContext & context ) const +{ + CommonWidgetInfos.IsDataValid( context ); + + for ( const auto & option : Options ) + { + option.IsDataValid( context ); + + if ( DefaultInputAction == nullptr && option.InputAction == nullptr ) + { + context.AddError( FText::FromString( TEXT( "No default input action is defined, and the option does not have any InputAction either" ) ) ); + } + else if ( DefaultInputAction == option.InputAction ) + { + context.AddWarning( FText::FromString( TEXT( "The same input action is defined for the default and for the option" ) ) ); + } + } + + return FDVEDataValidator( context ) + .Result(); +} +#endif \ No newline at end of file diff --git a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp index caecb98d..c977dded 100644 --- a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp +++ b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp @@ -1,7 +1,24 @@ #include "Interaction/GBFInteractionOptionsData.h" +#include "DVEDataValidator.h" + UGBFInteractionOptionsData::UGBFInteractionOptionsData() : bOverrideContainer( false ), bRemoveAllOptions( false ) { -} \ No newline at end of file +} + +#if WITH_EDITOR +EDataValidationResult UGBFInteractionOptionsData::IsDataValid( FDataValidationContext & context ) const +{ + OptionContainer.IsDataValid( context ); + + for ( const auto & option : Options ) + { + option.IsDataValid( context ); + } + + return FDVEDataValidator( context ) + .Result(); +} +#endif \ No newline at end of file diff --git a/Source/GameBaseFramework/Private/Pickupable/GBFPickupable.cpp b/Source/GameBaseFramework/Private/Pickupable/GBFPickupable.cpp index 05cd2c2c..ef1fa68c 100644 --- a/Source/GameBaseFramework/Private/Pickupable/GBFPickupable.cpp +++ b/Source/GameBaseFramework/Private/Pickupable/GBFPickupable.cpp @@ -49,6 +49,7 @@ EDataValidationResult AGBFPickupable::IsDataValid( FDataValidationContext & cont { return FDVEDataValidator( context ) .NotNull( VALIDATOR_GET_PROPERTY( EquipmentDefinition ) ) + .CombineWith( InteractableComponent ) .Result(); } diff --git a/Source/GameBaseFramework/Public/Interaction/GBFInteractableComponent.h b/Source/GameBaseFramework/Public/Interaction/GBFInteractableComponent.h index 6d66fbc7..92e1e6b3 100644 --- a/Source/GameBaseFramework/Public/Interaction/GBFInteractableComponent.h +++ b/Source/GameBaseFramework/Public/Interaction/GBFInteractableComponent.h @@ -26,6 +26,10 @@ class GAMEBASEFRAMEWORK_API UGBFInteractableComponent : public UActorComponent FGBFOnInteractableInteractionRadiusStateChangedDelegate & OnInteractableLeftRadius(); FGBFOnInteractionsUpdatedDelegate & OnInteractionsUpdated(); +#if WITH_EDITOR + EDataValidationResult IsDataValid( FDataValidationContext & context ) const override; +#endif + const FGBFInteractionOptionContainer & GetInteractableOptions() const; bool IsEnabled() const; void SetEnabled( bool enabled ); diff --git a/Source/GameBaseFramework/Public/Interaction/GBFInteractionOption.h b/Source/GameBaseFramework/Public/Interaction/GBFInteractionOption.h index b4f2e085..89bae3ad 100644 --- a/Source/GameBaseFramework/Public/Interaction/GBFInteractionOption.h +++ b/Source/GameBaseFramework/Public/Interaction/GBFInteractionOption.h @@ -19,6 +19,10 @@ struct FGBFInteractionWidgetInfos { GENERATED_BODY() +#if WITH_EDITOR + EDataValidationResult IsDataValid( FDataValidationContext & context ) const; +#endif + /** The widget to show for this kind of interaction. */ UPROPERTY( EditAnywhere, BlueprintReadWrite ) TSoftClassPtr< UUserWidget > InteractionWidgetClass; @@ -76,6 +80,10 @@ struct FGBFInteractionOption FGBFInteractionOption() = default; +#if WITH_EDITOR + EDataValidationResult IsDataValid( FDataValidationContext & context ) const; +#endif + /** Simple text the interaction might return */ UPROPERTY( EditAnywhere, BlueprintReadOnly ) FText Text = FText::GetEmpty(); @@ -132,6 +140,10 @@ struct FGBFInteractionOptionContainer const TArray< FGBFInteractionOption > & GetOptions() const; int GetInteractionsId() const; +#if WITH_EDITOR + EDataValidationResult IsDataValid( FDataValidationContext & context ) const; +#endif + UPROPERTY( EditAnywhere, BlueprintReadOnly ) TSoftObjectPtr< UInputMappingContext > InputMappingContext; diff --git a/Source/GameBaseFramework/Public/Interaction/GBFInteractionOptionsData.h b/Source/GameBaseFramework/Public/Interaction/GBFInteractionOptionsData.h index cc93ecde..980ee55d 100644 --- a/Source/GameBaseFramework/Public/Interaction/GBFInteractionOptionsData.h +++ b/Source/GameBaseFramework/Public/Interaction/GBFInteractionOptionsData.h @@ -15,6 +15,10 @@ class GAMEBASEFRAMEWORK_API UGBFInteractionOptionsData final : public UDataAsset public: UGBFInteractionOptionsData(); +#if WITH_EDITOR + EDataValidationResult IsDataValid( FDataValidationContext & context ) const override; +#endif + UPROPERTY( EditAnywhere, meta = ( InlineEditConditionToggle ) ) uint8 bOverrideContainer : 1; From 8defcd375d9eca9f184ec51ce310c387ba49e296 Mon Sep 17 00:00:00 2001 From: Michael Delva Date: Tue, 25 Feb 2025 22:22:00 +0100 Subject: [PATCH 2/3] Fixed validation of InteractionWidgetClass --- .../Private/Interaction/GBFInteractionOption.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp index d54126fe..50018e6f 100644 --- a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp +++ b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOption.cpp @@ -6,7 +6,7 @@ EDataValidationResult FGBFInteractionWidgetInfos::IsDataValid( FDataValidationContext & context ) const { return FDVEDataValidator( context ) - .IsValid( VALIDATOR_GET_PROPERTY( InteractionWidgetClass ) ) + .NotNull( VALIDATOR_GET_PROPERTY( InteractionWidgetClass ) ) .Result(); } #endif From 73bfdb286093ada1ec234e04c10af25e4e9a93cb Mon Sep 17 00:00:00 2001 From: Michael Delva Date: Wed, 26 Feb 2025 10:05:24 +0100 Subject: [PATCH 3/3] Dont validate the container if it's not used in the interaction options data --- .../Private/Interaction/GBFInteractionOptionsData.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp index c977dded..caa721e0 100644 --- a/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp +++ b/Source/GameBaseFramework/Private/Interaction/GBFInteractionOptionsData.cpp @@ -11,7 +11,10 @@ UGBFInteractionOptionsData::UGBFInteractionOptionsData() : #if WITH_EDITOR EDataValidationResult UGBFInteractionOptionsData::IsDataValid( FDataValidationContext & context ) const { - OptionContainer.IsDataValid( context ); + if ( bOverrideContainer ) + { + OptionContainer.IsDataValid( context ); + } for ( const auto & option : Options ) {