Fixed existing spawnable unit tests to work with entity alias changes.
Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com>
This commit is contained in:
@@ -303,18 +303,11 @@ namespace AzFramework
|
|||||||
AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate,
|
AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate,
|
||||||
EntityIdMap& templateToCloneMap, AZ::SerializeContext& serializeContext)
|
EntityIdMap& templateToCloneMap, AZ::SerializeContext& serializeContext)
|
||||||
{
|
{
|
||||||
if (!entityTemplate.GetComponents().empty())
|
// If the same ID gets remapped more than once, preserve the original remapping instead of overwriting it.
|
||||||
{
|
constexpr bool allowDuplicateIds = false;
|
||||||
// If the same ID gets remapped more than once, preserve the original remapping instead of overwriting it.
|
|
||||||
constexpr bool allowDuplicateIds = false;
|
|
||||||
|
|
||||||
return AZ::IdUtils::Remapper<AZ::EntityId, allowDuplicateIds>::CloneObjectAndGenerateNewIdsAndFixRefs(
|
return AZ::IdUtils::Remapper<AZ::EntityId, allowDuplicateIds>::CloneObjectAndGenerateNewIdsAndFixRefs(
|
||||||
&entityTemplate, templateToCloneMap, &serializeContext);
|
&entityTemplate, templateToCloneMap, &serializeContext);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AZ::Entity* SpawnableEntitiesManager::CloneSingleAliasedEntity(
|
AZ::Entity* SpawnableEntitiesManager::CloneSingleAliasedEntity(
|
||||||
@@ -468,9 +461,8 @@ namespace AzFramework
|
|||||||
|
|
||||||
if (aliasIt == aliasEnd || aliasIt->m_sourceIndex != i)
|
if (aliasIt == aliasEnd || aliasIt->m_sourceIndex != i)
|
||||||
{
|
{
|
||||||
AZ::Entity* clone =
|
spawnedEntities.emplace_back(
|
||||||
CloneSingleEntity(*entitiesToSpawn[i], ticket.m_entityIdReferenceMap, *request.m_serializeContext);
|
CloneSingleEntity(*entitiesToSpawn[i], ticket.m_entityIdReferenceMap, *request.m_serializeContext));
|
||||||
spawnedEntities.emplace_back(clone);
|
|
||||||
spawnedEntityIndices.push_back(i);
|
spawnedEntityIndices.push_back(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -483,21 +475,9 @@ namespace AzFramework
|
|||||||
AZ::Entity* clone = CloneSingleAliasedEntity(
|
AZ::Entity* clone = CloneSingleAliasedEntity(
|
||||||
*entitiesToSpawn[i], *aliasIt, ticket.m_entityIdReferenceMap, previousEntity,
|
*entitiesToSpawn[i], *aliasIt, ticket.m_entityIdReferenceMap, previousEntity,
|
||||||
*request.m_serializeContext);
|
*request.m_serializeContext);
|
||||||
// Not all alias operations create a new instance. It's also possible for an empty entity to be left behind,
|
previousEntity = clone;
|
||||||
// in which case it's also filtered out as the entity component framework doesn't handle these gracefully.
|
spawnedEntities.emplace_back(clone);
|
||||||
if (clone)
|
spawnedEntityIndices.push_back(i);
|
||||||
{
|
|
||||||
if (!clone->GetComponents().empty())
|
|
||||||
{
|
|
||||||
previousEntity = clone;
|
|
||||||
spawnedEntities.emplace_back(clone);
|
|
||||||
spawnedEntityIndices.push_back(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete clone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++aliasIt;
|
++aliasIt;
|
||||||
} while (aliasIt != aliasEnd && aliasIt->m_sourceIndex == i);
|
} while (aliasIt != aliasEnd && aliasIt->m_sourceIndex == i);
|
||||||
}
|
}
|
||||||
@@ -519,8 +499,13 @@ namespace AzFramework
|
|||||||
// Add to the game context, now the entities are active
|
// Add to the game context, now the entities are active
|
||||||
for (auto it = newEntitiesBegin; it != newEntitiesEnd; ++it)
|
for (auto it = newEntitiesBegin; it != newEntitiesEnd; ++it)
|
||||||
{
|
{
|
||||||
(*it)->SetSpawnTicketId(request.m_ticketId);
|
AZ::Entity* clone = (*it);
|
||||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
|
// The entity component framework doesn't handle entities without TransformComponent safely.
|
||||||
|
if (!clone->GetComponents().empty())
|
||||||
|
{
|
||||||
|
clone->SetSpawnTicketId(request.m_ticketId);
|
||||||
|
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context.
|
// Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context.
|
||||||
@@ -585,10 +570,8 @@ namespace AzFramework
|
|||||||
RefreshEntityIdMapping(
|
RefreshEntityIdMapping(
|
||||||
entitiesToSpawn[index].get()->GetId(), ticket.m_entityIdReferenceMap, ticket.m_previouslySpawned);
|
entitiesToSpawn[index].get()->GetId(), ticket.m_entityIdReferenceMap, ticket.m_previouslySpawned);
|
||||||
|
|
||||||
AZ::Entity* clone =
|
spawnedEntities.push_back(
|
||||||
CloneSingleEntity(*entitiesToSpawn[index], ticket.m_entityIdReferenceMap, *request.m_serializeContext);
|
CloneSingleEntity(*entitiesToSpawn[index], ticket.m_entityIdReferenceMap, *request.m_serializeContext));
|
||||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
|
||||||
spawnedEntities.push_back(clone);
|
|
||||||
spawnedEntityIndices.push_back(index);
|
spawnedEntityIndices.push_back(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,9 +595,8 @@ namespace AzFramework
|
|||||||
|
|
||||||
if (aliasIt == aliasEnd)
|
if (aliasIt == aliasEnd)
|
||||||
{
|
{
|
||||||
AZ::Entity* clone =
|
spawnedEntities.emplace_back(
|
||||||
CloneSingleEntity(*entitiesToSpawn[index], ticket.m_entityIdReferenceMap, *request.m_serializeContext);
|
CloneSingleEntity(*entitiesToSpawn[index], ticket.m_entityIdReferenceMap, *request.m_serializeContext));
|
||||||
spawnedEntities.emplace_back(clone);
|
|
||||||
spawnedEntityIndices.push_back(index);
|
spawnedEntityIndices.push_back(index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -627,22 +609,10 @@ namespace AzFramework
|
|||||||
AZ::Entity* clone = CloneSingleAliasedEntity(
|
AZ::Entity* clone = CloneSingleAliasedEntity(
|
||||||
*entitiesToSpawn[index], *aliasIt, ticket.m_entityIdReferenceMap, previousEntity,
|
*entitiesToSpawn[index], *aliasIt, ticket.m_entityIdReferenceMap, previousEntity,
|
||||||
*request.m_serializeContext);
|
*request.m_serializeContext);
|
||||||
// Not all alias operations create a new instance. It's also possible for an empty entity to be left
|
previousEntity = clone;
|
||||||
// behind, in which case it's also filtered out as the entity component framework doesn't handle these
|
spawnedEntities.emplace_back(clone);
|
||||||
// gracefully.
|
spawnedEntityIndices.push_back(index);
|
||||||
if (clone)
|
|
||||||
{
|
|
||||||
if (!clone->GetComponents().empty())
|
|
||||||
{
|
|
||||||
previousEntity = clone;
|
|
||||||
spawnedEntities.emplace_back(clone);
|
|
||||||
spawnedEntityIndices.push_back(index);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete clone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++aliasIt;
|
++aliasIt;
|
||||||
} while (aliasIt != aliasEnd && aliasIt->m_sourceIndex == index);
|
} while (aliasIt != aliasEnd && aliasIt->m_sourceIndex == index);
|
||||||
}
|
}
|
||||||
@@ -663,8 +633,13 @@ namespace AzFramework
|
|||||||
// Add to the game context, now the entities are active
|
// Add to the game context, now the entities are active
|
||||||
for (auto it = ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount; it != ticket.m_spawnedEntities.end(); ++it)
|
for (auto it = ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount; it != ticket.m_spawnedEntities.end(); ++it)
|
||||||
{
|
{
|
||||||
(*it)->SetSpawnTicketId(request.m_ticketId);
|
AZ::Entity* clone = (*it);
|
||||||
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
|
// The entity component framework doesn't handle entities without TransformComponent safely.
|
||||||
|
if (!clone->GetComponents().empty())
|
||||||
|
{
|
||||||
|
clone->SetSpawnTicketId(request.m_ticketId);
|
||||||
|
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (request.m_completionCallback)
|
if (request.m_completionCallback)
|
||||||
@@ -965,13 +940,18 @@ namespace AzFramework
|
|||||||
{
|
{
|
||||||
for (AZ::Entity* entity : request.m_ticket->m_spawnedEntities)
|
for (AZ::Entity* entity : request.m_ticket->m_spawnedEntities)
|
||||||
{
|
{
|
||||||
if (entity != nullptr)
|
if (entity != nullptr && !entity->GetComponents().empty())
|
||||||
{
|
{
|
||||||
// Setting it to 0 is needed to avoid the infite loop between GameEntityContext and SpawnableEntitiesManager.
|
// Setting it to 0 is needed to avoid the infinite loop between GameEntityContext and SpawnableEntitiesManager.
|
||||||
entity->SetSpawnTicketId(0);
|
entity->SetSpawnTicketId(0);
|
||||||
GameEntityContextRequestBus::Broadcast(
|
GameEntityContextRequestBus::Broadcast(
|
||||||
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
|
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Entities without components wouldn't have been send to the GameEntityContext.
|
||||||
|
delete entity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete request.m_ticket;
|
delete request.m_ticket;
|
||||||
|
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ namespace UnitTest
|
|||||||
static constexpr size_t NumEntities = 4;
|
static constexpr size_t NumEntities = 4;
|
||||||
FillSpawnable(NumEntities);
|
FillSpawnable(NumEntities);
|
||||||
|
|
||||||
AZStd::vector<size_t> indices = { 0, 2, 3, 1 };
|
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||||
|
|
||||||
size_t spawnedEntitiesCount = 0;
|
size_t spawnedEntitiesCount = 0;
|
||||||
auto callback = [&spawnedEntitiesCount](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
auto callback = [&spawnedEntitiesCount](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||||
@@ -423,7 +423,7 @@ namespace UnitTest
|
|||||||
static constexpr size_t NumEntities = 1;
|
static constexpr size_t NumEntities = 1;
|
||||||
FillSpawnable(NumEntities);
|
FillSpawnable(NumEntities);
|
||||||
|
|
||||||
AZStd::vector<size_t> indices = { 0, 0 };
|
AZStd::vector<uint32_t> indices = { 0, 0 };
|
||||||
|
|
||||||
size_t spawnedEntitiesCount = 0;
|
size_t spawnedEntitiesCount = 0;
|
||||||
auto callback =
|
auto callback =
|
||||||
@@ -444,7 +444,7 @@ namespace UnitTest
|
|||||||
static constexpr size_t NumEntities = 4;
|
static constexpr size_t NumEntities = 4;
|
||||||
FillSpawnable(NumEntities);
|
FillSpawnable(NumEntities);
|
||||||
|
|
||||||
AZStd::vector<size_t> indices = { 0, 2, 3, 1 };
|
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||||
|
|
||||||
size_t spawnedEntitiesCount = 0;
|
size_t spawnedEntitiesCount = 0;
|
||||||
auto callback =
|
auto callback =
|
||||||
@@ -467,7 +467,7 @@ namespace UnitTest
|
|||||||
FillSpawnable(NumEntities);
|
FillSpawnable(NumEntities);
|
||||||
CreateSingleParent();
|
CreateSingleParent();
|
||||||
|
|
||||||
AZStd::vector<size_t> indices = { 0, 1, 2, 3 };
|
AZStd::vector<uint32_t> indices = { 0, 1, 2, 3 };
|
||||||
AZStd::vector<AZ::EntityId> parents;
|
AZStd::vector<AZ::EntityId> parents;
|
||||||
|
|
||||||
auto callback = [&parents](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
auto callback = [&parents](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
|
||||||
@@ -499,7 +499,7 @@ namespace UnitTest
|
|||||||
FillSpawnable(NumEntities);
|
FillSpawnable(NumEntities);
|
||||||
CreateSingleParent();
|
CreateSingleParent();
|
||||||
|
|
||||||
AZStd::vector<size_t> indices = { 0, 1, 2, 3 };
|
AZStd::vector<uint32_t> indices = { 0, 1, 2, 3 };
|
||||||
AZStd::vector<AZ::EntityId> parents;
|
AZStd::vector<AZ::EntityId> parents;
|
||||||
|
|
||||||
auto callback =
|
auto callback =
|
||||||
|
|||||||
Reference in New Issue
Block a user