2022-05-31 04:51:18 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
# include "StateTree.h"
2023-05-23 10:46:16 -04:00
# include "StateTreeExecutionTypes.h"
2022-06-29 04:52:18 -04:00
# include "StateTreeNodeBase.h"
2022-09-23 20:02:42 -04:00
# include "Experimental/ConcurrentLinearAllocator.h"
2024-03-11 04:54:44 -04:00
# include "Templates/IsInvocable.h"
2022-05-31 04:51:18 -04:00
2023-01-25 02:42:36 -05:00
struct FGameplayTag ;
struct FInstancedPropertyBag ;
2023-12-13 06:34:27 -05:00
struct FStateTreeExecutionContext ;
2024-03-28 05:18:19 -04:00
struct FStateTreeReferenceOverrides ;
2022-05-31 04:51:18 -04:00
struct FStateTreeEvaluatorBase ;
struct FStateTreeTaskBase ;
struct FStateTreeConditionBase ;
2022-09-01 09:06:53 -04:00
struct FStateTreeEvent ;
2023-01-23 12:48:04 -05:00
struct FStateTreeTransitionRequest ;
2023-03-14 13:35:46 -04:00
struct FStateTreeInstanceDebugId ;
2024-03-28 05:18:19 -04:00
struct FStateTreeReference ;
2022-05-31 04:51:18 -04:00
/**
2023-12-13 06:34:27 -05:00
* Delegate used by the execution context to collect external data views for a given StateTree asset .
* The caller is expected to iterate over the ExternalDataDescs array , find the matching external data ,
* and store it in the OutDataViews at the same index :
*
* for ( int32 Index = 0 ; Index < ExternalDataDescs . Num ( ) ; Index + + )
* {
* const FStateTreeExternalDataDesc & Desc = ExternalDataDescs [ Index ] ;
* // Find data requested by Desc
* OutDataViews [ Index ] = . . . ;
* }
*/
DECLARE_DELEGATE_RetVal_FourParams ( bool , FOnCollectStateTreeExternalData , const FStateTreeExecutionContext & /*Context*/ , const UStateTree * /*StateTree*/ , TArrayView < const FStateTreeExternalDataDesc > /*ExternalDataDescs*/ , TArrayView < FStateTreeDataView > /*OutDataViews*/ ) ;
/**
* StateTree Execution Context is a helper that is used to update StateTree instance data .
2022-09-23 20:02:42 -04:00
*
* The context is meant to be temporary , you should not store a context across multiple frames .
*
2023-12-13 06:34:27 -05:00
* The owner is used as the owner of the instantiated UObjects in the instance data and logging ,
* it should have same or greater lifetime as the InstanceData .
2022-09-23 20:02:42 -04:00
*
2023-12-13 06:34:27 -05:00
* In common case you can use the constructor to initialize the context , and us a helper struct
* to set up the context data and external data getter :
2022-09-23 20:02:42 -04:00
*
* FStateTreeExecutionContext Context ( * GetOwner ( ) , * StateTreeRef . GetStateTree ( ) , InstanceData ) ;
* if ( SetContextRequirements ( Context ) )
* {
* Context . Tick ( DeltaTime ) ;
* }
2023-12-13 06:34:27 -05:00
*
2022-09-23 20:02:42 -04:00
*
* bool UMyComponent : : SetContextRequirements ( FStateTreeExecutionContext & Context )
* {
* if ( ! Context . IsValid ( ) )
* {
* return false ;
* }
* // Setup context data
2023-12-13 06:34:27 -05:00
* Context . SetContextDataByName ( . . . ) ;
* . . .
*
* Context . SetCollectExternalDataCallback ( FOnCollectStateTreeExternalData : : CreateUObject ( this , & UMyComponent : : CollectExternalData ) ;
*
* return Context . AreContextDataViewsValid ( ) ;
* }
*
* bool UMyComponent : : CollectExternalData ( const FStateTreeExecutionContext & Context , const UStateTree * StateTree , TArrayView < const FStateTreeExternalDataDesc > ExternalDataDescs , TArrayView < FStateTreeDataView > OutDataViews )
* {
* . . .
* for ( int32 Index = 0 ; Index < ExternalDataDescs . Num ( ) ; Index + + )
* {
* const FStateTreeExternalDataDesc & Desc = ExternalDataDescs [ Index ] ;
* if ( Desc . Struct - > IsChildOf ( UWorldSubsystem : : StaticClass ( ) ) )
* {
* UWorldSubsystem * Subsystem = World - > GetSubsystemBase ( Cast < UClass > ( const_cast < UStruct * > ( Desc . Struct . Get ( ) ) ) ) ;
* OutDataViews [ Index ] = FStateTreeDataView ( Subsystem ) ;
* }
* . . .
* }
2022-09-23 20:02:42 -04:00
* return true ;
* }
2023-12-13 06:34:27 -05:00
*
* In this example the SetContextRequirements ( ) method is used to set the context defined in the schema ,
* and the delegate FOnCollectStateTreeExternalData is used to query the external data required by the tasks and conditions .
*
* In case the State Tree links to other state tree assets , the collect external data might get called
* multiple times , once for each asset .
2022-05-31 04:51:18 -04:00
*/
struct STATETREEMODULE_API FStateTreeExecutionContext
{
public :
2024-06-10 15:59:27 -04:00
FStateTreeExecutionContext ( UObject & InOwner , const UStateTree & InStateTree , FStateTreeInstanceData & InInstanceData , const FOnCollectStateTreeExternalData & CollectExternalDataCallback = { } , const EStateTreeRecordTransitions RecordTransitions = EStateTreeRecordTransitions : : No ) ;
2024-03-20 08:28:58 -04:00
/** Construct an execution context from a parent context and another tree. Useful to run a subtree from the parent context with the same schema. */
FStateTreeExecutionContext ( const FStateTreeExecutionContext & InContextToCopy , const UStateTree & InStateTree , FStateTreeInstanceData & InInstanceData ) ;
2022-05-31 04:51:18 -04:00
virtual ~ FStateTreeExecutionContext ( ) ;
/** Updates data view of the parameters by using the default values defined in the StateTree asset. */
2024-01-22 05:38:03 -05:00
UE_DEPRECATED ( 5.4 , " Not providing parameters to Start() leads to setting up default values now. " )
2022-05-31 04:51:18 -04:00
void SetDefaultParameters ( ) ;
/**
* Updates data view of the parameters by replacing the default values defined in the StateTree asset by the provided values .
* Note : caller is responsible to make sure external parameters lifetime matches the context .
*/
2024-01-22 05:38:03 -05:00
UE_DEPRECATED ( 5.4 , " Provide parameters through Start() instead. " )
2022-05-31 04:51:18 -04:00
void SetParameters ( const FInstancedPropertyBag & Parameters ) ;
2023-12-13 06:34:27 -05:00
/** Sets callback used to collect external data views during State Tree execution. */
void SetCollectExternalDataCallback ( const FOnCollectStateTreeExternalData & Callback ) ;
2024-03-28 05:18:19 -04:00
/** */
void SetLinkedStateTreeOverrides ( const FStateTreeReferenceOverrides * InLinkedStateTreeOverrides ) ;
const FStateTreeReference * GetLinkedStateTreeOverrideForTag ( const FGameplayTag StateTag ) const ;
2022-05-31 04:51:18 -04:00
2022-09-23 20:02:42 -04:00
/** @return the StateTree asset in use. */
2023-11-22 04:08:33 -05:00
const UStateTree * GetStateTree ( ) const { return & RootStateTree ; }
2022-05-31 04:51:18 -04:00
2022-11-01 15:11:19 -04:00
/** @return const references to the instance data in use, or nullptr if the context is not valid. */
2022-09-23 20:02:42 -04:00
const FStateTreeInstanceData * GetInstanceData ( ) const { return & InstanceData ; }
2022-05-31 04:51:18 -04:00
2024-08-15 11:29:44 -04:00
/** @return mutable references to the instance data in use, or nullptr if the context is not valid. */
2022-09-23 20:02:42 -04:00
FStateTreeInstanceData * GetMutableInstanceData ( ) const { return & InstanceData ; }
2022-11-01 15:11:19 -04:00
2022-11-30 07:17:26 -05:00
/** @return mutable references to the instance data in use. */
const FStateTreeEventQueue & GetEventQueue ( ) const { return InstanceData . GetEventQueue ( ) ; }
/** @return mutable references to the instance data in use. */
FStateTreeEventQueue & GetMutableEventQueue ( ) const { return InstanceData . GetMutableEventQueue ( ) ; }
2022-11-01 15:11:19 -04:00
2022-05-31 04:51:18 -04:00
/** @return The owner of the context */
2022-09-23 20:02:42 -04:00
UObject * GetOwner ( ) const { return & Owner ; }
2022-05-31 04:51:18 -04:00
/** @return The world of the owner or nullptr if the owner is not set. */
2022-09-23 20:02:42 -04:00
UWorld * GetWorld ( ) const { return Owner . GetWorld ( ) ; } ;
2022-05-31 04:51:18 -04:00
/** @return True of the the execution context is valid and initialized. */
2023-11-22 04:08:33 -05:00
bool IsValid ( ) const { return RootStateTree . IsReadyToRun ( ) ; }
2022-05-31 04:51:18 -04:00
2024-01-22 05:38:03 -05:00
/**
* Start executing .
* @ param InitialParameters Optional override of parameters initial values
2024-04-23 14:17:24 -04:00
* @ param RandomSeed Optional override of initial seed for RandomStream . By default FPlatformTime : : Cycles ( ) will be used .
2024-01-22 05:38:03 -05:00
* @ return Tree execution status after the start .
*/
2024-04-23 14:17:24 -04:00
EStateTreeRunStatus Start ( const FInstancedPropertyBag * InitialParameters = nullptr , int32 RandomSeed = - 1 ) ;
2022-09-23 20:02:42 -04:00
2023-06-05 06:33:07 -04:00
/**
* Stop executing if the tree is running .
* @ param CompletionStatus Status ( and terminal state ) reported in the transition when the tree is stopped .
* @ return Tree execution status at stop , can be CompletionStatus , or earlier status if the tree is not running .
*/
EStateTreeRunStatus Stop ( const EStateTreeRunStatus CompletionStatus = EStateTreeRunStatus : : Stopped ) ;
2022-05-31 04:51:18 -04:00
2022-12-16 05:45:13 -05:00
/**
2024-04-12 06:04:01 -04:00
* Tick the state tree logic , updates the tasks and triggers transitions .
2022-12-16 05:45:13 -05:00
* @ param DeltaTime time to advance the logic .
* @ returns tree run status after the tick .
*/
2022-09-23 20:02:42 -04:00
EStateTreeRunStatus Tick ( const float DeltaTime ) ;
2022-05-31 04:51:18 -04:00
2024-04-12 06:04:01 -04:00
/**
* Tick the state tree logic partially , updates the tasks .
* For full update TickTriggerTransitions ( ) should be called after .
* @ param DeltaTime time to advance the logic .
* @ returns tree run status after the partial tick .
*/
EStateTreeRunStatus TickUpdateTasks ( const float DeltaTime ) ;
/**
* Tick the state tree logic partially , triggers the transitions .
* For full update TickUpdateTasks ( ) should be called before .
* @ returns tree run status after the partial tick .
*/
EStateTreeRunStatus TickTriggerTransitions ( ) ;
2022-12-16 05:45:13 -05:00
/** @return the tree run status. */
EStateTreeRunStatus GetStateTreeRunStatus ( ) const ;
2022-09-01 09:06:53 -04:00
/** @return the status of the last tick function */
2022-09-23 20:02:42 -04:00
EStateTreeRunStatus GetLastTickStatus ( ) const ;
2022-09-01 09:06:53 -04:00
/** @return reference to the list of currently active states. */
2023-11-22 04:08:33 -05:00
UE_DEPRECATED ( 5.4 , " Use GetActiveFrames() instead. " )
const FStateTreeActiveStates & GetActiveStates ( ) const
{
static FStateTreeActiveStates Dummy ;
return Dummy ;
}
/** @return reference to the list of currently active frames and states. */
TConstArrayView < FStateTreeExecutionFrame > GetActiveFrames ( ) const ;
2022-09-01 09:06:53 -04:00
# if WITH_GAMEPLAY_DEBUGGER
/** @return Debug string describing the current state of the execution */
2022-09-23 20:02:42 -04:00
FString GetDebugInfoString ( ) const ;
2022-09-01 09:06:53 -04:00
# endif // WITH_GAMEPLAY_DEBUGGER
# if WITH_STATETREE_DEBUG
2022-09-23 20:02:42 -04:00
int32 GetStateChangeCount ( ) const ;
2022-09-01 09:06:53 -04:00
2022-09-23 20:02:42 -04:00
void DebugPrintInternalLayout ( ) ;
2022-09-01 09:06:53 -04:00
# endif
/** @return the name of the active state. */
2022-09-23 20:02:42 -04:00
FString GetActiveStateName ( ) const ;
2022-09-01 09:06:53 -04:00
/** @return the names of all the active state. */
2022-09-23 20:02:42 -04:00
TArray < FName > GetActiveStateNames ( ) const ;
2022-09-01 09:06:53 -04:00
2022-11-01 15:11:19 -04:00
/** Sends event for the StateTree. */
void SendEvent ( const FGameplayTag Tag , const FConstStructView Payload = FConstStructView ( ) , const FName Origin = FName ( ) ) const ;
2022-09-01 09:06:53 -04:00
2024-04-12 06:04:01 -04:00
/**
* Iterates over all events .
* @ param Function a lambda which takes const FStateTreeSharedEvent & Event , and returns EStateTreeLoopEvents .
*/
2022-09-01 09:06:53 -04:00
template < typename TFunc >
2024-03-11 04:54:44 -04:00
typename TEnableIf < TIsInvocable < TFunc , FStateTreeSharedEvent > : : Value , void > : : Type ForEachEvent ( TFunc & & Function ) const
2022-09-01 09:06:53 -04:00
{
2024-04-12 06:04:01 -04:00
if ( ! EventQueue )
2022-09-01 09:06:53 -04:00
{
2024-04-12 06:04:01 -04:00
return ;
2022-09-01 09:06:53 -04:00
}
2024-04-12 06:04:01 -04:00
EventQueue - > template ForEachEvent ( Function ) ;
2022-09-01 09:06:53 -04:00
}
2024-04-12 06:04:01 -04:00
/**
* Iterates over all events .
* @ param Function a lambda which takes const FStateTreeSharedEvent & Event , and returns EStateTreeLoopEvents .
* Less preferable than FStateTreeSharedEvent version .
*/
2024-03-11 04:54:44 -04:00
template < typename TFunc >
typename TEnableIf < TIsInvocable < TFunc , FStateTreeEvent > : : Value , void > : : Type ForEachEvent ( TFunc & & Function ) const
{
2024-04-12 06:04:01 -04:00
if ( ! EventQueue )
2024-03-11 04:54:44 -04:00
{
2024-04-12 06:04:01 -04:00
return ;
2024-03-11 04:54:44 -04:00
}
2024-04-12 06:04:01 -04:00
EventQueue - > template ForEachEvent ( [ Function ] ( const FStateTreeSharedEvent & Event )
{
return Function ( * Event ) ;
} ) ;
2024-03-11 04:54:44 -04:00
}
2022-09-01 09:06:53 -04:00
/** @return events to process this tick. */
2024-04-12 06:04:01 -04:00
TArrayView < FStateTreeSharedEvent > GetMutableEventsToProcessView ( )
{
return EventQueue ? EventQueue - > GetMutableEventsView ( ) : TArrayView < FStateTreeSharedEvent > ( ) ;
}
2024-03-11 04:54:44 -04:00
/** @return events to process this tick. */
2024-04-12 06:04:01 -04:00
TConstArrayView < FStateTreeSharedEvent > GetEventsToProcessView ( ) const
{
return EventQueue ? EventQueue - > GetMutableEventsView ( ) : TArrayView < FStateTreeSharedEvent > ( ) ;
}
/** Consumes and removes the specified event from the event queue. */
void ConsumeEvent ( const FStateTreeSharedEvent & Event )
{
if ( EventQueue )
{
EventQueue - > ConsumeEvent ( Event ) ;
}
}
2024-03-11 04:54:44 -04:00
UE_DEPRECATED ( 5.5 , " Use GetEventsToProcessView() instead. " )
TConstArrayView < FStateTreeEvent > GetEventsToProcess ( ) const { return { } ; }
2022-09-01 09:06:53 -04:00
2023-01-23 12:48:04 -05:00
/** @return true if there is a pending event with specified tag. */
bool HasEventToProcess ( const FGameplayTag Tag ) const
{
2024-04-12 06:04:01 -04:00
return GetEventsToProcessView ( ) . ContainsByPredicate ( [ Tag ] ( const FStateTreeSharedEvent & Event )
2023-01-23 12:48:04 -05:00
{
2024-03-11 04:54:44 -04:00
check ( Event . IsValid ( ) ) ;
return Event - > Tag . MatchesTag ( Tag ) ;
2023-01-23 12:48:04 -05:00
} ) ;
}
/** @return the currently processed state if applicable. */
FStateTreeStateHandle GetCurrentlyProcessedState ( ) const { return CurrentlyProcessedState ; }
2024-01-30 03:18:31 -05:00
/** @return the currently processed execution frame if applicable. */
const FStateTreeExecutionFrame * GetCurrentlyProcessedFrame ( ) const { return CurrentlyProcessedFrame ; }
/** @return the currently processed execution parent frame if applicable. */
const FStateTreeExecutionFrame * GetCurrentlyProcessedParentFrame ( ) const { return CurrentlyProcessedParentFrame ; }
2022-09-01 09:06:53 -04:00
2022-05-31 04:51:18 -04:00
/** @return Pointer to a State or null if state not found */
const FCompactStateTreeState * GetStateFromHandle ( const FStateTreeStateHandle StateHandle ) const
{
2023-11-22 04:08:33 -05:00
return RootStateTree . GetStateFromHandle ( StateHandle ) ;
2022-05-31 04:51:18 -04:00
}
/** @return Array view to external data descriptors associated with this context. Note: Init() must be called before calling this method. */
2023-12-13 06:34:27 -05:00
UE_DEPRECATED ( 5.4 , " Use CollectStateTreeExternalData delegate instead. " )
2022-05-31 04:51:18 -04:00
TConstArrayView < FStateTreeExternalDataDesc > GetExternalDataDescs ( ) const
{
2023-11-22 04:08:33 -05:00
return RootStateTree . ExternalDataDescs ;
2022-05-31 04:51:18 -04:00
}
/** @return Array view to named external data descriptors associated with this context. Note: Init() must be called before calling this method. */
2022-09-19 19:47:11 -04:00
TConstArrayView < FStateTreeExternalDataDesc > GetContextDataDescs ( ) const
2022-05-31 04:51:18 -04:00
{
2023-11-22 04:08:33 -05:00
return RootStateTree . GetContextDataDescs ( ) ;
2022-05-31 04:51:18 -04:00
}
2023-12-13 06:34:27 -05:00
/** @return Handle to external data of type InStruct, or invalid handle if struct not found. */
UE_DEPRECATED ( 5.4 , " Not supported anymore. " )
2022-05-31 04:51:18 -04:00
FStateTreeExternalDataHandle GetExternalDataHandleByStruct ( const UStruct * InStruct ) const
{
2023-11-22 04:08:33 -05:00
const FStateTreeExternalDataDesc * DataDesc = RootStateTree . ExternalDataDescs . FindByPredicate ( [ InStruct ] ( const FStateTreeExternalDataDesc & Item ) { return Item . Struct = = InStruct ; } ) ;
2022-05-31 04:51:18 -04:00
return DataDesc ! = nullptr ? DataDesc - > Handle : FStateTreeExternalDataHandle : : Invalid ;
}
2023-12-13 06:34:27 -05:00
/** Sets context data view value for specific item. */
void SetContextData ( const FStateTreeExternalDataHandle Handle , FStateTreeDataView DataView )
2022-05-31 04:51:18 -04:00
{
check ( Handle . IsValid ( ) ) ;
2023-11-22 04:08:33 -05:00
check ( Handle . DataHandle . GetSource ( ) = = EStateTreeDataSourceType : : ContextData ) ;
2023-12-13 06:34:27 -05:00
ContextAndExternalDataViews [ Handle . DataHandle . GetIndex ( ) ] = DataView ;
}
/** Sets the context data based on name (name is defined in the schema), returns true if data was found */
bool SetContextDataByName ( const FName Name , FStateTreeDataView DataView ) ;
/** @return True if all context data pointers are set. */
bool AreContextDataViewsValid ( ) const ;
/** @return True if all required external data pointers are set. */
UE_DEPRECATED ( 5.4 , " Please AreContextDataViewsValid(). " )
bool AreExternalDataViewsValid ( ) const
{
return AreContextDataViewsValid ( ) ;
}
/** Sets external data view value for specific item. */
UE_DEPRECATED ( 5.4 , " Use SetContextData() for context data, or set SetExternalDataDelegate() to provide external data. " )
void SetExternalData ( const FStateTreeExternalDataHandle Handle , FStateTreeDataView DataView )
{
SetContextData ( Handle , DataView ) ;
2022-05-31 04:51:18 -04:00
}
/**
* Returns reference to external data based on provided handle . The return type is deduced from the handle ' s template type .
* @ param Handle Valid TStateTreeExternalDataHandle < > handle .
* @ return reference to external data based on handle or null if data is not set .
*/
template < typename T >
typename T : : DataType & GetExternalData ( const T Handle ) const
{
check ( Handle . IsValid ( ) ) ;
2023-12-13 06:34:27 -05:00
check ( Handle . DataHandle . GetSource ( ) = = EStateTreeDataSourceType : : ExternalData ) ;
check ( CurrentlyProcessedFrame ) ;
check ( CurrentlyProcessedFrame - > StateTree - > ExternalDataDescs [ Handle . DataHandle . GetIndex ( ) ] . Requirement ! = EStateTreeExternalDataRequirement : : Optional ) ; // Optionals should query pointer instead.
return ContextAndExternalDataViews [ CurrentlyProcessedFrame - > ExternalDataBaseIndex . Get ( ) + Handle . DataHandle . GetIndex ( ) ] . template GetMutable < typename T : : DataType > ( ) ;
2022-05-31 04:51:18 -04:00
}
/**
* Returns pointer to external data based on provided item handle . The return type is deduced from the handle ' s template type .
* @ param Handle Valid TStateTreeExternalDataHandle < > handle .
* @ return pointer to external data based on handle or null if item is not set or handle is invalid .
*/
template < typename T >
typename T : : DataType * GetExternalDataPtr ( const T Handle ) const
{
2023-11-22 04:08:33 -05:00
if ( Handle . IsValid ( ) )
{
2023-12-13 06:34:27 -05:00
check ( CurrentlyProcessedFrame ) ;
check ( Handle . DataHandle . GetSource ( ) = = EStateTreeDataSourceType : : ExternalData ) ;
return ContextAndExternalDataViews [ CurrentlyProcessedFrame - > ExternalDataBaseIndex . Get ( ) + Handle . DataHandle . GetIndex ( ) ] . template GetMutablePtr < typename T : : DataType > ( ) ;
2023-11-22 04:08:33 -05:00
}
return nullptr ;
2022-05-31 04:51:18 -04:00
}
FStateTreeDataView GetExternalDataView ( const FStateTreeExternalDataHandle Handle )
{
if ( Handle . IsValid ( ) )
{
2023-12-13 06:34:27 -05:00
check ( CurrentlyProcessedFrame ) ;
check ( Handle . DataHandle . GetSource ( ) = = EStateTreeDataSourceType : : ExternalData ) ;
return ContextAndExternalDataViews [ CurrentlyProcessedFrame - > ExternalDataBaseIndex . Get ( ) + Handle . DataHandle . GetIndex ( ) ] ;
2022-05-31 04:51:18 -04:00
}
return FStateTreeDataView ( ) ;
}
2022-06-29 04:52:18 -04:00
/** @returns pointer to the instance data of specified node. */
template < typename T >
T * GetInstanceDataPtr ( const FStateTreeNodeBase & Node ) const
{
2023-11-30 07:03:20 -05:00
check ( CurrentNodeDataHandle = = Node . InstanceDataHandle ) ;
return CurrentNodeInstanceData . template GetMutablePtr < T > ( ) ;
2022-06-29 04:52:18 -04:00
}
/** @returns reference to the instance data of specified node. */
template < typename T >
T & GetInstanceData ( const FStateTreeNodeBase & Node ) const
{
2023-11-30 07:03:20 -05:00
check ( CurrentNodeDataHandle = = Node . InstanceDataHandle ) ;
return CurrentNodeInstanceData . template GetMutable < T > ( ) ;
2022-06-29 04:52:18 -04:00
}
2022-09-29 20:26:53 -04:00
/** @returns reference to the instance data of specified node. Infers the instance data type from the node's FInstanceDataType. */
template < typename T >
typename T : : FInstanceDataType & GetInstanceData ( const T & Node ) const
{
static_assert ( TIsDerivedFrom < T , FStateTreeNodeBase > : : IsDerived , " Expecting Node to derive from FStateTreeNodeBase. " ) ;
2023-11-30 07:03:20 -05:00
check ( CurrentNodeDataHandle = = Node . InstanceDataHandle ) ;
return CurrentNodeInstanceData . template GetMutable < typename T : : FInstanceDataType > ( ) ;
2022-09-29 20:26:53 -04:00
}
2022-11-01 15:11:19 -04:00
/** @returns reference to instance data struct that can be passed to lambdas. See TStateTreeInstanceDataStructRef for usage. */
template < typename T >
TStateTreeInstanceDataStructRef < typename T : : FInstanceDataType > GetInstanceDataStructRef ( const T & Node ) const
{
static_assert ( TIsDerivedFrom < T , FStateTreeNodeBase > : : IsDerived , " Expecting Node to derive from FStateTreeNodeBase. " ) ;
2023-11-22 04:08:33 -05:00
check ( CurrentlyProcessedFrame ) ;
2023-11-30 07:03:20 -05:00
return TStateTreeInstanceDataStructRef < typename T : : FInstanceDataType > ( InstanceData , * CurrentlyProcessedFrame , Node . InstanceDataHandle ) ;
2022-11-01 15:11:19 -04:00
}
2023-01-23 12:48:04 -05:00
/**
* Requests transition to a state .
* If called during during transition processing ( e . g . from FStateTreeTaskBase : : TriggerTransitions ( ) ) the transition
* is attempted to be activate immediately ( it can fail e . g . because of preconditions on a target state ) .
* If called outside the transition handling , the request is buffered and handled at the beginning of next transition processing .
* @ param Request The state to transition to .
*/
void RequestTransition ( const FStateTreeTransitionRequest & Request ) ;
2024-01-30 03:18:31 -05:00
/** @return data view of the specified handle relative to given frame. */
2024-03-11 04:54:44 -04:00
static FStateTreeDataView GetDataViewFromInstanceStorage ( FStateTreeInstanceStorage & InstanceDataStorage , FStateTreeInstanceStorage * CurrentlyProcessedSharedInstanceStorage , const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeDataHandle Handle ) ;
2024-01-30 03:18:31 -05:00
2024-02-29 03:19:31 -05:00
/** Looks for a frame in provided list of frames. */
static const FStateTreeExecutionFrame * FindFrame ( const UStateTree * StateTree , FStateTreeStateHandle RootState , TConstArrayView < FStateTreeExecutionFrame > Frames , const FStateTreeExecutionFrame * & OutParentFrame ) ;
2024-03-11 04:54:44 -04:00
UE_DEPRECATED ( 5.5 , " Use GetDataViewFromInstanceStorage instead. " )
static FStateTreeDataView GetDataView ( FStateTreeInstanceStorage & InstanceDataStorage , FStateTreeInstanceStorage * CurrentlyProcessedSharedInstanceStorage , const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , TConstArrayView < FStateTreeDataView > ContextAndExternalDataViews , const FStateTreeDataHandle Handle )
{
return GetDataViewFromInstanceStorage ( InstanceDataStorage , CurrentlyProcessedSharedInstanceStorage , ParentFrame , CurrentFrame , Handle ) ;
}
2024-03-07 06:53:02 -05:00
2024-06-10 15:59:27 -04:00
/**
* Forces transition to a state from a previously recorded state tree transition result .
* Primarily used for replication purposes so that a client state tree stay in sync with its server counterpart .
* @ param Recorded state transition to run on the state tree .
* @ return The new run status for the state tree .
*/
EStateTreeRunStatus ForceTransition ( const FRecordedStateTreeTransitionResult & Transition ) ;
/** Returns the recorded transitions for this context. */
TConstArrayView < FRecordedStateTreeTransitionResult > GetRecordedTransitions ( ) const { return RecordedTransitions ; }
2024-03-11 04:54:44 -04:00
protected :
/**
* Describes a result of States Selection .
*/
struct FStateSelectionResult
{
/** Max number of execution frames handled during state selection. */
static constexpr int32 MaxExecutionFrames = 8 ;
FStateSelectionResult ( ) = default ;
explicit FStateSelectionResult ( TConstArrayView < FStateTreeExecutionFrame > InFrames )
{
SelectedFrames = InFrames ;
FramesStateSelectionEvents . SetNum ( SelectedFrames . Num ( ) ) ;
}
bool IsFull ( ) const
{
return SelectedFrames . Num ( ) = = MaxExecutionFrames ;
}
void PushFrame ( FStateTreeExecutionFrame Frame )
{
SelectedFrames . Add ( Frame ) ;
FramesStateSelectionEvents . AddDefaulted ( ) ;
}
void PopFrame ( )
{
SelectedFrames . Pop ( ) ;
FramesStateSelectionEvents . Pop ( ) ;
}
bool ContainsFrames ( ) const
{
return ! SelectedFrames . IsEmpty ( ) ;
}
int32 FramesNum ( ) const
{
return SelectedFrames . Num ( ) ;
}
TArrayView < FStateTreeExecutionFrame > GetSelectedFrames ( )
{
return SelectedFrames ;
}
TArrayView < FStateTreeFrameStateSelectionEvents > GetFramesStateSelectionEvents ( )
{
return FramesStateSelectionEvents ;
}
protected :
TArray < FStateTreeExecutionFrame , TFixedAllocator < MaxExecutionFrames > > SelectedFrames ;
TArray < FStateTreeFrameStateSelectionEvents , TFixedAllocator < MaxExecutionFrames > > FramesStateSelectionEvents ;
} ;
2023-11-22 04:08:33 -05:00
2024-05-02 11:47:26 -04:00
# if WITH_STATETREE_TRACE
2023-03-14 13:35:46 -04:00
FStateTreeInstanceDebugId GetInstanceDebugId ( ) const ;
2024-05-02 11:47:26 -04:00
# endif // WITH_STATETREE_TRACE
2023-03-14 13:35:46 -04:00
/** @return Prefix that will be used by STATETREE_LOG and STATETREE_CLOG, Owner name by default. */
2022-05-31 04:51:18 -04:00
virtual FString GetInstanceDescription ( ) const ;
2022-12-02 07:57:31 -05:00
/** Callback when delayed transition is triggered. Contexts that are event based can use this to trigger a future event. */
virtual void BeginDelayedTransition ( const FStateTreeTransitionDelayedState & DelayedState ) { } ;
2022-05-31 04:51:18 -04:00
2023-11-22 04:08:33 -05:00
void UpdateInstanceData ( TConstArrayView < FStateTreeExecutionFrame > CurrentActiveFrames , TArrayView < FStateTreeExecutionFrame > NextActiveFrames ) ;
2022-05-31 04:51:18 -04:00
/**
* Handles logic for entering State . EnterState is called on new active Evaluators and Tasks that are part of the re - planned tree .
* Re - planned tree is from the transition target up to the leaf state . States that are parent to the transition target state
* and still active after the transition will remain intact .
* @ return Run status returned by the tasks .
*/
2023-11-22 04:08:33 -05:00
EStateTreeRunStatus EnterState ( FStateTreeTransitionResult & Transition ) ;
2022-05-31 04:51:18 -04:00
/**
* Handles logic for exiting State . ExitState is called on current active Evaluators and Tasks that are part of the re - planned tree .
* Re - planned tree is from the transition target up to the leaf state . States that are parent to the transition target state
* and still active after the transition will remain intact .
*/
2022-09-23 20:02:42 -04:00
void ExitState ( const FStateTreeTransitionResult & Transition ) ;
2022-05-31 04:51:18 -04:00
/**
* Handles logic for signalling State completed . StateCompleted is called on current active Evaluators and Tasks in reverse order ( from leaf to root ) .
*/
2022-09-23 20:02:42 -04:00
void StateCompleted ( ) ;
2022-05-31 04:51:18 -04:00
/**
2023-01-10 15:44:28 -05:00
* Tick evaluators and global tasks by delta time .
2022-05-31 04:51:18 -04:00
*/
2023-01-10 15:44:28 -05:00
EStateTreeRunStatus TickEvaluatorsAndGlobalTasks ( const float DeltaTime , bool bTickGlobalTasks = true ) ;
2022-05-31 04:51:18 -04:00
2023-01-10 15:44:28 -05:00
/**
* Starts evaluators and global tasks .
2023-06-05 06:33:07 -04:00
* @ return run status returned by the global tasks .
2023-01-10 15:44:28 -05:00
*/
2023-06-05 06:33:07 -04:00
EStateTreeRunStatus StartEvaluatorsAndGlobalTasks ( FStateTreeIndex16 & OutLastInitializedTaskIndex ) ;
2022-05-31 04:51:18 -04:00
2023-01-10 15:44:28 -05:00
/**
* Stops evaluators and global tasks .
*/
2023-06-05 06:33:07 -04:00
void StopEvaluatorsAndGlobalTasks ( const EStateTreeRunStatus CompletionStatus , const FStateTreeIndex16 LastInitializedTaskIndex = FStateTreeIndex16 ( ) ) ;
2022-05-31 04:51:18 -04:00
2024-06-25 02:37:11 -04:00
/**
* Stops evaluators and global tasks of the given frame . Expects nodes data to be already bound .
*/
void CallStopOnEvaluatorsAndGlobalTasks ( const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & Frame , const FStateTreeTransitionResult & Transition , const FStateTreeIndex16 LastInitializedTaskIndex = FStateTreeIndex16 ( ) ) ;
2023-11-30 07:03:20 -05:00
/** Starts temporary instances of global evaluators and tasks for a given frame. */
EStateTreeRunStatus StartTemporaryEvaluatorsAndGlobalTasks ( const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame ) ;
2024-06-25 04:09:43 -04:00
/** Stops temporary global evaluators and tasks for the provided frame. */
void StopTemporaryEvaluatorsAndGlobalTasks ( const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame ) ;
2023-11-30 07:03:20 -05:00
2022-05-31 04:51:18 -04:00
/**
* Ticks tasks of all active states starting from current state by delta time .
* @ return Run status returned by the tasks .
*/
2022-09-23 20:02:42 -04:00
EStateTreeRunStatus TickTasks ( const float DeltaTime ) ;
2022-05-31 04:51:18 -04:00
2024-04-12 06:04:01 -04:00
/** Common functionality shared by the tick methods. */
EStateTreeRunStatus TickPrelude ( ) ;
EStateTreeRunStatus TickPostlude ( ) ;
/** Handles task ticking part of the tick. */
void TickUpdateTasksInternal ( const float DeltaTime ) ;
/** Handles transition triggering part of the tick. */
void TickTriggerTransitionsInternal ( ) ;
2022-05-31 04:51:18 -04:00
/**
* Checks all conditions at given range
* @ return True if all conditions pass .
*/
2023-11-30 07:03:20 -05:00
bool TestAllConditions ( const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const int32 ConditionsOffset , const int32 ConditionsNum ) ;
2022-05-31 04:51:18 -04:00
2024-06-13 22:57:49 -04:00
/**
* Calculate the final score of all considerations at given range
* @ return the final score
*/
2024-08-19 15:41:09 -04:00
float EvaluateUtility ( const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const int32 ConsiderationsOffset , const int32 ConsiderationsNum , const float StateWeight ) ;
2024-06-13 22:57:49 -04:00
2024-06-04 03:56:38 -04:00
/* Evaluate all function at given range. Should be used only on active instances, assumes valid handles and does not consider temporary instances. */
void EvaluatePropertyFunctionsOnActiveInstances ( const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame , FStateTreeIndex16 FuncsBegin , uint16 FuncsNum ) ;
/* Evaluate all function at given range. This version validates the data handles and looks up temporary instances. */
void EvaluatePropertyFunctionsWithValidation ( const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame , FStateTreeIndex16 FuncsBegin , uint16 FuncsNum ) ;
2022-12-02 07:57:31 -05:00
/**
2023-01-23 12:48:04 -05:00
* Requests transition to a specified state with specified priority .
2022-12-02 07:57:31 -05:00
*/
2023-11-22 04:08:33 -05:00
bool RequestTransition (
const FStateTreeExecutionFrame & CurrentFrame ,
const FStateTreeStateHandle NextState ,
const EStateTreeTransitionPriority Priority ,
2024-03-11 04:54:44 -04:00
const FStateTreeSharedEvent * TransitionEvent = nullptr ,
2023-11-22 04:08:33 -05:00
const EStateTreeSelectionFallback Fallback = EStateTreeSelectionFallback : : None ) ;
2023-09-22 09:53:34 -04:00
/**
* Sets up NextTransition based on the provided parameters and the current execution status .
*/
2023-11-22 04:08:33 -05:00
void SetupNextTransition ( const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeStateHandle NextState , const EStateTreeTransitionPriority Priority ) ;
2022-12-02 07:57:31 -05:00
2022-05-31 04:51:18 -04:00
/**
* Triggers transitions based on current run status . CurrentStatus is used to select which transitions events are triggered .
* If CurrentStatus is " Running " , " Conditional " transitions pass , " Completed/Failed " will trigger " OnCompleted/OnSucceeded/OnFailed " transitions .
* Transition target state can point to a selector state . For that reason the result contains both the target state , as well ass
* the actual next state returned by the selector .
* @ return Transition result describing the source state , state transitioned to , and next selected state .
*/
2023-01-23 12:48:04 -05:00
bool TriggerTransitions ( ) ;
2022-05-31 04:51:18 -04:00
/**
* Runs state selection logic starting at the specified state , walking towards the leaf states .
* If a state cannot be selected , false is returned .
* If NextState is a selector state , SelectStateInternal is called recursively ( depth - first ) to all child states ( where NextState will be one of child states ) .
* If NextState is a leaf state , the active states leading from root to the leaf are returned .
2023-11-22 04:08:33 -05:00
* @ param CurrentFrame The frame where the NextState is valid .
2022-05-31 04:51:18 -04:00
* @ param NextState The state which we try to select next .
2024-03-11 04:54:44 -04:00
* @ param OutSelectionResult The result of selection .
* @ param TransitionEvent Event used by transition to trigger the state selection .
2023-10-17 16:15:53 -04:00
* @ param Fallback selection behavior to execute if it fails to select the desired state
2022-05-31 04:51:18 -04:00
* @ return True if succeeded to select new active states .
*/
2023-11-22 04:08:33 -05:00
bool SelectState (
const FStateTreeExecutionFrame & CurrentFrame ,
const FStateTreeStateHandle NextState ,
2024-03-11 04:54:44 -04:00
FStateSelectionResult & OutSelectionResult ,
const FStateTreeSharedEvent * TransitionEvent = nullptr ,
2023-11-22 04:08:33 -05:00
const EStateTreeSelectionFallback Fallback = EStateTreeSelectionFallback : : None ) ;
2022-05-31 04:51:18 -04:00
/**
* Used internally to do the recursive part of the SelectState ( ) .
*/
2023-11-22 04:08:33 -05:00
bool SelectStateInternal (
2023-11-30 07:03:20 -05:00
const FStateTreeExecutionFrame * CurrentParentFrame ,
2023-11-22 04:08:33 -05:00
FStateTreeExecutionFrame & CurrentFrame ,
2023-12-01 06:43:27 -05:00
const FStateTreeExecutionFrame * CurrentFrameInActiveFrames ,
2024-04-05 02:16:32 -04:00
TConstArrayView < FStateTreeStateHandle > PathToNextState ,
2024-03-11 04:54:44 -04:00
FStateSelectionResult & OutSelectionResult ,
const FStateTreeSharedEvent * TransitionEvent = nullptr ) ;
2022-05-31 04:51:18 -04:00
/** @return StateTree execution state from the instance storage. */
2022-09-23 20:02:42 -04:00
FStateTreeExecutionState & GetExecState ( )
2022-05-31 04:51:18 -04:00
{
2024-04-12 06:04:01 -04:00
check ( InstanceDataStorage ) ;
return InstanceDataStorage - > GetMutableExecutionState ( ) ;
2022-05-31 04:51:18 -04:00
}
/** @return const StateTree execution state from the instance storage. */
2022-09-23 20:02:42 -04:00
const FStateTreeExecutionState & GetExecState ( ) const
2022-05-31 04:51:18 -04:00
{
2024-04-12 06:04:01 -04:00
check ( InstanceDataStorage ) ;
return InstanceDataStorage - > GetExecutionState ( ) ;
2022-05-31 04:51:18 -04:00
}
/** @return String describing state status for logging and debug. */
FString GetStateStatusString ( const FStateTreeExecutionState & ExecState ) const ;
/** @return String describing state name for logging and debug. */
2023-11-22 04:08:33 -05:00
FString GetSafeStateName ( const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeStateHandle State ) const ;
2022-05-31 04:51:18 -04:00
/** @return String describing full path of an activate state for logging and debug. */
2023-11-22 04:08:33 -05:00
FString DebugGetStatePath ( TConstArrayView < FStateTreeExecutionFrame > ActiveFrames , const FStateTreeExecutionFrame * CurrentFrame = nullptr , const int32 ActiveStateIndex = INDEX_NONE ) const ;
2022-05-31 04:51:18 -04:00
2022-11-01 15:11:19 -04:00
/** @return String describing all events that are currently being processed for logging and debug. */
FString DebugGetEventsAsString ( ) const ;
2023-11-22 04:08:33 -05:00
/** @return data view of the specified handle relative to given frame. */
2024-03-11 04:54:44 -04:00
FStateTreeDataView GetDataView ( const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeDataHandle Handle ) ;
2023-11-22 04:08:33 -05:00
2024-01-30 03:18:31 -05:00
/** @return true if handle source is valid cified handle relative to given frame. */
2023-11-30 07:03:20 -05:00
bool IsHandleSourceValid ( const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeDataHandle Handle ) const ;
2022-09-23 20:02:42 -04:00
2023-11-30 07:03:20 -05:00
/** @return data view of the specified handle relative to the given frame, or tries to find a matching temporary instance. */
2024-03-11 04:54:44 -04:00
FStateTreeDataView GetDataViewOrTemporary ( const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeDataHandle Handle ) ;
2023-11-30 07:03:20 -05:00
/**
* Adds a temporary instance that can be located using frame and data handle later .
* @ returns view to the newly added instance . If NewInstanceData is Object wrapper , the new object is returned .
*/
FStateTreeDataView AddTemporaryInstance ( const FStateTreeExecutionFrame & Frame , const FStateTreeIndex16 OwnerNodeIndex , const FStateTreeDataHandle DataHandle , FConstStructView NewInstanceData ) ;
/** Copies a batch of properties to the data in TargetView. Should be used only on active instances, assumes valid handles and does not consider temporary instances. */
2024-03-11 04:54:44 -04:00
bool CopyBatchOnActiveInstances ( const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeDataView TargetView , const FStateTreeIndex16 BindingsBatch ) ;
2023-11-30 07:03:20 -05:00
/** Copies a batch of properties to the data in TargetView. This version validates the data handles and looks up temporary instances. */
2024-03-11 04:54:44 -04:00
bool CopyBatchWithValidation ( const FStateTreeExecutionFrame * ParentFrame , const FStateTreeExecutionFrame & CurrentFrame , const FStateTreeDataView TargetView , const FStateTreeIndex16 BindingsBatch ) ;
2023-12-13 06:34:27 -05:00
2023-12-14 03:17:43 -05:00
/**
* Collects external data for all StateTrees in active frames .
* @ returns true if all external data are set successfully . */
2023-12-13 06:34:27 -05:00
bool CollectActiveExternalData ( ) ;
/**
2023-12-14 03:17:43 -05:00
* Collects external data for specific State Tree asset . If the data is already collected , cached index is returned .
2023-12-13 06:34:27 -05:00
* @ returns index in ContextAndExternalDataViews for the first external data .
*/
FStateTreeIndex16 CollectExternalData ( const UStateTree * StateTree ) ;
2024-01-22 05:38:03 -05:00
/**
* Stores copy of provided parameters as State Tree global parameters .
* @ param Parameters parameters to copy
* @ returns true if successfully set the parameters
*/
bool SetGlobalParameters ( const FInstancedPropertyBag & Parameters ) ;
2024-03-11 04:54:44 -04:00
/**
* Captures StateTree events used during the state selection .
*/
void CaptureNewStateEvents ( TConstArrayView < FStateTreeExecutionFrame > PrevFrames , TConstArrayView < FStateTreeExecutionFrame > NewFrames , TArrayView < FStateTreeFrameStateSelectionEvents > FramesStateSelectionEvents ) ;
2023-11-30 07:03:20 -05:00
2022-09-23 20:02:42 -04:00
/** Owner of the instance data. */
UObject & Owner ;
2022-05-31 04:51:18 -04:00
/** The StateTree asset the context is initialized for */
2023-11-22 04:08:33 -05:00
const UStateTree & RootStateTree ;
2022-05-31 04:51:18 -04:00
2022-09-01 09:06:53 -04:00
/** Instance data used during current tick. */
2022-09-23 20:02:42 -04:00
FStateTreeInstanceData & InstanceData ;
2022-09-01 09:06:53 -04:00
2023-11-22 04:08:33 -05:00
/** Data storage of the instance data, cached for less indirections. */
FStateTreeInstanceStorage * InstanceDataStorage = nullptr ;
2022-09-01 09:06:53 -04:00
2024-04-12 06:04:01 -04:00
/** Events queue to use, cached for less indirections. */
TSharedPtr < FStateTreeEventQueue > EventQueue ;
2024-03-28 05:18:19 -04:00
/** Pointer to linked state tree overrides. */
const FStateTreeReferenceOverrides * LinkedStateTreeOverrides = nullptr ;
2023-11-22 04:08:33 -05:00
/** Data view of the context data. */
2023-12-13 06:34:27 -05:00
TArray < FStateTreeDataView , TConcurrentLinearArrayAllocator < FDefaultBlockAllocationTag > > ContextAndExternalDataViews ;
FOnCollectStateTreeExternalData CollectExternalDataDelegate ;
struct FCollectedExternalDataCache
{
const UStateTree * StateTree = nullptr ;
FStateTreeIndex16 BaseIndex ;
} ;
TArray < FCollectedExternalDataCache , TConcurrentLinearArrayAllocator < FDefaultBlockAllocationTag > > CollectedExternalCache ;
bool bActiveExternalDataCollected = false ;
2023-11-22 04:08:33 -05:00
2023-01-23 12:48:04 -05:00
/** Next transition, used by RequestTransition(). */
FStateTreeTransitionResult NextTransition ;
2023-08-04 14:55:23 -04:00
/** Structure describing the origin of the state transition that caused the state change. */
FStateTreeTransitionSource NextTransitionSource ;
2023-06-20 13:49:25 -04:00
2023-11-22 04:08:33 -05:00
/** Current frame we're processing. */
2023-11-30 07:03:20 -05:00
const FStateTreeExecutionFrame * CurrentlyProcessedParentFrame = nullptr ;
2023-11-22 04:08:33 -05:00
const FStateTreeExecutionFrame * CurrentlyProcessedFrame = nullptr ;
/** Pointer to the shared instance data of the current frame we're processing. */
FStateTreeInstanceStorage * CurrentlyProcessedSharedInstanceStorage = nullptr ;
/** Helper struct to track currently processed frame. */
struct FCurrentlyProcessedFrameScope
{
2023-12-13 10:21:13 -05:00
FCurrentlyProcessedFrameScope ( FStateTreeExecutionContext & InContext , const FStateTreeExecutionFrame * CurrentParentFrame , const FStateTreeExecutionFrame & CurrentFrame ) ;
2023-11-22 04:08:33 -05:00
2023-12-13 10:21:13 -05:00
~ FCurrentlyProcessedFrameScope ( ) ;
2023-11-22 04:08:33 -05:00
private :
FStateTreeExecutionContext & Context ;
int32 SavedFrameIndex = 0 ;
FStateTreeInstanceStorage * SavedSharedInstanceDataStorage = nullptr ;
const FStateTreeExecutionFrame * SavedFrame = nullptr ;
2023-11-30 07:03:20 -05:00
const FStateTreeExecutionFrame * SavedParentFrame = nullptr ;
2023-11-22 04:08:33 -05:00
} ;
2023-01-23 12:48:04 -05:00
/** Current state we're processing, or invalid if not applicable. */
FStateTreeStateHandle CurrentlyProcessedState ;
2023-11-22 04:08:33 -05:00
/** Helper struct to track currently processed state. */
struct FCurrentlyProcessedStateScope
{
FCurrentlyProcessedStateScope ( FStateTreeExecutionContext & InContext , const FStateTreeStateHandle State )
: Context ( InContext )
{
SavedState = Context . CurrentlyProcessedState ;
Context . CurrentlyProcessedState = State ;
}
~ FCurrentlyProcessedStateScope ( )
{
Context . CurrentlyProcessedState = SavedState ;
}
private :
FStateTreeExecutionContext & Context ;
FStateTreeStateHandle SavedState = FStateTreeStateHandle : : Invalid ;
} ;
2024-03-11 04:54:44 -04:00
/** Current event we're processing in transition, or invalid if not applicable. */
const FStateTreeEvent * CurrentlyProcessedTransitionEvent = nullptr ;
/** Helper struct to track currently processed transition event. */
struct FCurrentlyProcessedTransitionEventScope
{
FCurrentlyProcessedTransitionEventScope ( FStateTreeExecutionContext & InContext , const FStateTreeEvent * Event )
: Context ( InContext )
{
check ( Context . CurrentlyProcessedTransitionEvent = = nullptr ) ;
Context . CurrentlyProcessedTransitionEvent = Event ;
}
~ FCurrentlyProcessedTransitionEventScope ( )
{
Context . CurrentlyProcessedTransitionEvent = nullptr ;
}
private :
FStateTreeExecutionContext & Context ;
} ;
/** Current frames events we're processing during the state selection, or invalid if not applicable. */
FStateTreeFrameStateSelectionEvents * CurrentlyProcessedStateSelectionEvents = nullptr ;
/** Helper struct to track currently processed state selection events. */
struct FCurrentFrameStateSelectionEventsScope
{
FCurrentFrameStateSelectionEventsScope ( FStateTreeExecutionContext & InContext , FStateTreeFrameStateSelectionEvents & InCurrentlyProcessedStateSelectionEvents )
: Context ( InContext )
{
SavedStateSelectionEvents = Context . CurrentlyProcessedStateSelectionEvents ;
Context . CurrentlyProcessedStateSelectionEvents = & InCurrentlyProcessedStateSelectionEvents ;
}
~ FCurrentFrameStateSelectionEventsScope ( )
{
Context . CurrentlyProcessedStateSelectionEvents = SavedStateSelectionEvents ;
}
private :
FStateTreeExecutionContext & Context ;
FStateTreeFrameStateSelectionEvents * SavedStateSelectionEvents = nullptr ;
} ;
2023-01-23 12:48:04 -05:00
/** True if transitions are allowed to be requested directly instead of buffering. */
bool bAllowDirectTransitions = false ;
/** Helper struct to track when it is allowed to request transitions. */
struct FAllowDirectTransitionsScope
{
FAllowDirectTransitionsScope ( FStateTreeExecutionContext & InContext )
: Context ( InContext )
{
2023-11-30 07:03:20 -05:00
bSavedAllowDirectTransitions = Context . bAllowDirectTransitions ;
2023-01-23 12:48:04 -05:00
Context . bAllowDirectTransitions = true ;
}
~ FAllowDirectTransitionsScope ( )
{
2023-11-30 07:03:20 -05:00
Context . bAllowDirectTransitions = bSavedAllowDirectTransitions ;
2023-01-23 12:48:04 -05:00
}
2023-11-22 04:08:33 -05:00
private :
2023-01-23 12:48:04 -05:00
FStateTreeExecutionContext & Context ;
2023-11-30 07:03:20 -05:00
bool bSavedAllowDirectTransitions = false ;
} ;
/** Currently processed nodes instance data. Ideally we would pass these to the nodes directly, but do not want to change the API currently. */
FStateTreeDataHandle CurrentNodeDataHandle ;
FStateTreeDataView CurrentNodeInstanceData ;
/** Helper struct to set current node data. */
struct FNodeInstanceDataScope
{
FNodeInstanceDataScope ( FStateTreeExecutionContext & InContext , const FStateTreeDataHandle InNodeDataHandle , const FStateTreeDataView InNodeInstanceData )
: Context ( InContext )
{
SavedNodeDataHandle = Context . CurrentNodeDataHandle ;
SavedNodeInstanceData = Context . CurrentNodeInstanceData ;
Context . CurrentNodeDataHandle = InNodeDataHandle ;
Context . CurrentNodeInstanceData = InNodeInstanceData ;
}
~ FNodeInstanceDataScope ( )
{
Context . CurrentNodeDataHandle = SavedNodeDataHandle ;
Context . CurrentNodeInstanceData = SavedNodeInstanceData ;
}
private :
FStateTreeExecutionContext & Context ;
FStateTreeDataHandle SavedNodeDataHandle ;
FStateTreeDataView SavedNodeInstanceData ;
2023-01-23 12:48:04 -05:00
} ;
2024-06-10 15:59:27 -04:00
/** If true, the state tree context will create snapshots of transition events and capture them within RecordedTransitions for later use. */
bool bRecordTransitions = false ;
/** Captured snapshots for transition results that can be used to recreate transitions. This array is only populated if bRecordTransitions is true. */
TArray < FRecordedStateTreeTransitionResult > RecordedTransitions ;
2022-05-31 04:51:18 -04:00
} ;
2024-08-22 11:29:18 -04:00
/**
* The const version of a StateTree Execution Context that prevents using the FStateTreeInstanceData with non - const member function .
*/
struct FConstStateTreeExecutionContextView
{
public :
FConstStateTreeExecutionContextView ( UObject & InOwner , const UStateTree & InStateTree , const FStateTreeInstanceData & InInstanceData )
: ExecutionContext ( InOwner , InStateTree , const_cast < FStateTreeInstanceData & > ( InInstanceData ) )
{ }
operator const FStateTreeExecutionContext & ( )
{
return ExecutionContext ;
}
const FStateTreeExecutionContext & Get ( ) const
{
return ExecutionContext ;
}
private :
FConstStateTreeExecutionContextView ( const FConstStateTreeExecutionContextView & ) = delete ;
FConstStateTreeExecutionContextView & operator = ( const FConstStateTreeExecutionContextView & ) = delete ;
private :
FStateTreeExecutionContext ExecutionContext ;
} ;