// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "GameplayTagContainer.h" #include "StructUtils/StructView.h" #include "StateTreeIndexTypes.h" #include "StateTreeEvents.generated.h" #define UE_API STATETREEMODULE_API /** Enum used for flow control during event iteration. */ UENUM() enum class EStateTreeLoopEvents : uint8 { /** Continues to next event. */ Next, /** Stops the event handling loop. */ Break, /** Consumes and removes the current event. */ Consume, }; /** * StateTree event with payload. */ USTRUCT(BlueprintType) struct FStateTreeEvent { GENERATED_BODY() FStateTreeEvent() = default; explicit FStateTreeEvent(const FGameplayTag InTag) : Tag(InTag) { } explicit FStateTreeEvent(const FGameplayTag InTag, const FConstStructView InPayload, const FName InOrigin) : Tag(InTag) , Payload(InPayload) , Origin(InOrigin) { } friend FORCEINLINE uint32 GetTypeHash(const FStateTreeEvent& Event) { uint32 Hash = GetTypeHash(Event.Tag); if (Event.Payload.IsValid()) { Hash = HashCombineFast(Hash, Event.Payload.GetScriptStruct()->GetStructTypeHash(Event.Payload.GetMemory())); } return Hash; } /** Tag describing the event */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default", meta=(Categories="StateTreeEvent")) FGameplayTag Tag; /** Optional payload for the event. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") FInstancedStruct Payload; /** Optional info to describe who sent the event. */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Default") FName Origin; }; /** * A struct wrapping FStateTreeEvent in shared struct, used to make it easier to refer to the events during State Tree update. */ USTRUCT() struct FStateTreeSharedEvent { GENERATED_BODY() FStateTreeSharedEvent() = default; explicit FStateTreeSharedEvent(const FGameplayTag InTag, const FConstStructView InPayload, const FName InOrigin) : Event(MakeShared(InTag, InPayload, InOrigin)) {} explicit FStateTreeSharedEvent(const FStateTreeEvent& InEvent) : Event(MakeShared(InEvent)) {} void AddStructReferencedObjects(FReferenceCollector& Collector); const FStateTreeEvent* Get() const { return Event.Get(); } FStateTreeEvent* GetMutable() { return Event.Get(); } const FStateTreeEvent* operator->() const { return Event.Get(); } FStateTreeEvent* operator->() { return Event.Get(); } const FStateTreeEvent& operator*() { check(Event.IsValid()); return *Event.Get(); } FStateTreeEvent& operator*() const { check(Event.IsValid()); return *Event.Get(); } bool IsValid() const { return Event.IsValid(); } bool operator==(const FStateTreeSharedEvent& Other) const { return Event == Other.Event; } protected: TSharedPtr Event; }; template<> struct TStructOpsTypeTraits : public TStructOpsTypeTraitsBase2 { enum { WithAddStructReferencedObjects = true, }; }; /** * Event queue buffering all the events to be processed by a State Tree. */ USTRUCT() struct FStateTreeEventQueue { GENERATED_BODY() /** Maximum number of events that can be buffered. */ static constexpr int32 MaxActiveEvents = 64; /** @return const view to all the events in the buffer. */ TConstArrayView GetEventsView() const { return SharedEvents; } /** @return view to all the events in the buffer. */ TArrayView GetMutableEventsView() { return SharedEvents; } /** Resets the events in the event queue */ void Reset() { SharedEvents.Reset(); } /** @return true if the queue has any events. */ bool HasEvents() const { return !SharedEvents.IsEmpty(); } /** * Buffers and event to be sent to the State Tree. * @param Owner Optional pointer to an owner UObject that is used for logging errors. * @param Tag tag identifying the event. * @param Payload Optional reference to the payload struct. * @param Origin Optional name identifying the origin of the event. */ UE_API void SendEvent(const UObject* Owner, const FGameplayTag& Tag, const FConstStructView Payload = FConstStructView(), const FName Origin = FName()); /** Consumes and removes the specified event from the event queue. */ UE_API void ConsumeEvent(const FStateTreeSharedEvent& Event); /** * Iterates over all events. * @param Function a lambda which takes const FStateTreeSharedEvent& Event, and returns EStateTreeLoopEvents. */ template void ForEachEvent(TFunc&& Function) { for (TArray::TIterator It(SharedEvents); It; ++It) { const EStateTreeLoopEvents Result = Function(*It); if (Result == EStateTreeLoopEvents::Break) { break; } if (Result == EStateTreeLoopEvents::Consume) { It.RemoveCurrent(); } } } UE_DEPRECATED(5.5, "Use GetEventsView() instead.") TConstArrayView GetEvents() const { return {}; } protected: // Used by FStateTreeExecutionState to implement deprecated functionality. TArray& GetEventsArray() { return SharedEvents; }; UPROPERTY() TArray SharedEvents; friend struct FStateTreeInstanceData; }; #undef UE_API