2022-09-28 01:06:15 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2022-08-10 16:03:37 +00:00
# include "StateTreeInstanceData.h"
2023-06-27 09:07:17 -04:00
# include "StateTreeExecutionTypes.h"
2022-12-05 05:01:48 -05:00
# include "Serialization/MemoryReader.h"
# include "Serialization/MemoryWriter.h"
2023-01-23 12:48:04 -05:00
# include "VisualLogger/VisualLogger.h"
2023-02-09 04:20:54 -05:00
# include "StateTree.h"
# include "Serialization/ObjectAndNameAsStringProxyArchive.h"
2024-01-30 03:18:31 -05:00
# include "Serialization/CustomVersion.h"
# include "Serialization/PropertyLocalizationDataGathering.h"
2022-08-10 16:03:37 +00:00
2022-09-28 01:06:15 -04:00
# include UE_INLINE_GENERATED_CPP_BY_NAME(StateTreeInstanceData)
2024-01-30 03:18:31 -05:00
const FGuid FStateTreeInstanceStorageCustomVersion : : GUID ( 0x60C4F0DE , 0x8B264C34 , 0xAA937201 , 0x5DFF09CC ) ;
FCustomVersionRegistration GRegisterStateTreeInstanceStorageCustomVersion ( FStateTreeInstanceStorageCustomVersion : : GUID , FStateTreeInstanceStorageCustomVersion : : LatestVersion , TEXT ( " StateTreeInstanceStorage " ) ) ;
2022-12-05 03:19:45 -05:00
namespace UE : : StateTree
{
/**
* Duplicates object , and tries to covert old BP classes ( REINST_ * ) to their newer version .
*/
UObject * DuplicateNodeInstance ( const UObject & Instance , UObject & InOwner )
{
const UClass * InstanceClass = Instance . GetClass ( ) ;
if ( InstanceClass - > HasAnyClassFlags ( CLASS_NewerVersionExists ) )
{
const UClass * AuthoritativeClass = InstanceClass - > GetAuthoritativeClass ( ) ;
UObject * NewInstance = NewObject < UObject > ( & InOwner , AuthoritativeClass ) ;
// Try to copy the values over using serialization
2023-02-09 04:20:54 -05:00
// FObjectAndNameAsStringProxyArchive is used to store and restore names and objects as memory writer does not support UObject references at all.
2022-12-05 03:19:45 -05:00
TArray < uint8 > Data ;
FMemoryWriter Writer ( Data ) ;
2023-02-09 04:20:54 -05:00
FObjectAndNameAsStringProxyArchive WriterProxy ( Writer , /*bInLoadIfFindFails*/ true ) ;
2022-12-05 03:19:45 -05:00
UObject & NonConstInstance = const_cast < UObject & > ( Instance ) ;
2023-02-09 04:20:54 -05:00
NonConstInstance . Serialize ( WriterProxy ) ;
2022-12-05 03:19:45 -05:00
FMemoryReader Reader ( Data ) ;
2023-02-09 04:20:54 -05:00
FObjectAndNameAsStringProxyArchive ReaderProxy ( Reader , /*bInLoadIfFindFails*/ true ) ;
NewInstance - > Serialize ( ReaderProxy ) ;
const UStateTree * OuterStateTree = Instance . GetTypedOuter < UStateTree > ( ) ;
UE_LOG ( LogStateTree , Display , TEXT ( " FStateTreeInstanceData: Duplicating '%s' with old class '%s' as '%s', potential data loss. Please resave State Tree asset %s. " ) ,
* GetFullNameSafe ( & Instance ) , * GetNameSafe ( InstanceClass ) , * GetNameSafe ( AuthoritativeClass ) , * GetFullNameSafe ( OuterStateTree ) ) ;
2022-12-05 03:19:45 -05:00
return NewInstance ;
}
return DuplicateObject ( & Instance , & InOwner ) ;
}
2024-01-30 03:18:31 -05:00
# if WITH_EDITORONLY_DATA
void GatherForLocalization ( const FString & PathToParent , const UScriptStruct * Struct , const void * StructData , const void * DefaultStructData , FPropertyLocalizationDataGatherer & PropertyLocalizationDataGatherer , const EPropertyLocalizationGathererTextFlags GatherTextFlags )
{
const FStateTreeInstanceData * ThisInstance = static_cast < const FStateTreeInstanceData * > ( StructData ) ;
const FStateTreeInstanceData * DefaultInstance = static_cast < const FStateTreeInstanceData * > ( DefaultStructData ) ;
PropertyLocalizationDataGatherer . GatherLocalizationDataFromStruct ( PathToParent , Struct , StructData , DefaultStructData , GatherTextFlags ) ;
const uint8 * DefaultInstanceMemory = nullptr ;
if ( DefaultInstance )
{
DefaultInstanceMemory = reinterpret_cast < const uint8 * > ( & DefaultInstance - > GetStorage ( ) ) ;
}
const UScriptStruct * StructTypePtr = FStateTreeInstanceStorage : : StaticStruct ( ) ;
PropertyLocalizationDataGatherer . GatherLocalizationDataFromStructWithCallbacks ( PathToParent + TEXT ( " .InstanceStorage " ) , StructTypePtr , & ThisInstance - > GetStorage ( ) , DefaultInstanceMemory , GatherTextFlags ) ;
}
void RegisterInstanceDataForLocalization ( )
{
{ static const FAutoRegisterLocalizationDataGatheringCallback AutomaticRegistrationOfLocalizationGatherer ( TBaseStructure < FStateTreeInstanceData > : : Get ( ) , & GatherForLocalization ) ; }
}
# endif // WITH_EDITORONLY_DATA
2022-12-05 03:19:45 -05:00
} // UE::StateTree
2023-01-23 12:48:04 -05:00
2022-08-10 16:03:37 +00:00
//----------------------------------------------------------------//
2023-01-23 12:48:04 -05:00
// FStateTreeInstanceStorage
//----------------------------------------------------------------//
void FStateTreeInstanceStorage : : AddTransitionRequest ( const UObject * Owner , const FStateTreeTransitionRequest & Request )
{
constexpr int32 MaxPendingTransitionRequests = 32 ;
if ( TransitionRequests . Num ( ) > = MaxPendingTransitionRequests )
{
UE_VLOG_UELOG ( Owner , LogStateTree , Error , TEXT ( " %s: Too many transition requests sent to '%s' (%d pending). Dropping request. " ) , ANSI_TO_TCHAR ( __FUNCTION__ ) , * GetNameSafe ( Owner ) , TransitionRequests . Num ( ) ) ;
return ;
}
TransitionRequests . Add ( Request ) ;
}
2023-01-24 15:07:59 -05:00
void FStateTreeInstanceStorage : : ResetTransitionRequests ( )
{
TransitionRequests . Reset ( ) ;
}
2023-03-09 06:35:16 -05:00
bool FStateTreeInstanceStorage : : AreAllInstancesValid ( ) const
{
for ( FConstStructView Instance : InstanceStructs )
{
if ( ! Instance . IsValid ( ) )
{
return false ;
}
2023-11-22 04:08:33 -05:00
if ( const FStateTreeInstanceObjectWrapper * Wrapper = Instance . GetPtr < const FStateTreeInstanceObjectWrapper > ( ) )
2023-03-09 06:35:16 -05:00
{
2023-11-22 04:08:33 -05:00
if ( ! Wrapper - > InstanceObject )
{
return false ;
}
2023-03-09 06:35:16 -05:00
}
}
return true ;
}
2023-11-30 07:03:20 -05:00
FStructView FStateTreeInstanceStorage : : AddTemporaryInstance ( UObject & InOwner , const FStateTreeExecutionFrame & Frame , const FStateTreeIndex16 OwnerNodeIndex , const FStateTreeDataHandle DataHandle , FConstStructView NewInstanceData )
{
FStateTreeTemporaryInstanceData * TempInstance = TemporaryInstances . FindByPredicate ( [ & Frame , & OwnerNodeIndex , & DataHandle ] ( const FStateTreeTemporaryInstanceData & TempInstance )
{
return TempInstance . StateTree = = Frame . StateTree
& & TempInstance . RootState = = Frame . RootState
& & TempInstance . OwnerNodeIndex = = OwnerNodeIndex
& & TempInstance . DataHandle = = DataHandle ;
} ) ;
if ( TempInstance )
{
if ( TempInstance - > Instance . GetScriptStruct ( ) ! = NewInstanceData . GetScriptStruct ( ) )
{
TempInstance - > Instance = NewInstanceData ;
}
}
else
{
TempInstance = & TemporaryInstances . AddDefaulted_GetRef ( ) ;
check ( TempInstance ) ;
TempInstance - > StateTree = Frame . StateTree ;
TempInstance - > RootState = Frame . RootState ;
TempInstance - > OwnerNodeIndex = OwnerNodeIndex ;
TempInstance - > DataHandle = DataHandle ;
TempInstance - > Instance = NewInstanceData ;
}
if ( FStateTreeInstanceObjectWrapper * Wrapper = TempInstance - > Instance . GetMutablePtr < FStateTreeInstanceObjectWrapper > ( ) )
{
if ( Wrapper - > InstanceObject )
{
Wrapper - > InstanceObject = UE : : StateTree : : DuplicateNodeInstance ( * Wrapper - > InstanceObject , InOwner ) ;
}
}
return TempInstance - > Instance ;
}
FStructView FStateTreeInstanceStorage : : GetMutableTemporaryStruct ( const FStateTreeExecutionFrame & Frame , const FStateTreeDataHandle DataHandle )
{
FStateTreeTemporaryInstanceData * ExistingInstance = TemporaryInstances . FindByPredicate ( [ & Frame , & DataHandle ] ( const FStateTreeTemporaryInstanceData & TempInstance )
{
return TempInstance . StateTree = = Frame . StateTree
& & TempInstance . RootState = = Frame . RootState
& & TempInstance . DataHandle = = DataHandle ;
} ) ;
return ExistingInstance ? FStructView ( ExistingInstance - > Instance ) : FStructView ( ) ;
}
UObject * FStateTreeInstanceStorage : : GetMutableTemporaryObject ( const FStateTreeExecutionFrame & Frame , const FStateTreeDataHandle DataHandle )
{
FStateTreeTemporaryInstanceData * ExistingInstance = TemporaryInstances . FindByPredicate ( [ & Frame , & DataHandle ] ( const FStateTreeTemporaryInstanceData & TempInstance )
{
return TempInstance . StateTree = = Frame . StateTree
& & TempInstance . RootState = = Frame . RootState
& & TempInstance . DataHandle = = DataHandle ;
} ) ;
if ( ExistingInstance )
{
const FStateTreeInstanceObjectWrapper & Wrapper = ExistingInstance - > Instance . Get < FStateTreeInstanceObjectWrapper > ( ) ;
return Wrapper . InstanceObject ;
}
return nullptr ;
}
void FStateTreeInstanceStorage : : ResetTemporaryInstances ( )
{
TemporaryInstances . Reset ( ) ;
}
2023-01-23 12:48:04 -05:00
2024-01-22 05:38:03 -05:00
void FStateTreeInstanceStorage : : SetGlobalParameters ( const FInstancedPropertyBag & Parameters )
{
GlobalParameters = Parameters ;
}
2023-01-23 12:48:04 -05:00
//----------------------------------------------------------------//
// FStateTreeInstanceData
2022-08-10 16:03:37 +00:00
//----------------------------------------------------------------//
2024-01-30 03:18:31 -05:00
FStateTreeInstanceData : : FStateTreeInstanceData ( ) = default ;
FStateTreeInstanceData : : FStateTreeInstanceData ( const FStateTreeInstanceData & Other )
2022-11-01 15:11:19 -04:00
{
2024-01-30 03:18:31 -05:00
InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( * Other . InstanceStorage ) ;
}
FStateTreeInstanceData : : FStateTreeInstanceData ( FStateTreeInstanceData & & Other )
{
InstanceStorage = Other . InstanceStorage ;
Other . InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( ) ;
}
FStateTreeInstanceData & FStateTreeInstanceData : : operator = ( const FStateTreeInstanceData & Other )
{
InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( * Other . InstanceStorage ) ;
return * this ;
}
FStateTreeInstanceData & FStateTreeInstanceData : : operator = ( FStateTreeInstanceData & & Other )
{
InstanceStorage = Other . InstanceStorage ;
Other . InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( ) ;
return * this ;
2022-11-30 07:17:26 -05:00
}
FStateTreeInstanceData : : ~ FStateTreeInstanceData ( )
{
Reset ( ) ;
}
const FStateTreeInstanceStorage & FStateTreeInstanceData : : GetStorage ( ) const
{
2024-01-30 03:18:31 -05:00
return * InstanceStorage ;
}
TWeakPtr < FStateTreeInstanceStorage > FStateTreeInstanceData : : GetWeakMutableStorage ( )
{
return InstanceStorage ;
}
TWeakPtr < const FStateTreeInstanceStorage > FStateTreeInstanceData : : GetWeakStorage ( ) const
{
return InstanceStorage ;
2022-11-30 07:17:26 -05:00
}
FStateTreeInstanceStorage & FStateTreeInstanceData : : GetMutableStorage ( )
{
2024-01-30 03:18:31 -05:00
return * InstanceStorage ;
2022-11-30 07:17:26 -05:00
}
FStateTreeEventQueue & FStateTreeInstanceData : : GetMutableEventQueue ( )
{
return GetMutableStorage ( ) . EventQueue ;
}
const FStateTreeEventQueue & FStateTreeInstanceData : : GetEventQueue ( ) const
{
return GetStorage ( ) . EventQueue ;
2022-11-01 15:11:19 -04:00
}
2023-01-23 12:48:04 -05:00
void FStateTreeInstanceData : : AddTransitionRequest ( const UObject * Owner , const FStateTreeTransitionRequest & Request )
{
GetMutableStorage ( ) . AddTransitionRequest ( Owner , Request ) ;
}
TConstArrayView < FStateTreeTransitionRequest > FStateTreeInstanceData : : GetTransitionRequests ( ) const
{
return GetStorage ( ) . GetTransitionRequests ( ) ;
}
void FStateTreeInstanceData : : ResetTransitionRequests ( )
{
GetMutableStorage ( ) . ResetTransitionRequests ( ) ;
}
2023-03-09 06:35:16 -05:00
bool FStateTreeInstanceData : : AreAllInstancesValid ( ) const
{
return GetStorage ( ) . AreAllInstancesValid ( ) ;
}
2022-08-10 16:03:37 +00:00
int32 FStateTreeInstanceData : : GetEstimatedMemoryUsage ( ) const
{
2022-11-30 07:17:26 -05:00
const FStateTreeInstanceStorage & Storage = GetStorage ( ) ;
2022-08-10 16:03:37 +00:00
int32 Size = sizeof ( FStateTreeInstanceData ) ;
2022-11-30 07:17:26 -05:00
Size + = Storage . InstanceStructs . GetAllocatedMemory ( ) ;
2022-08-10 16:03:37 +00:00
2023-11-22 04:08:33 -05:00
for ( FConstStructView Instance : Storage . InstanceStructs )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( const FStateTreeInstanceObjectWrapper * Wrapper = Instance . GetPtr < const FStateTreeInstanceObjectWrapper > ( ) )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( Wrapper - > InstanceObject )
{
Size + = Wrapper - > InstanceObject - > GetClass ( ) - > GetStructureSize ( ) ;
}
2022-08-10 16:03:37 +00:00
}
}
return Size ;
}
bool FStateTreeInstanceData : : Identical ( const FStateTreeInstanceData * Other , uint32 PortFlags ) const
{
if ( Other = = nullptr )
{
return false ;
}
2022-11-30 07:17:26 -05:00
const FStateTreeInstanceStorage & Storage = GetStorage ( ) ;
const FStateTreeInstanceStorage & OtherStorage = Other - > GetStorage ( ) ;
2024-01-22 05:38:03 -05:00
// Not identical if global parameters don't match.
if ( ! Storage . GlobalParameters . Identical ( & OtherStorage . GlobalParameters , PortFlags ) )
{
return false ;
}
2022-08-10 16:03:37 +00:00
// Not identical if structs are different.
2022-11-30 07:17:26 -05:00
if ( Storage . InstanceStructs . Identical ( & OtherStorage . InstanceStructs , PortFlags ) = = false )
2022-08-10 16:03:37 +00:00
{
return false ;
}
// Check that the instance object contents are identical.
// Copied from object property.
2022-11-30 07:17:26 -05:00
auto AreObjectsIdentical = [ ] ( UObject * A , UObject * B , uint32 PortFlags ) - > bool
2022-08-10 16:03:37 +00:00
{
if ( ( PortFlags & PPF_DuplicateForPIE ) ! = 0 )
{
return false ;
}
if ( A = = B )
{
return true ;
}
// Resolve the object handles and run the deep comparison logic
if ( ( PortFlags & ( PPF_DeepCompareInstances | PPF_DeepComparison ) ) ! = 0 )
{
return FObjectPropertyBase : : StaticIdentical ( A , B , PortFlags ) ;
}
return true ;
} ;
bool bResult = true ;
2023-11-22 04:08:33 -05:00
for ( int32 Index = 0 ; Index < Storage . InstanceStructs . Num ( ) ; Index + + )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
const FStateTreeInstanceObjectWrapper * Wrapper = Storage . InstanceStructs [ Index ] . GetPtr < const FStateTreeInstanceObjectWrapper > ( ) ;
const FStateTreeInstanceObjectWrapper * OtherWrapper = OtherStorage . InstanceStructs [ Index ] . GetPtr < const FStateTreeInstanceObjectWrapper > ( ) ;
if ( Wrapper )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( ! OtherWrapper )
2022-08-10 16:03:37 +00:00
{
bResult = false ;
break ;
}
2023-11-22 04:08:33 -05:00
if ( Wrapper - > InstanceObject & & OtherWrapper - > InstanceObject )
{
if ( ! AreObjectsIdentical ( Wrapper - > InstanceObject , OtherWrapper - > InstanceObject , PortFlags ) )
{
bResult = false ;
break ;
}
}
2022-08-10 16:03:37 +00:00
}
}
return bResult ;
}
2024-01-30 03:18:31 -05:00
void FStateTreeInstanceData : : AddStructReferencedObjects ( FReferenceCollector & Collector )
{
Collector . AddPropertyReferencesWithStructARO ( FStateTreeInstanceStorage : : StaticStruct ( ) , & GetMutableStorage ( ) ) ;
}
bool FStateTreeInstanceData : : Serialize ( FArchive & Ar )
{
Ar . UsingCustomVersion ( FStateTreeInstanceStorageCustomVersion : : GUID ) ;
if ( Ar . IsLoading ( ) )
{
if ( Ar . CustomVer ( FStateTreeInstanceStorageCustomVersion : : GUID ) < FStateTreeInstanceStorageCustomVersion : : AddedCustomSerialization )
{
# if WITH_EDITORONLY_DATA
PRAGMA_DISABLE_DEPRECATION_WARNINGS
StaticStruct ( ) - > SerializeTaggedProperties ( Ar , ( uint8 * ) this , StaticStruct ( ) , nullptr ) ;
if ( InstanceStorage_DEPRECATED . IsValid ( ) )
{
InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( MoveTemp ( InstanceStorage_DEPRECATED . GetMutable ( ) ) ) ;
InstanceStorage_DEPRECATED . Reset ( ) ;
return true ;
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
# endif // WITH_EDITORONLY_DATA
InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( ) ;
return true ;
}
InstanceStorage = MakeShared < FStateTreeInstanceStorage > ( ) ;
}
FStateTreeInstanceStorage : : StaticStruct ( ) - > SerializeItem ( Ar , & InstanceStorage . Get ( ) , nullptr ) ;
return true ;
}
void FStateTreeInstanceData : : GetPreloadDependencies ( TArray < UObject * > & OutDeps )
{
UScriptStruct * ScriptStruct = FStateTreeInstanceStorage : : StaticStruct ( ) ;
OutDeps . Add ( ScriptStruct ) ;
if ( UScriptStruct : : ICppStructOps * CppStructOps = ScriptStruct - > GetCppStructOps ( ) )
{
CppStructOps - > GetPreloadDependencies ( & GetMutableStorage ( ) , OutDeps ) ;
}
for ( TPropertyValueIterator < FStructProperty > It ( ScriptStruct , & GetMutableStorage ( ) ) ; It ; + + It )
{
const UScriptStruct * StructType = It . Key ( ) - > Struct ;
if ( UScriptStruct : : ICppStructOps * CppStructOps = StructType - > GetCppStructOps ( ) )
{
void * StructDataPtr = const_cast < void * > ( It . Value ( ) ) ;
CppStructOps - > GetPreloadDependencies ( StructDataPtr , OutDeps ) ;
}
}
}
2022-08-10 16:03:37 +00:00
void FStateTreeInstanceData : : CopyFrom ( UObject & InOwner , const FStateTreeInstanceData & InOther )
{
if ( & InOther = = this )
{
return ;
}
2022-11-30 07:17:26 -05:00
FStateTreeInstanceStorage & Storage = GetMutableStorage ( ) ;
const FStateTreeInstanceStorage & OtherStorage = InOther . GetStorage ( ) ;
2022-08-10 16:03:37 +00:00
// Copy structs
2022-11-30 07:17:26 -05:00
Storage . InstanceStructs = OtherStorage . InstanceStructs ;
2022-08-10 16:03:37 +00:00
// Copy instance objects.
2023-11-22 04:08:33 -05:00
for ( FStructView Instance : Storage . InstanceStructs )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( FStateTreeInstanceObjectWrapper * Wrapper = Instance . GetPtr < FStateTreeInstanceObjectWrapper > ( ) )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( Wrapper - > InstanceObject )
{
Wrapper - > InstanceObject = UE : : StateTree : : DuplicateNodeInstance ( * Wrapper - > InstanceObject , InOwner ) ;
}
2022-08-10 16:03:37 +00:00
}
}
}
2023-11-22 04:08:33 -05:00
void FStateTreeInstanceData : : Init ( UObject & InOwner , TConstArrayView < FInstancedStruct > InStructs )
2022-08-10 16:03:37 +00:00
{
Reset ( ) ;
2023-11-22 04:08:33 -05:00
Append ( InOwner , InStructs ) ;
2022-08-10 16:03:37 +00:00
}
2023-11-22 04:08:33 -05:00
void FStateTreeInstanceData : : Init ( UObject & InOwner , TConstArrayView < FConstStructView > InStructs )
2022-08-10 16:03:37 +00:00
{
Reset ( ) ;
2023-11-22 04:08:33 -05:00
Append ( InOwner , InStructs ) ;
2022-08-10 16:03:37 +00:00
}
2023-11-22 04:08:33 -05:00
void FStateTreeInstanceData : : Append ( UObject & InOwner , TConstArrayView < FInstancedStruct > InStructs )
2022-08-10 16:03:37 +00:00
{
2022-11-30 07:17:26 -05:00
FStateTreeInstanceStorage & Storage = GetMutableStorage ( ) ;
2023-11-22 04:08:33 -05:00
const int32 StartIndex = Storage . InstanceStructs . Num ( ) ;
2022-11-30 07:17:26 -05:00
Storage . InstanceStructs . Append ( InStructs ) ;
2023-11-22 04:08:33 -05:00
for ( int32 Index = StartIndex ; Index < Storage . InstanceStructs . Num ( ) ; Index + + )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( FStateTreeInstanceObjectWrapper * Wrapper = Storage . InstanceStructs [ Index ] . GetPtr < FStateTreeInstanceObjectWrapper > ( ) )
2022-08-10 16:03:37 +00:00
{
2023-11-22 04:08:33 -05:00
if ( Wrapper - > InstanceObject )
{
Wrapper - > InstanceObject = UE : : StateTree : : DuplicateNodeInstance ( * Wrapper - > InstanceObject , InOwner ) ;
}
2022-08-10 16:03:37 +00:00
}
}
}
2023-11-22 04:08:33 -05:00
void FStateTreeInstanceData : : Append ( UObject & InOwner , TConstArrayView < FConstStructView > InStructs )
2022-08-10 16:03:37 +00:00
{
2022-11-30 07:17:26 -05:00
FStateTreeInstanceStorage & Storage = GetMutableStorage ( ) ;
2023-11-17 11:42:17 -05:00
2023-11-22 04:08:33 -05:00
const int32 StartIndex = Storage . InstanceStructs . Num ( ) ;
2023-11-17 11:42:17 -05:00
Storage . InstanceStructs . Append ( InStructs ) ;
2023-11-22 04:08:33 -05:00
for ( int32 Index = StartIndex ; Index < Storage . InstanceStructs . Num ( ) ; Index + + )
2023-11-17 11:42:17 -05:00
{
2023-11-22 04:08:33 -05:00
if ( FStateTreeInstanceObjectWrapper * Wrapper = Storage . InstanceStructs [ Index ] . GetPtr < FStateTreeInstanceObjectWrapper > ( ) )
2023-11-17 11:42:17 -05:00
{
2023-11-22 04:08:33 -05:00
if ( Wrapper - > InstanceObject )
{
Wrapper - > InstanceObject = UE : : StateTree : : DuplicateNodeInstance ( * Wrapper - > InstanceObject , InOwner ) ;
}
2023-11-17 11:42:17 -05:00
}
}
}
2023-11-30 07:03:20 -05:00
void FStateTreeInstanceData : : Append ( UObject & InOwner , TConstArrayView < FConstStructView > InStructs , TConstArrayView < FInstancedStruct * > InInstancesToMove )
{
check ( InStructs . Num ( ) = = InInstancesToMove . Num ( ) ) ;
FStateTreeInstanceStorage & Storage = GetMutableStorage ( ) ;
const int32 StartIndex = Storage . InstanceStructs . Num ( ) ;
Storage . InstanceStructs . Append ( InStructs ) ;
for ( int32 Index = StartIndex ; Index < Storage . InstanceStructs . Num ( ) ; Index + + )
{
FStructView Struct = Storage . InstanceStructs [ Index ] ;
FInstancedStruct * Source = InInstancesToMove [ Index - StartIndex ] ;
// The source is used to move temporary instance data into instance data. Not all entries may have it.
// If the source is specified, move it to the instance data. We assume that if the source is object wrapper, it is already the instance we want.
if ( Source & & Source - > IsValid ( ) )
{
check ( Struct . GetScriptStruct ( ) = = Source - > GetScriptStruct ( ) ) ;
FMemory : : Memswap ( Struct . GetMemory ( ) , Source - > GetMutableMemory ( ) , Struct . GetScriptStruct ( ) - > GetStructureSize ( ) ) ;
Source - > Reset ( ) ;
}
else if ( FStateTreeInstanceObjectWrapper * Wrapper = Storage . InstanceStructs [ Index ] . GetPtr < FStateTreeInstanceObjectWrapper > ( ) )
{
if ( Wrapper - > InstanceObject )
{
Wrapper - > InstanceObject = UE : : StateTree : : DuplicateNodeInstance ( * Wrapper - > InstanceObject , InOwner ) ;
}
}
}
}
2023-11-22 04:08:33 -05:00
void FStateTreeInstanceData : : ShrinkTo ( const int32 NumStructs )
2023-11-17 11:42:17 -05:00
{
FStateTreeInstanceStorage & Storage = GetMutableStorage ( ) ;
2023-11-22 04:08:33 -05:00
check ( NumStructs < = Storage . InstanceStructs . Num ( ) ) ;
2022-11-30 07:17:26 -05:00
Storage . InstanceStructs . SetNum ( NumStructs ) ;
}
2022-08-10 16:03:37 +00:00
void FStateTreeInstanceData : : Reset ( )
{
2022-11-30 07:17:26 -05:00
FStateTreeInstanceStorage & Storage = GetMutableStorage ( ) ;
Storage . InstanceStructs . Reset ( ) ;
Storage . EventQueue . Reset ( ) ;
2023-11-30 07:03:20 -05:00
Storage . ExecutionState . Reset ( ) ;
Storage . TemporaryInstances . Reset ( ) ;
2024-01-22 05:38:03 -05:00
Storage . GlobalParameters . Reset ( ) ;
2022-08-10 16:03:37 +00:00
}