Added unit tests for spawnable entity aliases.
This also fixes several issues discovered through the unit tests and renames a few functions to be clearer. Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com>
This commit is contained in:
@@ -55,6 +55,40 @@ namespace UnitTest
|
||||
AZ::EntityId m_entityReference;
|
||||
};
|
||||
|
||||
class SourceSpawnableComponent : public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(SourceSpawnableComponent, "{47FF79CE-A95B-420E-8BEB-F1CC58087B87}");
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* reflection)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
|
||||
{
|
||||
serializeContext->Class<SourceSpawnableComponent, AZ::Component>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class TargetSpawnableComponent : public AZ::Component
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(TargetSpawnableComponent, "{B4041561-63A7-4E1E-80F1-78C08D497960}");
|
||||
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
|
||||
static void Reflect(AZ::ReflectContext* reflection)
|
||||
{
|
||||
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
|
||||
{
|
||||
serializeContext->Class<TargetSpawnableComponent, AZ::Component>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SpawnableEntitiesManagerTest : public AllocatorsFixture
|
||||
{
|
||||
public:
|
||||
@@ -66,6 +100,8 @@ namespace UnitTest
|
||||
AZ::ComponentApplication::Descriptor descriptor;
|
||||
m_application->Start(descriptor);
|
||||
m_application->RegisterComponentDescriptor(ComponentWithEntityReference::CreateDescriptor());
|
||||
m_application->RegisterComponentDescriptor(SourceSpawnableComponent::CreateDescriptor());
|
||||
m_application->RegisterComponentDescriptor(TargetSpawnableComponent::CreateDescriptor());
|
||||
|
||||
// Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is
|
||||
// shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash
|
||||
@@ -109,7 +145,50 @@ namespace UnitTest
|
||||
entities.reserve(numElements);
|
||||
for (size_t i=0; i<numElements; ++i)
|
||||
{
|
||||
entities.push_back(AZStd::make_unique<AZ::Entity>());
|
||||
auto entry = AZStd::make_unique<AZ::Entity>();
|
||||
entry->AddComponent(aznew SourceSpawnableComponent());
|
||||
entities.push_back(AZStd::move(entry));
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Data::Asset<AzFramework::Spawnable> CreateTargetSpawnable(size_t numElements)
|
||||
{
|
||||
auto target = aznew AzFramework::Spawnable(
|
||||
AZ::Data::AssetId(AZ::Uuid("{716CD8C3-0BA8-4F32-B579-0EC7C967796F}")), AZ::Data::AssetData::AssetStatus::Ready);
|
||||
|
||||
AzFramework::Spawnable::EntityList& entities = target->GetEntities();
|
||||
entities.reserve(numElements);
|
||||
for (size_t i = 0; i < numElements; ++i)
|
||||
{
|
||||
auto entry = AZStd::make_unique<AZ::Entity>();
|
||||
entry->AddComponent(aznew TargetSpawnableComponent());
|
||||
entities.push_back(AZStd::move(entry));
|
||||
}
|
||||
|
||||
return AZ::Data::Asset<AzFramework::Spawnable>(target, AZ::Data::AssetLoadBehavior::NoLoad);
|
||||
}
|
||||
|
||||
template<size_t AliasCount>
|
||||
void InsertEntityAliases(
|
||||
const AZStd::array<uint32_t, AliasCount>& sourceIds,
|
||||
const AZStd::array<uint32_t, AliasCount>& targetIds,
|
||||
const AZStd::array<AzFramework::Spawnable::EntityAliasType, AliasCount>& aliasTypes,
|
||||
AZ::Data::Asset<AzFramework::Spawnable>* target = nullptr)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
|
||||
for (uint32_t i = 0; i < AliasCount; ++i)
|
||||
{
|
||||
if (target)
|
||||
{
|
||||
visitor.AddAlias(*target, AZ::Crc32(i), sourceIds[i], targetIds[i], aliasTypes[i], false);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::Data::Asset<AzFramework::Spawnable> spawnable(
|
||||
AZ::Data::AssetId(AZ::Uuid("{4CBEC17A-52D6-42D5-9037-F4C05B9CE1D9}"), i), azrtti_typeid<AzFramework::Spawnable>());
|
||||
visitor.AddAlias(AZStd::move(spawnable), AZ::Crc32(i), sourceIds[i], targetIds[i], aliasTypes[i], false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +324,30 @@ namespace UnitTest
|
||||
TestApplication* m_application { nullptr };
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, EntitySpawnTicket_Move_Works)
|
||||
{
|
||||
AzFramework::EntitySpawnTicket ticket1(*m_spawnableAsset);
|
||||
AzFramework::EntitySpawnTicket ticket2(*m_spawnableAsset);
|
||||
|
||||
const AzFramework::EntitySpawnTicket::Id ticket1Id = ticket1.GetId();
|
||||
const AzFramework::EntitySpawnTicket::Id ticket2Id = ticket2.GetId();
|
||||
|
||||
AzFramework::EntitySpawnTicket ticketMoveConstructor(AZStd::move(ticket1));
|
||||
EXPECT_TRUE(ticketMoveConstructor.IsValid());
|
||||
EXPECT_EQ(ticketMoveConstructor.GetId(), ticket1Id);
|
||||
|
||||
AzFramework::EntitySpawnTicket ticketMoveOperator;
|
||||
ticketMoveOperator = AZStd::move(ticket2);
|
||||
EXPECT_TRUE(ticketMoveOperator.IsValid());
|
||||
EXPECT_EQ(ticketMoveOperator.GetId(), ticket2Id);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// SpawnAllEntitities
|
||||
//
|
||||
@@ -366,24 +469,6 @@ namespace UnitTest
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, EntitySpawnTicket_Move_Works)
|
||||
{
|
||||
AzFramework::EntitySpawnTicket ticket1(*m_spawnableAsset);
|
||||
AzFramework::EntitySpawnTicket ticket2(*m_spawnableAsset);
|
||||
|
||||
const AzFramework::EntitySpawnTicket::Id ticket1Id = ticket1.GetId();
|
||||
const AzFramework::EntitySpawnTicket::Id ticket2Id = ticket2.GetId();
|
||||
|
||||
AzFramework::EntitySpawnTicket ticketMoveConstructor(AZStd::move(ticket1));
|
||||
EXPECT_TRUE(ticketMoveConstructor.IsValid());
|
||||
EXPECT_EQ(ticketMoveConstructor.GetId(), ticket1Id);
|
||||
|
||||
AzFramework::EntitySpawnTicket ticketMoveOperator;
|
||||
ticketMoveOperator = AZStd::move(ticket2);
|
||||
EXPECT_TRUE(ticketMoveOperator.IsValid());
|
||||
EXPECT_EQ(ticketMoveOperator.GetId(), ticket2Id);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_DeleteTicketBeforeCall_NoCrash)
|
||||
{
|
||||
{
|
||||
@@ -393,6 +478,178 @@ namespace UnitTest
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithDisabled_NoEntitiesSpawned)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
InsertEntityAliases<NumEntities>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled,
|
||||
Spawnable::EntityAliasType::Disabled });
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
auto callback = [&spawnedEntitiesCount](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnAllEntities(*m_ticket, AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(0, spawnedEntitiesCount);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_SomeAliasesWithDisabled_RegularEntitiesAreSpawned)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 8;
|
||||
FillSpawnable(NumEntities);
|
||||
InsertEntityAliases<2>({ 1, 3 }, { 1, 3 }, { Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled });
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
auto callback = [&spawnedEntitiesCount](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnAllEntities(*m_ticket, AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(6, spawnedEntitiesCount);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithReplace_EntitiesSpawnedFromTarget)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
|
||||
InsertEntityAliases<4>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
|
||||
Spawnable::EntityAliasType::Replace },
|
||||
&target);
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() == nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnAllEntities(*m_ticket, AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(4, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithAdditional_SourceAndTargetComponentsMerged)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
|
||||
InsertEntityAliases<4>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional,
|
||||
Spawnable::EntityAliasType::Additional },
|
||||
&target);
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
bool onSource = true;
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
if (onSource)
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() != nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() == nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() == nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
|
||||
}
|
||||
onSource = !onSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnAllEntities(*m_ticket, AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(8, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
|
||||
InsertEntityAliases<4>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge,
|
||||
Spawnable::EntityAliasType::Merge },
|
||||
&target);
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() != nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnAllEntities(*m_ticket, AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(4, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
}
|
||||
|
||||
//
|
||||
// SpawnEntities
|
||||
@@ -754,6 +1011,190 @@ namespace UnitTest
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithDisabled_NoEntitiesSpawned)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
|
||||
InsertEntityAliases<NumEntities>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled,
|
||||
Spawnable::EntityAliasType::Disabled });
|
||||
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
auto callback = [&spawnedEntitiesCount](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnEntities(*m_ticket, AZStd::move(indices), AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(0, spawnedEntitiesCount);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_SomeAliasesWithDisabled_RegularEntitiesAreSpawned)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
FillSpawnable(8);
|
||||
InsertEntityAliases<3>(
|
||||
{ 1, 3, 6 }, { 1, 3, 6 },
|
||||
{ Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled, Spawnable::EntityAliasType::Disabled });
|
||||
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1, 2, 3, 0, 1, 6, 4, 5, 7, 4, 1, 0, 6 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
auto callback = [&spawnedEntitiesCount](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnEntities(*m_ticket, AZStd::move(indices), AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(9, spawnedEntitiesCount);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithReplace_EntitiesSpawnedFromTarget)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
|
||||
InsertEntityAliases<4>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
|
||||
Spawnable::EntityAliasType::Replace },
|
||||
&target);
|
||||
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() == nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnEntities(*m_ticket, AZStd::move(indices), AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(4, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithAdditional_SourceAndTargetComponentsMerged)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
|
||||
InsertEntityAliases<4>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional,
|
||||
Spawnable::EntityAliasType::Additional },
|
||||
&target);
|
||||
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
bool onSource = true;
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
if (onSource)
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() != nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() == nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() == nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
|
||||
}
|
||||
onSource = !onSource;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnEntities(*m_ticket, AZStd::move(indices), AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(8, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
static constexpr size_t NumEntities = 4;
|
||||
FillSpawnable(NumEntities);
|
||||
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
|
||||
InsertEntityAliases<4>(
|
||||
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
|
||||
{ Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge,
|
||||
Spawnable::EntityAliasType::Merge },
|
||||
&target);
|
||||
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||
{
|
||||
spawnedEntitiesCount += entities.size();
|
||||
for (const AZ::Entity* entity : entities)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() != nullptr;
|
||||
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
allReplaced = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
m_manager->SpawnEntities(*m_ticket, AZStd::move(indices), AZStd::move(optionalArgs));
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(4, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
}
|
||||
|
||||
//
|
||||
// DespawnAllEntities
|
||||
|
||||
Reference in New Issue
Block a user