2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "FunctionalTestingPrivatePCH.h"
# include "ObjectEditorUtils.h"
2014-10-27 08:35:45 -04:00
# include "VisualLogger/VisualLogger.h"
2015-03-11 11:02:39 -04:00
# if WITH_EDITORONLY_DATA
# include "FuncTestRenderingComponent.h"
# endif // WITH_EDITORONLY_DATA
# if WITH_EDITOR
# include "Engine/Selection.h"
# endif // WITH_EDITOR
2014-03-14 14:13:41 -04:00
2014-10-14 10:29:11 -04:00
AFunctionalTest : : AFunctionalTest ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
2014-03-14 14:13:41 -04:00
, TimesUpResult ( EFunctionalTestResult : : Failed )
, TimeLimit ( DefaultTimeLimit )
, TimesUpMessage ( NSLOCTEXT ( " FunctionalTest " , " DefaultTimesUpMessage " , " Time's up! " ) )
2014-04-23 19:29:53 -04:00
, bIsEnabled ( true )
2014-03-14 14:13:41 -04:00
, bIsRunning ( false )
2014-06-06 06:27:44 -04:00
, TotalTime ( 0.f )
2014-03-14 14:13:41 -04:00
{
PrimaryActorTick . bCanEverTick = true ;
PrimaryActorTick . bStartWithTickEnabled = false ;
2014-11-11 10:35:51 -05:00
2015-02-10 04:34:10 -05:00
SpriteComponent = CreateDefaultSubobject < UBillboardComponent > ( TEXT ( " Sprite " ) ) ;
2014-04-23 19:29:53 -04:00
if ( SpriteComponent )
{
SpriteComponent - > bHiddenInGame = false ;
SpriteComponent - > AlwaysLoadOnClient = false ;
SpriteComponent - > AlwaysLoadOnServer = false ;
2014-03-14 14:13:41 -04:00
# if WITH_EDITORONLY_DATA
2014-04-23 19:29:53 -04:00
if ( ! IsRunningCommandlet ( ) )
2014-04-02 18:09:23 -04:00
{
2014-04-23 19:29:53 -04:00
struct FConstructorStatics
2014-04-02 18:09:23 -04:00
{
2014-04-23 19:29:53 -04:00
ConstructorHelpers : : FObjectFinderOptional < UTexture2D > Texture ;
FName ID_FTests ;
FText NAME_FTests ;
2014-03-14 14:13:41 -04:00
2014-04-23 19:29:53 -04:00
FConstructorStatics ( )
: Texture ( TEXT ( " /Engine/EditorResources/S_FTest " ) )
, ID_FTests ( TEXT ( " FTests " ) )
, NAME_FTests ( NSLOCTEXT ( " SpriteCategory " , " FTests " , " FTests " ) )
{
}
} ;
static FConstructorStatics ConstructorStatics ;
2014-03-14 14:13:41 -04:00
2014-04-23 19:29:53 -04:00
SpriteComponent - > Sprite = ConstructorStatics . Texture . Get ( ) ;
SpriteComponent - > SpriteInfo . Category = ConstructorStatics . ID_FTests ;
SpriteComponent - > SpriteInfo . DisplayName = ConstructorStatics . NAME_FTests ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 19:29:53 -04:00
# endif
RootComponent = SpriteComponent ;
2014-03-14 14:13:41 -04:00
}
2015-03-11 11:02:39 -04:00
# if WITH_EDITORONLY_DATA
RenderComp = CreateDefaultSubobject < UFuncTestRenderingComponent > ( TEXT ( " RenderComp " ) ) ;
RenderComp - > PostPhysicsComponentTick . bCanEverTick = false ;
RenderComp - > AttachParent = RootComponent ;
# endif // WITH_EDITORONLY_DATA
# if WITH_EDITOR
static bool bSelectionHandlerSetUp = false ;
if ( HasAnyFlags ( RF_ClassDefaultObject ) & & ! HasAnyFlags ( RF_TagGarbageTemp ) & & bSelectionHandlerSetUp = = false )
{
USelection : : SelectObjectEvent . AddStatic ( & AFunctionalTest : : OnSelectObject ) ;
bSelectionHandlerSetUp = true ;
}
# endif // WITH_EDITOR
2014-03-14 14:13:41 -04:00
}
void AFunctionalTest : : Tick ( float DeltaSeconds )
{
// already requested not to tick.
if ( bIsRunning = = false )
{
return ;
}
2014-06-06 06:27:44 -04:00
TotalTime + = DeltaSeconds ;
if ( TimeLimit > 0.f & & TotalTime > TimeLimit )
2014-03-14 14:13:41 -04:00
{
FinishTest ( TimesUpResult , TimesUpMessage . ToString ( ) ) ;
}
else
{
Super : : Tick ( DeltaSeconds ) ;
}
}
2014-06-17 08:31:02 -04:00
bool AFunctionalTest : : StartTest ( const TArray < FString > & Params )
2014-03-14 14:13:41 -04:00
{
2014-04-23 19:29:53 -04:00
FailureMessage = TEXT ( " " ) ;
2014-11-11 10:35:51 -05:00
2014-06-06 06:27:44 -04:00
TotalTime = 0.f ;
2014-03-14 14:13:41 -04:00
if ( TimeLimit > 0 )
{
SetActorTickEnabled ( true ) ;
}
bIsRunning = true ;
2014-06-09 11:13:04 -04:00
GoToObservationPoint ( ) ;
2014-03-14 14:13:41 -04:00
OnTestStart . Broadcast ( ) ;
2014-04-23 19:29:53 -04:00
return true ;
2014-03-14 14:13:41 -04:00
}
void AFunctionalTest : : FinishTest ( TEnumAsByte < EFunctionalTestResult : : Type > TestResult , const FString & Message )
{
2015-01-20 09:33:54 -05:00
const static UEnum * FTestResultTypeEnum = FindObject < UEnum > ( NULL , TEXT ( " FunctionalTesting.EFunctionalTestResult " ) ) ;
2014-03-14 14:13:41 -04:00
2014-06-09 11:13:04 -04:00
if ( bIsRunning = = false )
{
// ignore
return ;
}
2014-06-17 08:31:02 -04:00
Result = TestResult ;
2014-03-14 14:13:41 -04:00
bIsRunning = false ;
SetActorTickEnabled ( false ) ;
OnTestFinished . Broadcast ( ) ;
2014-09-29 04:23:44 -04:00
AActor * * ActorToDestroy = AutoDestroyActors . GetData ( ) ;
2014-03-14 14:13:41 -04:00
for ( int32 ActorIndex = 0 ; ActorIndex < AutoDestroyActors . Num ( ) ; + + ActorIndex , + + ActorToDestroy )
{
if ( * ActorToDestroy ! = NULL )
{
// will be removed next frame
( * ActorToDestroy ) - > SetLifeSpan ( 0.01f ) ;
}
}
const FText ResultText = FTestResultTypeEnum - > GetEnumText ( TestResult . GetValue ( ) ) ;
2014-06-17 08:31:02 -04:00
const FString OutMessage = FString : : Printf ( TEXT ( " %s %s: \" %s \' " )
2014-03-14 14:13:41 -04:00
, * GetActorLabel ( )
, * ResultText . ToString ( )
, Message . IsEmpty ( ) = = false ? * Message : TEXT ( " Test finished " ) ) ;
2015-03-18 12:16:37 -04:00
const FString AdditionalDetails = FString : : Printf ( TEXT ( " %s %s, time %.2fs " ) , * GetAdditionalTestFinishedMessage ( TestResult ) , * OnAdditionalTestFinishedMessageRequest ( TestResult ) , TotalTime ) ;
2014-03-14 14:13:41 -04:00
AutoDestroyActors . Reset ( ) ;
2014-06-17 08:31:02 -04:00
2014-03-14 14:13:41 -04:00
switch ( TestResult . GetValue ( ) )
{
case EFunctionalTestResult : : Invalid :
case EFunctionalTestResult : : Error :
case EFunctionalTestResult : : Failed :
UE_VLOG ( this , LogFunctionalTest , Error , TEXT ( " %s " ) , * OutMessage ) ;
2014-06-17 08:31:02 -04:00
UFunctionalTestingManager : : AddError ( FText : : FromString ( OutMessage ) ) ;
2014-03-14 14:13:41 -04:00
break ;
2014-06-17 08:31:02 -04:00
case EFunctionalTestResult : : Running :
UE_VLOG ( this , LogFunctionalTest , Warning , TEXT ( " %s " ) , * OutMessage ) ;
UFunctionalTestingManager : : AddWarning ( FText : : FromString ( OutMessage ) ) ;
break ;
2014-03-14 14:13:41 -04:00
default :
UE_VLOG ( this , LogFunctionalTest , Log , TEXT ( " %s " ) , * OutMessage ) ;
2014-06-17 08:31:02 -04:00
UFunctionalTestingManager : : AddLogItem ( FText : : FromString ( OutMessage ) ) ;
2014-03-14 14:13:41 -04:00
break ;
}
2014-06-17 08:31:02 -04:00
if ( AdditionalDetails . IsEmpty ( ) = = false )
2014-06-16 09:55:19 -04:00
{
2014-06-17 08:31:02 -04:00
UFunctionalTestingManager : : AddLogItem ( FText : : FromString ( AdditionalDetails ) ) ;
2014-06-16 09:55:19 -04:00
}
2014-03-14 14:13:41 -04:00
TestFinishedObserver . ExecuteIfBound ( this ) ;
}
2014-06-25 05:47:19 -04:00
void AFunctionalTest : : EndPlay ( const EEndPlayReason : : Type EndPlayReason )
{
TestFinishedObserver . Unbind ( ) ;
Super : : EndPlay ( EndPlayReason ) ;
}
2014-04-23 19:29:53 -04:00
void AFunctionalTest : : CleanUp ( )
{
FailureMessage = TEXT ( " " ) ;
}
2014-03-14 14:13:41 -04:00
//@todo add "warning" level here
void AFunctionalTest : : LogMessage ( const FString & Message )
{
UE_VLOG ( this , LogFunctionalTest , Warning
, TEXT ( " %s> %s " )
, * GetActorLabel ( ) , * Message ) ;
}
void AFunctionalTest : : SetTimeLimit ( float InTimeLimit , TEnumAsByte < EFunctionalTestResult : : Type > InResult )
{
if ( InTimeLimit < 0.f )
{
UE_VLOG ( this , LogFunctionalTest , Warning
, TEXT ( " %s> Trying to set TimeLimit to less than 0. Falling back to 0 (infinite). " )
, * GetActorLabel ( ) ) ;
InTimeLimit = 0.f ;
}
TimeLimit = InTimeLimit ;
if ( InResult = = EFunctionalTestResult : : Invalid )
{
UE_VLOG ( this , LogFunctionalTest , Warning
, TEXT ( " %s> Trying to set test Result to \' Invalid \' . Falling back to \' Failed \' " )
, * GetActorLabel ( ) ) ;
2014-05-12 08:42:24 -04:00
InResult = EFunctionalTestResult : : Failed ;
2014-03-14 14:13:41 -04:00
}
TimesUpResult = InResult ;
}
2015-03-11 11:02:39 -04:00
void AFunctionalTest : : GatherRelevantActors ( TArray < AActor * > & OutActors ) const
{
if ( ObservationPoint )
{
OutActors . AddUnique ( ObservationPoint ) ;
}
for ( auto Actor : AutoDestroyActors )
{
if ( Actor )
{
OutActors . AddUnique ( Actor ) ;
}
}
OutActors . Append ( DebugGatherRelevantActors ( ) ) ;
}
2014-03-14 14:13:41 -04:00
void AFunctionalTest : : RegisterAutoDestroyActor ( AActor * ActorToAutoDestroy )
{
AutoDestroyActors . AddUnique ( ActorToAutoDestroy ) ;
}
# if WITH_EDITOR
void AFunctionalTest : : PostEditChangeProperty ( struct FPropertyChangedEvent & PropertyChangedEvent )
{
static const FName NAME_FunctionalTesting = FName ( TEXT ( " FunctionalTesting " ) ) ;
static const FName NAME_TimeLimit = FName ( TEXT ( " TimeLimit " ) ) ;
static const FName NAME_TimesUpResult = FName ( TEXT ( " TimesUpResult " ) ) ;
Super : : PostEditChangeProperty ( PropertyChangedEvent ) ;
if ( PropertyChangedEvent . Property ! = NULL )
{
if ( FObjectEditorUtils : : GetCategoryFName ( PropertyChangedEvent . Property ) = = NAME_FunctionalTesting )
{
// first validate new data since there are some dependencies
if ( PropertyChangedEvent . Property - > GetFName ( ) = = NAME_TimeLimit )
{
if ( TimeLimit < 0.f )
{
TimeLimit = 0.f ;
}
}
else if ( PropertyChangedEvent . Property - > GetFName ( ) = = NAME_TimesUpResult )
{
if ( TimesUpResult = = EFunctionalTestResult : : Invalid )
{
TimesUpResult = EFunctionalTestResult : : Failed ;
}
}
}
}
}
2015-03-11 11:02:39 -04:00
void AFunctionalTest : : OnSelectObject ( UObject * NewSelection )
{
AFunctionalTest * AsFTest = Cast < AFunctionalTest > ( NewSelection ) ;
if ( AsFTest )
{
AsFTest - > MarkComponentsRenderStateDirty ( ) ;
}
}
2014-04-23 19:29:53 -04:00
# endif // WITH_EDITOR
2014-06-09 11:13:04 -04:00
void AFunctionalTest : : GoToObservationPoint ( )
{
if ( ObservationPoint = = NULL )
{
return ;
}
UWorld * World = GetWorld ( ) ;
if ( World )
{
APlayerController * PC = World - > GetFirstPlayerController ( ) ;
if ( PC & & PC - > GetPawn ( ) )
{
2014-06-26 17:26:58 -04:00
PC - > GetPawn ( ) - > TeleportTo ( ObservationPoint - > GetActorLocation ( ) , ObservationPoint - > GetActorRotation ( ) , /*bIsATest=*/ false , /*bNoCheck=*/ true ) ;
2014-06-09 11:13:04 -04:00
PC - > SetControlRotation ( ObservationPoint - > GetActorRotation ( ) ) ;
}
}
2014-10-30 17:10:56 -04:00
}
/** Returns SpriteComponent subobject **/
UBillboardComponent * AFunctionalTest : : GetSpriteComponent ( ) { return SpriteComponent ; }