2021-09-29 02:36:08 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "CoreMinimal.h"
# include "AITestsCommon.h"
# include "Engine/World.h"
2022-08-12 10:47:11 -04:00
# include "MassEntityManager.h"
2021-09-30 14:29:32 -04:00
# include "MassProcessingTypes.h"
2021-09-29 02:36:08 -04:00
# include "MassEntityTestTypes.h"
# include "MassExecutor.h"
2023-01-11 03:01:44 -05:00
# include "MassExecutionContext.h"
2021-09-29 02:36:08 -04:00
2021-10-01 13:37:08 -04:00
# define LOCTEXT_NAMESPACE "MassTest"
2021-09-29 02:36:08 -04:00
2021-10-07 16:57:44 -04:00
namespace FMassQueryTest
2021-09-29 02:36:08 -04:00
{
struct FQueryTest_ProcessorRequirements : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2022-08-12 07:56:27 -04:00
UMassTestProcessor_Floats * Processor = NewObject < UMassTestProcessor_Floats > ( ) ;
2023-01-25 07:13:10 -05:00
TConstArrayView < FMassFragmentRequirementDescription > Requirements = Processor - > EntityQuery . GetFragmentRequirements ( ) ;
2021-09-29 02:36:08 -04:00
AITEST_TRUE ( " Query should have extracted some requirements from the given Processor " , Requirements . Num ( ) > 0 ) ;
AITEST_TRUE ( " There should be exactly one requirement " , Requirements . Num ( ) = = 1 ) ;
AITEST_TRUE ( " The requirement should be of the Float fragment type " , Requirements [ 0 ] . StructType = = FTestFragment_Float : : StaticStruct ( ) ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_ProcessorRequirements , " System.Mass.Query.ProcessorRequiements " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_ExplicitRequirements : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ( { FTestFragment_Float : : StaticStruct ( ) } ) ;
2022-07-20 08:17:28 -04:00
TConstArrayView < FMassFragmentRequirementDescription > Requirements = Query . GetFragmentRequirements ( ) ;
2021-09-29 02:36:08 -04:00
AITEST_TRUE ( " Query should have extracted some requirements from the given Processor " , Requirements . Num ( ) > 0 ) ;
AITEST_TRUE ( " There should be exactly one requirement " , Requirements . Num ( ) = = 1 ) ;
AITEST_TRUE ( " The requirement should be of the Float fragment type " , Requirements [ 0 ] . StructType = = FTestFragment_Float : : StaticStruct ( ) ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_ExplicitRequirements , " System.Mass.Query.ExplicitRequiements " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_FragmentViewBinding : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2022-08-12 07:56:27 -04:00
FMassEntityHandle Entity = EntityManager - > CreateEntity ( FloatsArchetype ) ;
FTestFragment_Float & TestedFragment = EntityManager - > GetFragmentDataChecked < FTestFragment_Float > ( Entity ) ;
2021-10-06 06:45:11 -04:00
AITEST_TRUE ( " Initial value of the fragment should match expectations " , TestedFragment . Value = = 0.f ) ;
2021-09-29 02:36:08 -04:00
2022-08-12 07:56:27 -04:00
UMassTestProcessor_Floats * Processor = NewObject < UMassTestProcessor_Floats > ( ) ;
2023-01-25 07:13:10 -05:00
Processor - > ForEachEntityChunkExecutionFunction = [ ] ( FMassExecutionContext & Context )
{
TArrayView < FTestFragment_Float > Floats = Context . GetMutableFragmentView < FTestFragment_Float > ( ) ;
for ( int32 i = 0 ; i < Context . GetNumEntities ( ) ; + + i )
{
Floats [ i ] . Value = 13.f ;
}
2021-09-29 02:36:08 -04:00
} ;
2022-08-12 07:56:27 -04:00
FMassProcessingContext ProcessingContext ( * EntityManager , /*DeltaSeconds=*/ 0.f ) ;
2021-10-01 13:37:08 -04:00
UE : : Mass : : Executor : : Run ( * Processor , ProcessingContext ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " Fragment value should have changed to the expected value " , TestedFragment . Value , 13.f ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_FragmentViewBinding , " System.Mass.Query.FragmentViewBinding " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_ExecuteSingleArchetype : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
const int32 NumToCreate = 10 ;
2021-09-30 10:09:03 -04:00
TArray < FMassEntityHandle > EntitiesCreated ;
2022-08-12 07:56:27 -04:00
EntityManager - > BatchCreateEntities ( FloatsArchetype , NumToCreate , EntitiesCreated ) ;
2021-09-29 02:36:08 -04:00
int TotalProcessed = 0 ;
2023-01-11 03:01:44 -05:00
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ( { FTestFragment_Float : : StaticStruct ( ) } ) ;
2022-08-12 07:56:27 -04:00
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & TotalProcessed ] ( FMassExecutionContext & Context )
2021-09-29 02:36:08 -04:00
{
2021-10-04 15:50:03 -04:00
TotalProcessed + = Context . GetNumEntities ( ) ;
2021-10-06 06:45:11 -04:00
TArrayView < FTestFragment_Float > Floats = Context . GetMutableFragmentView < FTestFragment_Float > ( ) ;
2021-09-29 02:36:08 -04:00
2021-10-04 15:50:03 -04:00
for ( int32 i = 0 ; i < Context . GetNumEntities ( ) ; + + i )
2021-09-29 02:36:08 -04:00
{
Floats [ i ] . Value = 13.f ;
}
} ) ;
AITEST_TRUE ( " The number of entities processed needs to match expectations " , TotalProcessed = = NumToCreate ) ;
2021-09-30 10:09:03 -04:00
for ( FMassEntityHandle & Entity : EntitiesCreated )
2021-09-29 02:36:08 -04:00
{
2022-08-12 07:56:27 -04:00
const FTestFragment_Float & TestedFragment = EntityManager - > GetFragmentDataChecked < FTestFragment_Float > ( Entity ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " Every fragment value should have changed to the expected value " , TestedFragment . Value , 13.f ) ;
}
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_ExecuteSingleArchetype , " System.Mass.Query.ExecuteSingleArchetype " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_ExecuteMultipleArchetypes : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
const int32 FloatsArchetypeCreated = 7 ;
const int32 IntsArchetypeCreated = 11 ;
const int32 FloatsIntsArchetypeCreated = 13 ;
2021-09-30 10:09:03 -04:00
TArray < FMassEntityHandle > EntitiesCreated ;
2022-08-12 07:56:27 -04:00
EntityManager - > BatchCreateEntities ( IntsArchetype , IntsArchetypeCreated , EntitiesCreated ) ;
2021-09-29 02:36:08 -04:00
// clear to store only the float-related entities
EntitiesCreated . Reset ( ) ;
2022-08-12 07:56:27 -04:00
EntityManager - > BatchCreateEntities ( FloatsArchetype , FloatsArchetypeCreated , EntitiesCreated ) ;
EntityManager - > BatchCreateEntities ( FloatsIntsArchetype , FloatsIntsArchetypeCreated , EntitiesCreated ) ;
2021-09-29 02:36:08 -04:00
int TotalProcessed = 0 ;
2023-01-11 03:01:44 -05:00
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ( { FTestFragment_Float : : StaticStruct ( ) } ) ;
2022-08-12 07:56:27 -04:00
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & TotalProcessed ] ( FMassExecutionContext & Context )
2021-09-29 02:36:08 -04:00
{
2021-10-04 15:50:03 -04:00
TotalProcessed + = Context . GetNumEntities ( ) ;
2021-10-06 06:45:11 -04:00
TArrayView < FTestFragment_Float > Floats = Context . GetMutableFragmentView < FTestFragment_Float > ( ) ;
2021-09-29 02:36:08 -04:00
2021-10-04 15:50:03 -04:00
for ( int32 i = 0 ; i < Context . GetNumEntities ( ) ; + + i )
2021-09-29 02:36:08 -04:00
{
Floats [ i ] . Value = 13.f ;
}
} ) ;
AITEST_TRUE ( " The number of entities processed needs to match expectations " , TotalProcessed = = FloatsIntsArchetypeCreated + FloatsArchetypeCreated ) ;
2021-09-30 10:09:03 -04:00
for ( FMassEntityHandle & Entity : EntitiesCreated )
2021-09-29 02:36:08 -04:00
{
2022-08-12 07:56:27 -04:00
const FTestFragment_Float & TestedFragment = EntityManager - > GetFragmentDataChecked < FTestFragment_Float > ( Entity ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " Every fragment value should have changed to the expected value " , TestedFragment . Value , 13.f ) ;
}
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_ExecuteMultipleArchetypes , " System.Mass.Query.ExecuteMultipleArchetypes " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_ExecuteSparse : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
const int32 NumToCreate = 10 ;
2021-09-30 10:09:03 -04:00
TArray < FMassEntityHandle > AllEntitiesCreated ;
2022-08-12 07:56:27 -04:00
EntityManager - > BatchCreateEntities ( FloatsArchetype , NumToCreate , AllEntitiesCreated ) ;
2021-09-29 02:36:08 -04:00
TArray < int32 > IndicesToProcess = { 1 , 2 , 3 , 6 , 7 } ;
2021-09-30 10:09:03 -04:00
TArray < FMassEntityHandle > EntitiesToProcess ;
TArray < FMassEntityHandle > EntitiesToIgnore ;
2021-09-29 02:36:08 -04:00
for ( int32 i = 0 ; i < AllEntitiesCreated . Num ( ) ; + + i )
{
if ( IndicesToProcess . Find ( i ) ! = INDEX_NONE )
{
EntitiesToProcess . Add ( AllEntitiesCreated [ i ] ) ;
}
else
{
EntitiesToIgnore . Add ( AllEntitiesCreated [ i ] ) ;
}
}
int TotalProcessed = 0 ;
2023-01-11 03:01:44 -05:00
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
2022-07-20 08:17:28 -04:00
FMassEntityQuery TestQuery ;
TestQuery . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadWrite ) ;
TestQuery . ForEachEntityChunk ( FMassArchetypeEntityCollection ( FloatsArchetype , EntitiesToProcess , FMassArchetypeEntityCollection : : NoDuplicates )
2022-08-12 07:56:27 -04:00
, * EntityManager , ExecContext , [ & TotalProcessed ] ( FMassExecutionContext & Context )
2021-09-29 02:36:08 -04:00
{
2021-10-04 15:50:03 -04:00
TotalProcessed + = Context . GetNumEntities ( ) ;
2021-10-06 06:45:11 -04:00
TArrayView < FTestFragment_Float > Floats = Context . GetMutableFragmentView < FTestFragment_Float > ( ) ;
2021-09-29 02:36:08 -04:00
2021-10-04 15:50:03 -04:00
for ( int32 i = 0 ; i < Context . GetNumEntities ( ) ; + + i )
2021-09-29 02:36:08 -04:00
{
Floats [ i ] . Value = 13.f ;
}
} ) ;
AITEST_TRUE ( " The number of entities processed needs to match expectations " , TotalProcessed = = IndicesToProcess . Num ( ) ) ;
2021-09-30 10:09:03 -04:00
for ( FMassEntityHandle & Entity : EntitiesToProcess )
2021-09-29 02:36:08 -04:00
{
2022-08-12 07:56:27 -04:00
const FTestFragment_Float & TestedFragment = EntityManager - > GetFragmentDataChecked < FTestFragment_Float > ( Entity ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " Every fragment value should have changed to the expected value " , TestedFragment . Value , 13.f ) ;
}
2021-09-30 10:09:03 -04:00
for ( FMassEntityHandle & Entity : EntitiesToIgnore )
2021-09-29 02:36:08 -04:00
{
2022-08-12 07:56:27 -04:00
const FTestFragment_Float & TestedFragment = EntityManager - > GetFragmentDataChecked < FTestFragment_Float > ( Entity ) ;
2024-02-02 10:02:15 -05:00
AITEST_EQUAL ( " Untouched entities should retain default fragment value " , TestedFragment . Value , 0.f ) ;
2021-09-29 02:36:08 -04:00
}
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_ExecuteSparse , " System.Mass.Query.ExecuteSparse " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_TagPresent : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
TArray < const UScriptStruct * > Fragments = { FTestFragment_Float : : StaticStruct ( ) , FTestFragment_Tag : : StaticStruct ( ) } ;
2022-08-12 07:56:27 -04:00
const FMassArchetypeHandle FloatsTagArchetype = EntityManager - > CreateArchetype ( Fragments ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadWrite ) ;
Query . AddTagRequirement < FTestFragment_Tag > ( EMassFragmentPresence : : All ) ;
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " There's a single archetype matching the requirements " , Query . GetArchetypes ( ) . Num ( ) , 1 ) ;
AITEST_TRUE ( " The only valid archetype is FloatsTagArchetype " , FloatsTagArchetype = = Query . GetArchetypes ( ) [ 0 ] ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_TagPresent , " System.Mass.Query.TagPresent " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_TagAbsent : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
TArray < const UScriptStruct * > Fragments = { FTestFragment_Float : : StaticStruct ( ) , FTestFragment_Tag : : StaticStruct ( ) } ;
2022-08-12 07:56:27 -04:00
const FMassArchetypeHandle FloatsTagArchetype = EntityManager - > CreateArchetype ( Fragments ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadWrite ) ;
Query . AddTagRequirement < FTestFragment_Tag > ( EMassFragmentPresence : : None ) ;
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " There are exactly two archetypes matching the requirements " , Query . GetArchetypes ( ) . Num ( ) , 2 ) ;
AITEST_TRUE ( " FloatsTagArchetype is not amongst matching archetypes "
, ! ( FloatsTagArchetype = = Query . GetArchetypes ( ) [ 0 ] | | FloatsTagArchetype = = Query . GetArchetypes ( ) [ 1 ] ) ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_TagAbsent , " System.Mass.Query.TagAbsent " ) ;
2021-09-29 02:36:08 -04:00
/** using a fragment as a tag */
struct FQueryTest_FragmentPresent : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
2023-08-08 00:49:56 -04:00
// using EMassFragmentAccess::None to indicate we're interested only in the archetype having the fragment, no binding is required
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : None , EMassFragmentPresence : : Any ) ;
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " There are exactly two archetypes matching the requirements " , Query . GetArchetypes ( ) . Num ( ) , 2 ) ;
AITEST_TRUE ( " FloatsArchetype is not amongst matching archetypes "
, ! ( FloatsArchetype = = Query . GetArchetypes ( ) [ 0 ] | | FloatsArchetype = = Query . GetArchetypes ( ) [ 1 ] ) ) ;
2023-08-08 00:49:56 -04:00
constexpr int32 NumberOfEntitiesToAddA = 5 ;
constexpr int32 NumberOfEntitiesToAddB = 7 ;
TArray < FMassEntityHandle > MatchingEntities ;
EntityManager - > BatchCreateEntities ( IntsArchetype , NumberOfEntitiesToAddA , MatchingEntities ) ;
EntityManager - > BatchCreateEntities ( FloatsIntsArchetype , NumberOfEntitiesToAddB , MatchingEntities ) ;
ensure ( MatchingEntities . Num ( ) = = NumberOfEntitiesToAddA + NumberOfEntitiesToAddB ) ;
int TotalProcessed = 0 ;
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
2024-06-18 07:44:34 -04:00
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & TotalProcessed ] ( FMassExecutionContext & Context ) {
TotalProcessed + = Context . GetNumEntities ( ) ;
} ) ;
2023-08-08 00:49:56 -04:00
AITEST_EQUAL ( " We expect the number of entities processed to match number added to matching archetypes " , MatchingEntities . Num ( ) , TotalProcessed ) ;
2021-09-29 02:36:08 -04:00
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_FragmentPresent , " System.Mass.Query.FragmentPresent " ) ;
2021-09-29 02:36:08 -04:00
2024-07-25 13:36:25 -04:00
struct FQueryTest_OnlyAbsentFragments : FEntityTestBase
2021-09-29 02:36:08 -04:00
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
2024-07-25 13:36:25 -04:00
AITEST_FALSE ( " The empty query is not valid " , Query . CheckValidity ( ) ) ;
2021-09-30 10:09:03 -04:00
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadOnly , EMassFragmentPresence : : None ) ;
2024-07-25 13:36:25 -04:00
AITEST_TRUE ( " Single negative requirement is valid " , Query . CheckValidity ( ) ) ;
2021-09-29 02:36:08 -04:00
2024-07-25 13:18:29 -04:00
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadOnly , EMassFragmentPresence : : None ) ;
2024-07-25 13:36:25 -04:00
Query . AddRequirement < FTestFragment_Bool > ( EMassFragmentAccess : : ReadOnly , EMassFragmentPresence : : None ) ;
AITEST_TRUE ( " Multiple negative requirement is valid " , Query . CheckValidity ( ) ) ;
2024-07-25 13:18:29 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2024-07-25 13:36:25 -04:00
AITEST_EQUAL ( " There's only one default test archetype matching the query " , Query . GetArchetypes ( ) . Num ( ) , 1 ) ;
AITEST_TRUE ( " Only the Empty archetype matches the query " , Query . GetArchetypes ( ) [ 0 ] = = EmptyArchetype ) ;
2024-07-25 13:18:29 -04:00
2024-07-25 13:36:25 -04:00
const FMassArchetypeHandle NewMatchingArchetypeHandle = EntityManager - > CreateArchetype ( { FTestFragment_Large : : StaticStruct ( ) } ) ;
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " The number of matching queries matches expectations " , Query . GetArchetypes ( ) . Num ( ) , 2 ) ;
AITEST_TRUE ( " The new archetype matches the query " , Query . GetArchetypes ( ) [ 1 ] = = NewMatchingArchetypeHandle ) ;
2024-07-25 13:18:29 -04:00
return true ;
}
} ;
2024-07-25 13:36:25 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_OnlyAbsentFragments , " System.Mass.Query.OnlyAbsentFragments " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_AbsentAndPresentFragments : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : None , EMassFragmentPresence : : None ) ;
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadOnly , EMassFragmentPresence : : All ) ;
2021-09-29 02:36:08 -04:00
AITEST_TRUE ( " The query is valid " , Query . CheckValidity ( ) ) ;
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " There is only one archetype matching the query " , Query . GetArchetypes ( ) . Num ( ) , 1 ) ;
AITEST_TRUE ( " FloatsArchetype is the only one matching the query " , FloatsArchetype = = Query . GetArchetypes ( ) [ 0 ] ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_AbsentAndPresentFragments , " System.Mass.Query.AbsentAndPresentFragments " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_SingleOptionalFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : Optional ) ;
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " There are exactly two archetypes matching the requirements " , Query . GetArchetypes ( ) . Num ( ) , 2 ) ;
AITEST_TRUE ( " FloatsArchetype is not amongst matching archetypes "
, ! ( FloatsArchetype = = Query . GetArchetypes ( ) [ 0 ] | | FloatsArchetype = = Query . GetArchetypes ( ) [ 1 ] ) ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_SingleOptionalFragment , " System.Mass.Query.SingleOptionalFragment " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_MultipleOptionalFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : Optional ) ;
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : Optional ) ;
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " All three archetype meet requirements " , Query . GetArchetypes ( ) . Num ( ) , 3 ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_MultipleOptionalFragment , " System.Mass.Query.MultipleOptionalFragment " ) ;
2021-09-29 02:36:08 -04:00
/** This test configures a query to fetch archetypes that have a Float fragment (we have two of these) with an optional
* Int fragment ( of which we ' ll have one among the Float ones ) */
struct FQueryTest_UsingOptionalFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2022-08-12 07:56:27 -04:00
EntityManager - > CreateEntity ( FloatsArchetype ) ;
const FMassEntityHandle EntityWithFloatsInts = EntityManager - > CreateEntity ( FloatsIntsArchetype ) ;
EntityManager - > CreateEntity ( IntsArchetype ) ;
2021-09-29 02:36:08 -04:00
const int32 IntValueSet = 123 ;
int TotalProcessed = 0 ;
int EmptyIntsViewCount = 0 ;
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : Optional ) ;
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : All ) ;
2023-01-11 03:01:44 -05:00
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
2022-08-12 07:56:27 -04:00
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & TotalProcessed , & EmptyIntsViewCount , IntValueSet ] ( FMassExecutionContext & Context ) {
2021-09-29 02:36:08 -04:00
+ + TotalProcessed ;
2021-10-06 06:45:11 -04:00
TArrayView < FTestFragment_Int > Ints = Context . GetMutableFragmentView < FTestFragment_Int > ( ) ;
2021-09-29 02:36:08 -04:00
if ( Ints . Num ( ) = = 0 )
{
+ + EmptyIntsViewCount ;
}
else
{
for ( FTestFragment_Int & IntFragment : Ints )
{
IntFragment . Value = IntValueSet ;
}
}
} ) ;
AITEST_EQUAL ( " Two archetypes total should get processed " , TotalProcessed , 2 ) ;
AITEST_EQUAL ( " Only one of these archetypes should get an empty Ints array view " , EmptyIntsViewCount , 1 ) ;
2022-08-12 07:56:27 -04:00
const FTestFragment_Int & TestFragment = EntityManager - > GetFragmentDataChecked < FTestFragment_Int > ( EntityWithFloatsInts ) ;
2021-09-29 02:36:08 -04:00
AITEST_TRUE ( " The optional fragment \' s value should get modified where present " , TestFragment . Value = = IntValueSet ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_UsingOptionalFragment , " System.Mass.Query.UsingOptionalFragment " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_AnyFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
// From FEntityTestBase:
2022-01-26 03:42:44 -05:00
// FMassArchetypeHandle FloatsArchetype;
// FMassArchetypeHandle IntsArchetype;
// FMassArchetypeHandle FloatsIntsArchetype;
2022-08-12 07:56:27 -04:00
const FMassArchetypeHandle BoolArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Bool : : StaticStruct ( ) } ) ;
const FMassArchetypeHandle BoolFloatArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Bool : : StaticStruct ( ) , FTestFragment_Float : : StaticStruct ( ) } ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : Any ) ;
Query . AddRequirement < FTestFragment_Bool > ( EMassFragmentAccess : : ReadWrite , EMassFragmentPresence : : Any ) ;
2021-09-29 02:36:08 -04:00
// this query should match:
// IntsArchetype, FloatsIntsArchetype, BoolArchetype, BoolFloatArchetype
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " Archetypes containing Int or Bool should meet requirements " , Query . GetArchetypes ( ) . Num ( ) , 4 ) ;
// populate the archetypes so that we can test fragment binding
for ( auto ArchetypeHandle : Query . GetArchetypes ( ) )
{
2022-08-12 07:56:27 -04:00
EntityManager - > CreateEntity ( ArchetypeHandle ) ;
2021-09-29 02:36:08 -04:00
}
2023-01-11 03:01:44 -05:00
FMassExecutionContext TestContext ( * EntityManager . Get ( ) ) ;
2022-08-12 07:56:27 -04:00
Query . ForEachEntityChunk ( * EntityManager , TestContext , [ this ] ( FMassExecutionContext & Context )
2021-09-29 02:36:08 -04:00
{
2021-10-06 06:45:11 -04:00
TArrayView < FTestFragment_Bool > BoolView = Context . GetMutableFragmentView < FTestFragment_Bool > ( ) ;
TArrayView < FTestFragment_Int > IntView = Context . GetMutableFragmentView < FTestFragment_Int > ( ) ;
2021-09-29 02:36:08 -04:00
GetTestRunner ( ) . TestTrue ( " Every matching archetype needs to host Bool or Int fragments " , BoolView . Num ( ) | | IntView . Num ( ) ) ;
} ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_AnyFragment , " System.Mass.Query.AnyFragment " ) ;
2021-09-29 02:36:08 -04:00
struct FQueryTest_AnyTag : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
2022-08-12 07:56:27 -04:00
CA_ASSUME ( EntityManager ) ;
2021-09-29 02:36:08 -04:00
2022-08-12 07:56:27 -04:00
const FMassArchetypeHandle ABArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Int : : StaticStruct ( ) , FTestTag_A : : StaticStruct ( ) , FTestTag_B : : StaticStruct ( ) } ) ;
const FMassArchetypeHandle ACArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Int : : StaticStruct ( ) , FTestTag_A : : StaticStruct ( ) , FTestTag_C : : StaticStruct ( ) } ) ;
const FMassArchetypeHandle BCArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Int : : StaticStruct ( ) , FTestTag_B : : StaticStruct ( ) , FTestTag_C : : StaticStruct ( ) } ) ;
const FMassArchetypeHandle BDArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Int : : StaticStruct ( ) , FTestTag_B : : StaticStruct ( ) , FTestTag_D : : StaticStruct ( ) } ) ;
const FMassArchetypeHandle FloatACArchetype = EntityManager - > CreateArchetype ( { FTestFragment_Float : : StaticStruct ( ) , FTestTag_A : : StaticStruct ( ) , FTestTag_C : : StaticStruct ( ) } ) ;
2021-09-29 02:36:08 -04:00
2021-09-30 10:09:03 -04:00
FMassEntityQuery Query ;
2021-09-29 02:36:08 -04:00
// at least one fragment requirement needs to be present for the query to be valid
2021-09-30 10:09:03 -04:00
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadOnly ) ;
Query . AddTagRequirement < FTestTag_A > ( EMassFragmentPresence : : Any ) ;
Query . AddTagRequirement < FTestTag_C > ( EMassFragmentPresence : : Any ) ;
2021-09-29 02:36:08 -04:00
// this query should match:
// ABArchetype, ACArchetype and ABCrchetype but not BDArchetype nor FEntityTestBase.IntsArchetype
2022-08-12 07:56:27 -04:00
Query . CacheArchetypes ( * EntityManager ) ;
2021-09-29 02:36:08 -04:00
AITEST_EQUAL ( " Only Archetypes tagged with A or C should matched the query " , Query . GetArchetypes ( ) . Num ( ) , 3 ) ;
AITEST_TRUE ( " ABArchetype should be amongst the matched archetypes " , Query . GetArchetypes ( ) . Find ( ABArchetype ) ! = INDEX_NONE ) ;
AITEST_TRUE ( " ACArchetype should be amongst the matched archetypes " , Query . GetArchetypes ( ) . Find ( ACArchetype ) ! = INDEX_NONE ) ;
AITEST_TRUE ( " BCArchetype should be amongst the matched archetypes " , Query . GetArchetypes ( ) . Find ( BCArchetype ) ! = INDEX_NONE ) ;
return true ;
}
} ;
2021-10-01 13:37:08 -04:00
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_AnyTag , " System.Mass.Query.AnyTag " ) ;
2021-09-29 02:36:08 -04:00
2023-01-25 07:13:10 -05:00
struct FQueryTest_AutoRecache : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
CA_ASSUME ( EntityManager ) ;
FMassEntityQuery Query ;
// at least one fragment requirement needs to be present for the query to be valid
Query . AddRequirement < FTestFragment_Int > ( EMassFragmentAccess : : ReadOnly ) ;
int32 EntitiesFound = 0 ;
const FMassExecuteFunction QueryExecFunction = [ & EntitiesFound ] ( FMassExecutionContext & Context )
{
EntitiesFound + = Context . GetNumEntities ( ) ;
} ;
FMassExecutionContext ExecutionContext ( * EntityManager , /*DeltaSeconds=*/ 0.f ) ;
Query . ForEachEntityChunk ( * EntityManager , ExecutionContext , QueryExecFunction ) ;
AITEST_EQUAL ( " No entities have been created so we expect counting to yield 0 " , EntitiesFound , 0 ) ;
constexpr int32 NumberOfEntitiesMatching = 17 ;
TArray < FMassEntityHandle > MatchingEntities ;
EntityManager - > BatchCreateEntities ( IntsArchetype , NumberOfEntitiesMatching , MatchingEntities ) ;
EntitiesFound = 0 ;
Query . ForEachEntityChunk ( * EntityManager , ExecutionContext , QueryExecFunction ) ;
AITEST_EQUAL ( " The number of entities found should match the number of entities created in the matching archetype " , EntitiesFound , MatchingEntities . Num ( ) ) ;
// create more entities, but in an archetype not matching the query
constexpr int32 NumberOfEntitiesNotMatching = 13 ;
TArray < FMassEntityHandle > NotMatchingEntities ;
EntityManager - > BatchCreateEntities ( FloatsArchetype , NumberOfEntitiesNotMatching , NotMatchingEntities ) ;
EntitiesFound = 0 ;
Query . ForEachEntityChunk ( * EntityManager , ExecutionContext , QueryExecFunction ) ;
AITEST_EQUAL ( " The number of entities found should not change with addition of entities not matching the query " , EntitiesFound , MatchingEntities . Num ( ) ) ;
// create some more in another matching archetype
EntityManager - > BatchCreateEntities ( FloatsIntsArchetype , NumberOfEntitiesMatching , MatchingEntities ) ;
EntitiesFound = 0 ;
Query . ForEachEntityChunk ( * EntityManager , ExecutionContext , QueryExecFunction ) ;
AITEST_EQUAL ( " The total number of entities found should include entities from both matching archetypes " , EntitiesFound , MatchingEntities . Num ( ) ) ;
return true ;
}
} ;
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_AutoRecache , " System.Mass.Query.AutoReCaching " ) ;
2024-07-25 13:36:25 -04:00
struct FQueryTest_AllOptional : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
CA_ASSUME ( EntityManager ) ;
FMassEntityQuery Query ;
Query . AddRequirement < FTestFragment_Float > ( EMassFragmentAccess : : None , EMassFragmentPresence : : Optional ) ;
Query . AddTagRequirement < FTestTag_A > ( EMassFragmentPresence : : Optional ) ;
Query . AddChunkRequirement < FTestChunkFragment_Int > ( EMassFragmentAccess : : None , EMassFragmentPresence : : Optional ) ;
Query . AddSharedRequirement < FTestSharedFragment_Int > ( EMassFragmentAccess : : None , EMassFragmentPresence : : Optional ) ;
Query . AddConstSharedRequirement < FTestConstSharedFragment_Int > ( EMassFragmentPresence : : Optional ) ;
Query . CacheArchetypes ( * EntityManager ) ;
int32 ExpectedNumOfArchetypes = 2 ;
// only the FloatsArchetype and FloatsIntsArchetype should match
AITEST_TRUE ( " Initial number of matching archetypes matches expectations " , Query . GetArchetypes ( ) . Num ( ) = = ExpectedNumOfArchetypes ) ;
TArray < FMassEntityHandle > Entities ;
EntityManager - > BatchCreateEntities ( IntsArchetype , 10 , Entities ) ;
int32 CurrentEntityIndex = 0 ;
EntityManager - > AddTagToEntity ( Entities [ CurrentEntityIndex + + ] , FTestTag_A : : StaticStruct ( ) ) ;
+ + ExpectedNumOfArchetypes ;
EntityManager - > AddTagToEntity ( Entities [ CurrentEntityIndex + + ] , FTestTag_B : : StaticStruct ( ) ) ;
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " A: number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . ChunkFragments . Add < FTestChunkFragment_Int > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . ChunkFragments . Add < FTestChunkFragment_Float > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " B: number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
{
FTestSharedFragment_Int FragmentInstance ;
FSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
FMassArchetypeSharedFragmentValues SharedFragmentValues ;
SharedFragmentValues . AddSharedFragment ( SharedFragmentInstance ) ;
FMassArchetypeEntityCollection Collection ( IntsArchetype , MakeArrayView ( & Entities [ CurrentEntityIndex + + ] , 1 ) , FMassArchetypeEntityCollection : : EDuplicatesHandling : : NoDuplicates ) ;
EntityManager - > BatchAddSharedFragmentsForEntities ( MakeArrayView ( & Collection , 1 ) , SharedFragmentValues ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FTestSharedFragment_Float FragmentInstance ;
FSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
FMassArchetypeSharedFragmentValues SharedFragmentValues ;
SharedFragmentValues . AddSharedFragment ( SharedFragmentInstance ) ;
FMassArchetypeEntityCollection Collection ( IntsArchetype , MakeArrayView ( & Entities [ CurrentEntityIndex + + ] , 1 ) , FMassArchetypeEntityCollection : : EDuplicatesHandling : : NoDuplicates ) ;
EntityManager - > BatchAddSharedFragmentsForEntities ( MakeArrayView ( & Collection , 1 ) , SharedFragmentValues ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " C: number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
{
FTestConstSharedFragment_Int FragmentInstance ;
FConstSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
EntityManager - > AddConstSharedFragmentToEntity ( Entities [ CurrentEntityIndex + + ] , SharedFragmentInstance ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FTestConstSharedFragment_Float FragmentInstance ;
FConstSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
EntityManager - > AddConstSharedFragmentToEntity ( Entities [ CurrentEntityIndex + + ] , SharedFragmentInstance ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " D: number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
return true ;
}
} ;
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_AllOptional , " System.Mass.Query.AllOptional " ) ;
struct FQueryTest_JustATag : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
CA_ASSUME ( EntityManager ) ;
FMassEntityQuery Query ;
Query . AddTagRequirement < FTestTag_A > ( EMassFragmentPresence : : All ) ;
Query . CacheArchetypes ( * EntityManager ) ;
int32 ExpectedNumOfArchetypes = 0 ;
// only the FloatsArchetype and FloatsIntsArchetype should match
AITEST_TRUE ( " Initial number of matching archetypes matches expectations " , Query . GetArchetypes ( ) . Num ( ) = = ExpectedNumOfArchetypes ) ;
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . Tags . Add < FTestTag_A > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . Tags . Add < FTestTag_B > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " A: number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . Tags . Add < FTestTag_A > ( ) ;
Descriptor . Tags . Add < FTestTag_C > ( ) ;
Descriptor . Tags . Add < FTestTag_D > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . Tags . Add < FTestTag_B > ( ) ;
Descriptor . Tags . Add < FTestTag_C > ( ) ;
Descriptor . Tags . Add < FTestTag_D > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " B: number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
return true ;
}
} ;
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_JustATag , " System.Mass.Query.JustATag " ) ;
struct FQueryTest_JustAChunkFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
CA_ASSUME ( EntityManager ) ;
FMassArchetypeHandle TargetArchetype ;
FMassEntityQuery Query ;
Query . AddChunkRequirement < FTestChunkFragment_Int > ( EMassFragmentAccess : : ReadOnly , EMassFragmentPresence : : All ) ;
Query . CacheArchetypes ( * EntityManager ) ;
int32 ExpectedNumOfArchetypes = 0 ;
// no matching archetypes at this time
AITEST_TRUE ( " Initial number of matching archetypes matches expectations " , Query . GetArchetypes ( ) . Num ( ) = = ExpectedNumOfArchetypes ) ;
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . ChunkFragments . Add < FTestChunkFragment_Int > ( ) ;
TargetArchetype = EntityManager - > CreateArchetype ( Descriptor ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FMassArchetypeCompositionDescriptor Descriptor ( EntityManager - > GetArchetypeComposition ( IntsArchetype ) ) ;
Descriptor . ChunkFragments . Add < FTestChunkFragment_Float > ( ) ;
EntityManager - > CreateArchetype ( Descriptor ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " Number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
// try to access the chunk fragment
{
EntityManager - > CreateEntity ( TargetArchetype ) ;
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
bool bExecuted = false ;
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & bExecuted ] ( FMassExecutionContext & Context )
{
const FTestChunkFragment_Int & ChunkFragment = Context . GetChunkFragment < FTestChunkFragment_Int > ( ) ;
bExecuted = true ;
} ) ;
AITEST_TRUE ( " The tested query did execute and bounding was successful " , bExecuted ) ;
}
return true ;
}
} ;
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_JustAChunkFragment , " System.Mass.Query.JustAChunkFragment " ) ;
struct FQueryTest_JustASharedFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
CA_ASSUME ( EntityManager ) ;
FMassArchetypeHandle TargetArchetype ;
FMassEntityQuery Query ;
Query . AddSharedRequirement < FTestSharedFragment_Int > ( EMassFragmentAccess : : ReadOnly , EMassFragmentPresence : : All ) ;
Query . CacheArchetypes ( * EntityManager ) ;
int32 ExpectedNumOfArchetypes = 0 ;
// no matching archetypes at this time
AITEST_TRUE ( " Initial number of matching archetypes matches expectations " , Query . GetArchetypes ( ) . Num ( ) = = ExpectedNumOfArchetypes ) ;
TArray < FMassEntityHandle > Entities ;
EntityManager - > BatchCreateEntities ( IntsArchetype , 10 , Entities ) ;
int32 CurrentEntityIndex = 0 ;
{
FTestSharedFragment_Int FragmentInstance ;
FSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
FMassArchetypeSharedFragmentValues SharedFragmentValues ;
SharedFragmentValues . AddSharedFragment ( SharedFragmentInstance ) ;
FMassArchetypeEntityCollection Collection ( IntsArchetype , MakeArrayView ( & Entities [ CurrentEntityIndex + + ] , 1 ) , FMassArchetypeEntityCollection : : EDuplicatesHandling : : NoDuplicates ) ;
EntityManager - > BatchAddSharedFragmentsForEntities ( MakeArrayView ( & Collection , 1 ) , SharedFragmentValues ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FTestSharedFragment_Float FragmentInstance ;
FSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
FMassArchetypeSharedFragmentValues SharedFragmentValues ;
SharedFragmentValues . AddSharedFragment ( SharedFragmentInstance ) ;
FMassArchetypeEntityCollection Collection ( IntsArchetype , MakeArrayView ( & Entities [ CurrentEntityIndex + + ] , 1 ) , FMassArchetypeEntityCollection : : EDuplicatesHandling : : NoDuplicates ) ;
EntityManager - > BatchAddSharedFragmentsForEntities ( MakeArrayView ( & Collection , 1 ) , SharedFragmentValues ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " Number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
// try to access the shared fragment
{
bool bExecuted = false ;
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & bExecuted ] ( FMassExecutionContext & Context )
{
const FTestSharedFragment_Int & SharedFragment = Context . GetSharedFragment < FTestSharedFragment_Int > ( ) ;
bExecuted = true ;
} ) ;
AITEST_TRUE ( " The tested query did execute and bounding was successful " , bExecuted ) ;
}
return true ;
}
} ;
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_JustASharedFragment , " System.Mass.Query.JustASharedFragment " ) ;
struct FQueryTest_JustAConstSharedFragment : FEntityTestBase
{
virtual bool InstantTest ( ) override
{
CA_ASSUME ( EntityManager ) ;
FMassArchetypeHandle TargetArchetype ;
FMassEntityQuery Query ;
Query . AddConstSharedRequirement < FTestConstSharedFragment_Int > ( EMassFragmentPresence : : All ) ;
Query . CacheArchetypes ( * EntityManager ) ;
int32 ExpectedNumOfArchetypes = 0 ;
// no matching archetypes at this time
AITEST_TRUE ( " Initial number of matching archetypes matches expectations " , Query . GetArchetypes ( ) . Num ( ) = = ExpectedNumOfArchetypes ) ;
TArray < FMassEntityHandle > Entities ;
EntityManager - > BatchCreateEntities ( IntsArchetype , 10 , Entities ) ;
int32 CurrentEntityIndex = 0 ;
{
FTestConstSharedFragment_Int FragmentInstance ;
FConstSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
EntityManager - > AddConstSharedFragmentToEntity ( Entities [ CurrentEntityIndex + + ] , SharedFragmentInstance ) ;
+ + ExpectedNumOfArchetypes ;
}
{
FTestConstSharedFragment_Float FragmentInstance ;
FConstSharedStruct SharedFragmentInstance = FSharedStruct : : Make ( FragmentInstance ) ;
EntityManager - > AddConstSharedFragmentToEntity ( Entities [ CurrentEntityIndex + + ] , SharedFragmentInstance ) ;
}
Query . CacheArchetypes ( * EntityManager ) ;
AITEST_EQUAL ( " Number of matching archetypes matches expectations. " , Query . GetArchetypes ( ) . Num ( ) , ExpectedNumOfArchetypes ) ;
// try to access the shared fragment
{
bool bExecuted = false ;
FMassExecutionContext ExecContext ( * EntityManager . Get ( ) ) ;
Query . ForEachEntityChunk ( * EntityManager , ExecContext , [ & bExecuted ] ( FMassExecutionContext & Context )
{
const FTestConstSharedFragment_Int & SharedFragment = Context . GetConstSharedFragment < FTestConstSharedFragment_Int > ( ) ;
bExecuted = true ;
} ) ;
AITEST_TRUE ( " The tested query did execute and bounding was successful " , bExecuted ) ;
}
return true ;
}
} ;
IMPLEMENT_AI_INSTANT_TEST ( FQueryTest_JustAConstSharedFragment , " System.Mass.Query.JustAConstSharedFragment " ) ;
2021-10-07 16:57:44 -04:00
} // FMassQueryTest
2021-09-29 02:36:08 -04:00
# undef LOCTEXT_NAMESPACE