// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License. #pragma once #include "CoreMinimal.h" #include "UObject/Interface.h" #include "UObject/Object.h" #include "GameFramework/SaveGame.h" #include "Engine/HitResult.h" #include "Tasks/DirectiveUtilTask_MoveToLocation.h" #include "DirectiveUtilTestObject.generated.h" class UWorld; class UGameInstance; UINTERFACE() class UDirectiveUtilTestInterface : public UInterface { GENERATED_BODY() }; class IDirectiveUtilTestInterface { GENERATED_BODY() }; USTRUCT(BlueprintType) struct FDirectiveUtilCollisionValue { GENERATED_BODY() UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") int32 Value = 0; bool operator==(const FDirectiveUtilCollisionValue& Other) const { return Value == Other.Value; } friend uint32 GetTypeHash(const FDirectiveUtilCollisionValue&) { return 0; } }; template <> struct TStructOpsTypeTraits : TStructOpsTypeTraitsBase2 { enum { WithIdenticalViaEquality = true }; }; USTRUCT() struct FDirectiveUtilPodValue { GENERATED_BODY() UPROPERTY() int32 Index; UPROPERTY() float Weight; }; static_assert(TIsPODType::Value); UCLASS() class UDirectiveUtilTestObject : public UObject { GENERATED_BODY() public: UPROPERTY() TArray TestArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestStringArray; UPROPERTY() TArray TestNameArray; UPROPERTY() TArray TestTextArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestBoolArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestCollisionArray; UPROPERTY() TArray TestPodArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray> TestObjectArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestBoolSourceArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestStringSourceArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestCollisionSourceArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray> TestObjectSourceArray; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TArray TestIndices; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") bool TestBoolItem = false; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") FString TestStringItem; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") FDirectiveUtilCollisionValue TestCollisionItem; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") TObjectPtr TestObjectItem; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") bool TestInsertResult = false; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") int32 TestRemovedCount = 0; UPROPERTY(BlueprintReadWrite, Category = "Directive Utilities|Tests") bool TestRemoveAllResult = false; UFUNCTION(BlueprintImplementableEvent) void RunArrayThunkScenario(); UPROPERTY() TMap TestMap; UPROPERTY() TMap TestMap2; UPROPERTY() TMap TestStringKeyMap; UPROPERTY() TMap TestStringMap; UPROPERTY() TMap TestStringMap2; UPROPERTY() TMap TestStructValueMap; }; UCLASS() class UDirectiveUtilTestSaveGame : public USaveGame { GENERATED_BODY() public: UPROPERTY() int32 TestValue = 0; }; UCLASS() class UDirectiveUtilDelegateListener : public UObject { GENERATED_BODY() public: UPROPERTY() bool bCompleted = false; UPROPERTY() bool bFailed = false; UPROPERTY() int32 CompletedCount = 0; UPROPERTY() int32 HitCount = 0; UPROPERTY() int32 UpdatedCount = 0; UPROPERTY() int32 IterationCount = 0; UPROPERTY() float LastElapsedTime = 0.0f; UPROPERTY() float LastDeltaTime = 0.0f; UPROPERTY() float LastAlpha = 0.0f; UPROPERTY() TArray IterationIndices; UPROPERTY() TArray IterationRemaining; UPROPERTY() TArray UpdateElapsedTimes; UPROPERTY() TArray UpdateDeltaTimes; UPROPERTY() TArray UpdateAlphas; UPROPERTY() bool bLastSuccess = false; UPROPERTY() TObjectPtr LastObject = nullptr; UPROPERTY() TArray> LastObjects; UPROPERTY() TObjectPtr Keepalive = nullptr; UPROPERTY() TObjectPtr ScenarioWorld = nullptr; UPROPERTY() TObjectPtr ScenarioGameInstance = nullptr; UFUNCTION() void OnCompleted() { bCompleted = true; ++CompletedCount; } UFUNCTION() void OnObjectCompleted(UObject* Object) { bCompleted = true; ++CompletedCount; LastObject = Object; } UFUNCTION() void OnObjectFailed(UObject* Object) { bFailed = true; } UFUNCTION() void OnObjectsCompleted(const TArray& Objects) { bCompleted = true; ++CompletedCount; LastObjects.Reset(); LastObjects.Append(Objects); } UFUNCTION() void OnClassCompleted(UClass* Class) { bCompleted = true; ++CompletedCount; LastObject = Class; } UFUNCTION() void OnClassFailed(UClass* Class) { bFailed = true; } UFUNCTION() void OnTraceCompleted(const TArray& Hits) { bCompleted = true; ++CompletedCount; HitCount = Hits.Num(); } UFUNCTION() void OnBoolCompleted(bool bSuccess) { bCompleted = true; ++CompletedCount; bLastSuccess = bSuccess; } UFUNCTION() void OnDurationUpdated(float ElapsedTime, float DeltaTime, float Alpha) { ++UpdatedCount; LastElapsedTime = ElapsedTime; LastDeltaTime = DeltaTime; LastAlpha = Alpha; UpdateElapsedTimes.Add(ElapsedTime); UpdateDeltaTimes.Add(DeltaTime); UpdateAlphas.Add(Alpha); } UFUNCTION() void OnRepeatIteration(int32 Index, int32 Remaining) { ++IterationCount; IterationIndices.Add(Index); IterationRemaining.Add(Remaining); } }; UCLASS() class UDirectiveUtilTestMoveToLocationTask : public UDirectiveUtilTask_MoveToLocation { GENERATED_BODY() public: void Configure(AController* InController, const FVector InDestination, const bool bInCheckStuckMovement) { Controller = InController; Destination = InDestination; bCheckStuckMovement = bInCheckStuckMovement; } void ClearController() { Controller = nullptr; } void Complete() { ExecuteCompleted(false); } void RegisterTimersForTest(UWorld* World); bool HasRegisteredTimers() const; }; UCLASS() class UDirectiveUtilTestMoveToActorTask : public UDirectiveUtilTask_MoveToActor { GENERATED_BODY() public: void Configure(AController* InController, AActor* InGoal, const bool bInCheckStuckMovement) { Controller = InController; Goal = InGoal; bCheckStuckMovement = bInCheckStuckMovement; } void ClearController() { Controller = nullptr; } void Complete() { ExecuteCompleted(false); } void RegisterTimersForTest(UWorld* World); bool HasRegisteredTimers() const; };