Updates for the spawnable entity aliases based on provided feedback.

Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com>
monroegm-disable-blank-issue-2
AMZN-koppersr 4 years ago
parent 0decc57dfc
commit 567702931f

@ -32,7 +32,7 @@ namespace AzFramework
// EntityAliasVisitorBase // EntityAliasVisitorBase
// //
bool Spawnable::EntityAliasVisitorBase::IsSet(const EntityAliasList* aliases) const bool Spawnable::EntityAliasVisitorBase::IsValid(const EntityAliasList* aliases) const
{ {
return aliases != nullptr; return aliases != nullptr;
} }
@ -139,7 +139,7 @@ namespace AzFramework
Spawnable::EntityAliasVisitor::~EntityAliasVisitor() Spawnable::EntityAliasVisitor::~EntityAliasVisitor()
{ {
if (IsSet()) if (IsValid())
{ {
Optimize(); Optimize();
@ -170,9 +170,9 @@ namespace AzFramework
return *this; return *this;
} }
bool Spawnable::EntityAliasVisitor::IsSet() const bool Spawnable::EntityAliasVisitor::IsValid() const
{ {
return EntityAliasVisitorBase::IsSet(m_entityAliasList); return EntityAliasVisitorBase::IsValid(m_entityAliasList);
} }
bool Spawnable::EntityAliasVisitor::HasAliases() const bool Spawnable::EntityAliasVisitor::HasAliases() const
@ -413,7 +413,7 @@ namespace AzFramework
Spawnable::EntityAliasConstVisitor::~EntityAliasConstVisitor() Spawnable::EntityAliasConstVisitor::~EntityAliasConstVisitor()
{ {
if (IsSet()) if (IsValid())
{ {
AZ_Assert( AZ_Assert(
m_owner.m_shareState <= ShareState::Read, "Attempting to unlock a read shared spawnable that was not in a read shared mode (%i).", m_owner.m_shareState <= ShareState::Read, "Attempting to unlock a read shared spawnable that was not in a read shared mode (%i).",
@ -422,9 +422,9 @@ namespace AzFramework
} }
} }
bool Spawnable::EntityAliasConstVisitor::IsSet() const bool Spawnable::EntityAliasConstVisitor::IsValid() const
{ {
return EntityAliasVisitorBase::IsSet(m_entityAliasList); return EntityAliasVisitorBase::IsValid(m_entityAliasList);
} }
bool Spawnable::EntityAliasConstVisitor::HasAliases() const bool Spawnable::EntityAliasConstVisitor::HasAliases() const

@ -71,7 +71,7 @@ namespace AzFramework
class EntityAliasVisitorBase class EntityAliasVisitorBase
{ {
protected: protected:
bool IsSet(const EntityAliasList* aliases) const; bool IsValid(const EntityAliasList* aliases) const;
bool HasAliases(const EntityAliasList* aliases) const; bool HasAliases(const EntityAliasList* aliases) const;
bool AreAllSpawnablesReady(const EntityAliasList* aliases) const; bool AreAllSpawnablesReady(const EntityAliasList* aliases) const;
@ -100,7 +100,7 @@ namespace AzFramework
EntityAliasVisitor& operator=(const EntityAliasVisitor& rhs) = delete; EntityAliasVisitor& operator=(const EntityAliasVisitor& rhs) = delete;
//! Checks if the visitor was able to retrieve data. This needs to be checked before calling any other functions. //! Checks if the visitor was able to retrieve data. This needs to be checked before calling any other functions.
bool IsSet() const; bool IsValid() const;
bool HasAliases() const; bool HasAliases() const;
bool AreAllSpawnablesReady() const; bool AreAllSpawnablesReady() const;
@ -153,7 +153,7 @@ namespace AzFramework
~EntityAliasConstVisitor(); ~EntityAliasConstVisitor();
//! Checks if the visitor was able to retrieve data. This needs to be checked before calling any other functions. //! Checks if the visitor was able to retrieve data. This needs to be checked before calling any other functions.
bool IsSet() const; bool IsValid() const;
bool HasAliases() const; bool HasAliases() const;
bool AreAllSpawnablesReady() const; bool AreAllSpawnablesReady() const;
@ -179,7 +179,7 @@ namespace AzFramework
Spawnable(const Spawnable& rhs) = delete; Spawnable(const Spawnable& rhs) = delete;
Spawnable(Spawnable&& other) = delete; Spawnable(Spawnable&& other) = delete;
~Spawnable() override = default; ~Spawnable() override = default;
Spawnable& operator=(const Spawnable& rhs) = delete; Spawnable& operator=(const Spawnable& rhs) = delete;
Spawnable& operator=(Spawnable&& other) = delete; Spawnable& operator=(Spawnable&& other) = delete;

@ -103,7 +103,7 @@ namespace AzFramework
const AZ::Data::AssetFilterCB& assetLoadFilterCB) const AZ::Data::AssetFilterCB& assetLoadFilterCB)
{ {
Spawnable::EntityAliasVisitor aliases = spawnable->TryGetAliases(); Spawnable::EntityAliasVisitor aliases = spawnable->TryGetAliases();
AZ_Assert(aliases.IsSet(), "Newly created Spawnable '%s' was already locked.", asset.GetHint().c_str()); AZ_Assert(aliases.IsValid(), "Newly created Spawnable '%s' was already locked.", asset.GetHint().c_str());
if (aliases.HasAliases()) if (aliases.HasAliases())
{ {
AZ_Assert( AZ_Assert(

@ -300,20 +300,20 @@ namespace AzFramework
} }
} }
AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate, AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityPrototype,
EntityIdMap& templateToCloneMap, AZ::SerializeContext& serializeContext) EntityIdMap& prototypeToCloneMap, AZ::SerializeContext& serializeContext)
{ {
// If the same ID gets remapped more than once, preserve the original remapping instead of overwriting it. // If the same ID gets remapped more than once, preserve the original remapping instead of overwriting it.
constexpr bool allowDuplicateIds = false; constexpr bool allowDuplicateIds = false;
return AZ::IdUtils::Remapper<AZ::EntityId, allowDuplicateIds>::CloneObjectAndGenerateNewIdsAndFixRefs( return AZ::IdUtils::Remapper<AZ::EntityId, allowDuplicateIds>::CloneObjectAndGenerateNewIdsAndFixRefs(
&entityTemplate, templateToCloneMap, &serializeContext); &entityPrototype, prototypeToCloneMap, &serializeContext);
} }
AZ::Entity* SpawnableEntitiesManager::CloneSingleAliasedEntity( AZ::Entity* SpawnableEntitiesManager::CloneSingleAliasedEntity(
const AZ::Entity& entityTemplate, const AZ::Entity& entityPrototype,
const Spawnable::EntityAlias& alias, const Spawnable::EntityAlias& alias,
EntityIdMap& templateToCloneMap, EntityIdMap& prototypeToCloneMap,
AZ::Entity* previouslySpawnedEntity, AZ::Entity* previouslySpawnedEntity,
AZ::SerializeContext& serializeContext) AZ::SerializeContext& serializeContext)
{ {
@ -324,26 +324,27 @@ namespace AzFramework
{ {
case Spawnable::EntityAliasType::Original: case Spawnable::EntityAliasType::Original:
// Behave as the original version. // Behave as the original version.
clone = CloneSingleEntity(entityTemplate, templateToCloneMap, serializeContext); clone = CloneSingleEntity(entityPrototype, prototypeToCloneMap, serializeContext);
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
return clone; return clone;
case Spawnable::EntityAliasType::Disable: case Spawnable::EntityAliasType::Disable:
// Do nothing. // Do nothing.
return nullptr; return nullptr;
case Spawnable::EntityAliasType::Replace: case Spawnable::EntityAliasType::Replace:
clone = CloneSingleEntity(*(alias.m_spawnable->GetEntities()[alias.m_targetIndex]), templateToCloneMap, serializeContext); clone = CloneSingleEntity(*(alias.m_spawnable->GetEntities()[alias.m_targetIndex]), prototypeToCloneMap, serializeContext);
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
return clone; return clone;
case Spawnable::EntityAliasType::Additional: case Spawnable::EntityAliasType::Additional:
// The asset handler will have sorted and inserted a Spawnable::EntityAliasType::Original, so the just // The asset handler will have sorted and inserted a Spawnable::EntityAliasType::Original, so the just
// spawn the additional entity. // spawn the additional entity.
clone = CloneSingleEntity(*(alias.m_spawnable->GetEntities()[alias.m_targetIndex]), templateToCloneMap, serializeContext); clone = CloneSingleEntity(*(alias.m_spawnable->GetEntities()[alias.m_targetIndex]), prototypeToCloneMap, serializeContext);
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
return clone; return clone;
case Spawnable::EntityAliasType::Merge: case Spawnable::EntityAliasType::Merge:
AZ_Assert(previouslySpawnedEntity != nullptr, "Merging components but there's no entity to add to yet."); AZ_Assert(previouslySpawnedEntity != nullptr, "Merging components but there's no entity to add to yet.");
AppendComponents( AppendComponents(
*previouslySpawnedEntity, alias.m_spawnable->GetEntities()[alias.m_targetIndex]->GetComponents(), templateToCloneMap, serializeContext); *previouslySpawnedEntity, alias.m_spawnable->GetEntities()[alias.m_targetIndex]->GetComponents(), prototypeToCloneMap,
serializeContext);
return nullptr; return nullptr;
default: default:
AZ_Assert(false, "Unsupported spawnable entity alias type: %i", alias.m_aliasType); AZ_Assert(false, "Unsupported spawnable entity alias type: %i", alias.m_aliasType);
@ -353,17 +354,17 @@ namespace AzFramework
void SpawnableEntitiesManager::AppendComponents( void SpawnableEntitiesManager::AppendComponents(
AZ::Entity& target, AZ::Entity& target,
const AZ::Entity::ComponentArrayType& componentTemplates, const AZ::Entity::ComponentArrayType& componentPrototypes,
EntityIdMap& templateToCloneMap, EntityIdMap& prototypeToCloneMap,
AZ::SerializeContext& serializeContext) AZ::SerializeContext& serializeContext)
{ {
// Only components are added and entities are looked up so no duplicate entity ids should be encountered. // Only components are added and entities are looked up so no duplicate entity ids should be encountered.
constexpr bool allowDuplicateIds = false; constexpr bool allowDuplicateIds = false;
for (const AZ::Component* component : componentTemplates) for (const AZ::Component* component : componentPrototypes)
{ {
AZ::Component* clone = AZ::IdUtils::Remapper<AZ::EntityId, allowDuplicateIds>::CloneObjectAndGenerateNewIdsAndFixRefs( AZ::Component* clone = AZ::IdUtils::Remapper<AZ::EntityId, allowDuplicateIds>::CloneObjectAndGenerateNewIdsAndFixRefs(
component, templateToCloneMap, &serializeContext); component, prototypeToCloneMap, &serializeContext);
AZ_Assert(clone, "Unable to clone component for entity '%s' (%zu).", target.GetName().c_str(), target.GetId()); AZ_Assert(clone, "Unable to clone component for entity '%s' (%zu).", target.GetName().c_str(), target.GetId());
[[maybe_unused]] bool result = target.AddComponent(clone); [[maybe_unused]] bool result = target.AddComponent(clone);
AZ_Assert(result, "Unable to add cloned component to entity '%s' (%zu).", target.GetName().c_str(), target.GetId()); AZ_Assert(result, "Unable to add cloned component to entity '%s' (%zu).", target.GetName().c_str(), target.GetId());
@ -409,7 +410,7 @@ namespace AzFramework
if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId) if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId)
{ {
if (Spawnable::EntityAliasConstVisitor aliases = ticket.m_spawnable->TryGetAliasesConst(); if (Spawnable::EntityAliasConstVisitor aliases = ticket.m_spawnable->TryGetAliasesConst();
aliases.IsSet() && aliases.AreAllSpawnablesReady()) aliases.IsValid() && aliases.AreAllSpawnablesReady())
{ {
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities; AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities;
AZStd::vector<uint32_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices; AZStd::vector<uint32_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
@ -417,7 +418,7 @@ namespace AzFramework
// Keep track how many entities there were in the array initially // Keep track how many entities there were in the array initially
size_t spawnedEntitiesInitialCount = spawnedEntities.size(); size_t spawnedEntitiesInitialCount = spawnedEntities.size();
// These are 'template' entities we'll be cloning from // These are 'prototype' entities we'll be cloning from
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities(); const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
uint32_t entitiesToSpawnSize = aznumeric_caster(entitiesToSpawn.size()); uint32_t entitiesToSpawnSize = aznumeric_caster(entitiesToSpawn.size());
@ -527,7 +528,7 @@ namespace AzFramework
if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId) if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId)
{ {
if (Spawnable::EntityAliasConstVisitor aliases = ticket.m_spawnable->TryGetAliasesConst(); if (Spawnable::EntityAliasConstVisitor aliases = ticket.m_spawnable->TryGetAliasesConst();
aliases.IsSet() && aliases.AreAllSpawnablesReady()) aliases.IsValid() && aliases.AreAllSpawnablesReady())
{ {
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities; AZStd::vector<AZ::Entity*>& spawnedEntities = ticket.m_spawnedEntities;
AZStd::vector<uint32_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices; AZStd::vector<uint32_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
@ -538,13 +539,13 @@ namespace AzFramework
// Keep track of how many entities there were in the array initially // Keep track of how many entities there were in the array initially
size_t spawnedEntitiesInitialCount = spawnedEntities.size(); size_t spawnedEntitiesInitialCount = spawnedEntities.size();
// These are 'template' entities we'll be cloning from // These are 'prototype' entities we'll be cloning from
const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities(); const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities();
size_t entitiesToSpawnSize = request.m_entityIndices.size(); size_t entitiesToSpawnSize = request.m_entityIndices.size();
if (ticket.m_entityIdReferenceMap.empty() || !request.m_referencePreviouslySpawnedEntities) if (ticket.m_entityIdReferenceMap.empty() || !request.m_referencePreviouslySpawnedEntities)
{ {
// This map keeps track of ids from template (spawnable) to clone (instance) allowing patch ups of fields referring // This map keeps track of ids from prototype (spawnable) to clone (instance) allowing patch ups of fields referring
// to entityIds outside of a given entity. // to entityIds outside of a given entity.
// We pre-generate the full set of entity id to new entity id mappings, so that during the clone operation below, // We pre-generate the full set of entity id to new entity id mappings, so that during the clone operation below,
// any entity references that point to a not-yet-cloned entity will still get their ids remapped correctly. // any entity references that point to a not-yet-cloned entity will still get their ids remapped correctly.
@ -754,7 +755,7 @@ namespace AzFramework
// Pre-generate the full set of entity id to new entity id mappings, so that during the clone operation below, // Pre-generate the full set of entity id to new entity id mappings, so that during the clone operation below,
// any entity references that point to a not-yet-cloned entity will still get their ids remapped correctly. // any entity references that point to a not-yet-cloned entity will still get their ids remapped correctly.
// This map is intentionally cleared out and regenerated here to ensure that we're starting fresh with mappings that // This map is intentionally cleared out and regenerated here to ensure that we're starting fresh with mappings that
// match the new set of template entities getting spawned. // match the new set of prototype entities getting spawned.
InitializeEntityIdMappings(entities, ticket.m_entityIdReferenceMap, ticket.m_previouslySpawned); InitializeEntityIdMappings(entities, ticket.m_entityIdReferenceMap, ticket.m_previouslySpawned);
if (ticket.m_loadAll) if (ticket.m_loadAll)
@ -819,7 +820,7 @@ namespace AzFramework
Ticket& ticket = *request.m_ticket; Ticket& ticket = *request.m_ticket;
if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId) if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId)
{ {
if (Spawnable::EntityAliasVisitor aliases = ticket.m_spawnable->TryGetAliases(); aliases.IsSet()) if (Spawnable::EntityAliasVisitor aliases = ticket.m_spawnable->TryGetAliases(); aliases.IsValid())
{ {
for (EntityAliasTypeChange& replacement : request.m_entityAliases) for (EntityAliasTypeChange& replacement : request.m_entityAliases)
{ {
@ -921,7 +922,7 @@ namespace AzFramework
if (request.m_checkAliasSpawnables) if (request.m_checkAliasSpawnables)
{ {
if (Spawnable::EntityAliasConstVisitor visitor = ticket.m_spawnable->TryGetAliasesConst(); if (Spawnable::EntityAliasConstVisitor visitor = ticket.m_spawnable->TryGetAliasesConst();
!visitor.IsSet() || !visitor.AreAllSpawnablesReady()) !visitor.IsValid() || !visitor.AreAllSpawnablesReady())
{ {
return CommandResult::Requeue; return CommandResult::Requeue;
} }

@ -96,9 +96,9 @@ namespace AzFramework
AZ_CLASS_ALLOCATOR(Ticket, AZ::ThreadPoolAllocator, 0); AZ_CLASS_ALLOCATOR(Ticket, AZ::ThreadPoolAllocator, 0);
static constexpr uint32_t Processing = AZStd::numeric_limits<uint32_t>::max(); static constexpr uint32_t Processing = AZStd::numeric_limits<uint32_t>::max();
//! Map of template entity ids to their associated instance ids. //! Map of prototype entity ids to their associated instance ids.
//! Tickets can be used to spawn the same template entities multiple times, in any order, across multiple calls. //! Tickets can be used to spawn the same prototype entities multiple times, in any order, across multiple calls.
//! Since template entities can reference other entities, this map is used to fix up those references across calls //! Since prototype entities can reference other entities, this map is used to fix up those references across calls
//! using the following policy: //! using the following policy:
//! - Entities referencing an entity that hasn't been spawned yet will get a reference to the id that *will* be used //! - Entities referencing an entity that hasn't been spawned yet will get a reference to the id that *will* be used
//! the first time that entity will be spawned. The reference will be invalid until that entity is spawned, but //! the first time that entity will be spawned. The reference will be invalid until that entity is spawned, but
@ -243,17 +243,17 @@ namespace AzFramework
CommandQueueStatus ProcessQueue(Queue& queue); CommandQueueStatus ProcessQueue(Queue& queue);
AZ::Entity* CloneSingleEntity( AZ::Entity* CloneSingleEntity(
const AZ::Entity& entityTemplate, EntityIdMap& templateToCloneMap, AZ::SerializeContext& serializeContext); const AZ::Entity& entityPrototype, EntityIdMap& prototypeToCloneMap, AZ::SerializeContext& serializeContext);
AZ::Entity* CloneSingleAliasedEntity( AZ::Entity* CloneSingleAliasedEntity(
const AZ::Entity& entityTemplate, const AZ::Entity& entityPrototype,
const Spawnable::EntityAlias& alias, const Spawnable::EntityAlias& alias,
EntityIdMap& templateToCloneMap, EntityIdMap& prototypeToCloneMap,
AZ::Entity* previouslySpawnedEntity, AZ::Entity* previouslySpawnedEntity,
AZ::SerializeContext& serializeContext); AZ::SerializeContext& serializeContext);
void AppendComponents( void AppendComponents(
AZ::Entity& target, AZ::Entity& target,
const AZ::Entity::ComponentArrayType& componentTemplates, const AZ::Entity::ComponentArrayType& componentPrototypes,
EntityIdMap& templateToCloneMap, EntityIdMap& prototypeToCloneMap,
AZ::SerializeContext& serializeContext); AZ::SerializeContext& serializeContext);
CommandResult ProcessRequest(SpawnAllEntitiesCommand& request); CommandResult ProcessRequest(SpawnAllEntitiesCommand& request);

@ -192,6 +192,79 @@ namespace UnitTest
} }
} }
static bool AreAllEntitiesReplaced(AzFramework::SpawnableConstEntityContainerView entities)
{
for (const AZ::Entity* entity : entities)
{
if (entity)
{
if (entity->FindComponent<SourceSpawnableComponent>() != nullptr ||
entity->FindComponent<TargetSpawnableComponent>() == nullptr)
{
return false;
}
}
else
{
return false;
}
}
return true;
}
static bool IsEveryOtherEntityAReplacement(AzFramework::SpawnableConstEntityContainerView entities)
{
bool onAlternative = true;
for (const AZ::Entity* entity : entities)
{
if (entity)
{
if (onAlternative)
{
if (entity->FindComponent<SourceSpawnableComponent>() == nullptr ||
entity->FindComponent<TargetSpawnableComponent>() != nullptr)
{
return false;
}
}
else
{
if (entity->FindComponent<SourceSpawnableComponent>() != nullptr ||
entity->FindComponent<TargetSpawnableComponent>() == nullptr)
{
return false;
}
}
onAlternative = !onAlternative;
}
else
{
return false;
}
}
return true;
}
static bool AreAllMerged(AzFramework::SpawnableConstEntityContainerView entities)
{
for (const AZ::Entity* entity : entities)
{
if (entity)
{
if (entity->FindComponent<SourceSpawnableComponent>() == nullptr ||
entity->FindComponent<TargetSpawnableComponent>() == nullptr)
{
return false;
}
}
else
{
return false;
}
}
return true;
}
void CreateRecursiveHierarchy() void CreateRecursiveHierarchy()
{ {
AzFramework::Spawnable::EntityList& entities = m_spawnable->GetEntities(); AzFramework::Spawnable::EntityList& entities = m_spawnable->GetEntities();
@ -539,18 +612,7 @@ namespace UnitTest
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{ {
spawnedEntitiesCount += entities.size(); spawnedEntitiesCount += entities.size();
for (const AZ::Entity* entity : entities) allReplaced = AreAllEntitiesReplaced(entities);
{
if (entity)
{
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() == nullptr;
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
}
else
{
allReplaced = false;
}
}
}; };
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs; AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback); optionalArgs.m_completionCallback = AZStd::move(callback);
@ -574,33 +636,12 @@ namespace UnitTest
&target); &target);
size_t spawnedEntitiesCount = 0; size_t spawnedEntitiesCount = 0;
bool allReplaced = true; bool allAdded = true;
auto callback = [&spawnedEntitiesCount, &allReplaced]( auto callback = [&spawnedEntitiesCount, &allAdded](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{ {
spawnedEntitiesCount += entities.size(); spawnedEntitiesCount += entities.size();
bool onSource = true; allAdded = IsEveryOtherEntityAReplacement(entities);
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; AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback); optionalArgs.m_completionCallback = AZStd::move(callback);
@ -608,7 +649,7 @@ namespace UnitTest
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular); m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
EXPECT_EQ(8, spawnedEntitiesCount); EXPECT_EQ(8, spawnedEntitiesCount);
EXPECT_TRUE(allReplaced); EXPECT_TRUE(allAdded);
} }
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged) TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
@ -624,23 +665,12 @@ namespace UnitTest
&target); &target);
size_t spawnedEntitiesCount = 0; size_t spawnedEntitiesCount = 0;
bool allReplaced = true; bool allMerged = true;
auto callback = [&spawnedEntitiesCount, &allReplaced]( auto callback = [&spawnedEntitiesCount, &allMerged](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{ {
spawnedEntitiesCount += entities.size(); spawnedEntitiesCount += entities.size();
for (const AZ::Entity* entity : entities) allMerged = AreAllMerged(entities);
{
if (entity)
{
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() != nullptr;
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
}
else
{
allReplaced = false;
}
}
}; };
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs; AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback); optionalArgs.m_completionCallback = AZStd::move(callback);
@ -648,7 +678,7 @@ namespace UnitTest
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular); m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
EXPECT_EQ(4, spawnedEntitiesCount); EXPECT_EQ(4, spawnedEntitiesCount);
EXPECT_TRUE(allReplaced); EXPECT_TRUE(allMerged);
} }
// //
@ -1080,18 +1110,7 @@ namespace UnitTest
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{ {
spawnedEntitiesCount += entities.size(); spawnedEntitiesCount += entities.size();
for (const AZ::Entity* entity : entities) allReplaced = AreAllEntitiesReplaced(entities);
{
if (entity)
{
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() == nullptr;
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
}
else
{
allReplaced = false;
}
}
}; };
AzFramework::SpawnEntitiesOptionalArgs optionalArgs; AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback); optionalArgs.m_completionCallback = AZStd::move(callback);
@ -1117,33 +1136,13 @@ namespace UnitTest
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 }; AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
size_t spawnedEntitiesCount = 0; size_t spawnedEntitiesCount = 0;
bool allReplaced = true; bool allAdded = true;
auto callback = [&spawnedEntitiesCount, &allReplaced]( auto callback =
[&spawnedEntitiesCount, &allAdded](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{ {
spawnedEntitiesCount += entities.size(); spawnedEntitiesCount += entities.size();
bool onSource = true; allAdded = IsEveryOtherEntityAReplacement(entities);
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; AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback); optionalArgs.m_completionCallback = AZStd::move(callback);
@ -1151,7 +1150,7 @@ namespace UnitTest
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular); m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
EXPECT_EQ(8, spawnedEntitiesCount); EXPECT_EQ(8, spawnedEntitiesCount);
EXPECT_TRUE(allReplaced); EXPECT_TRUE(allAdded);
} }
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged) TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
@ -1169,23 +1168,12 @@ namespace UnitTest
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 }; AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
size_t spawnedEntitiesCount = 0; size_t spawnedEntitiesCount = 0;
bool allReplaced = true; bool allMerged = true;
auto callback = [&spawnedEntitiesCount, &allReplaced]( auto callback = [&spawnedEntitiesCount, &allMerged](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities) AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{ {
spawnedEntitiesCount += entities.size(); spawnedEntitiesCount += entities.size();
for (const AZ::Entity* entity : entities) allMerged = AreAllMerged(entities);
{
if (entity)
{
allReplaced = allReplaced && entity->FindComponent<SourceSpawnableComponent>() != nullptr;
allReplaced = allReplaced && entity->FindComponent<TargetSpawnableComponent>() != nullptr;
}
else
{
allReplaced = false;
}
}
}; };
AzFramework::SpawnEntitiesOptionalArgs optionalArgs; AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback); optionalArgs.m_completionCallback = AZStd::move(callback);
@ -1193,7 +1181,7 @@ namespace UnitTest
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular); m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
EXPECT_EQ(4, spawnedEntitiesCount); EXPECT_EQ(4, spawnedEntitiesCount);
EXPECT_TRUE(allReplaced); EXPECT_TRUE(allMerged);
} }
// //

@ -6,6 +6,7 @@
* *
*/ */
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/UnitTest/TestTypes.h> #include <AzCore/UnitTest/TestTypes.h>
#include <AzFramework/Spawnable/Spawnable.h> #include <AzFramework/Spawnable/Spawnable.h>
#include <AzTest/AzTest.h> #include <AzTest/AzTest.h>
@ -15,6 +16,8 @@ namespace UnitTest
class SpawnableTest : public AllocatorsFixture class SpawnableTest : public AllocatorsFixture
{ {
public: public:
static constexpr size_t DefaultEntityAliasTestCount = 8;
void SetUp() override void SetUp() override
{ {
AllocatorsFixture::SetUp(); AllocatorsFixture::SetUp();
@ -30,25 +33,26 @@ namespace UnitTest
AllocatorsFixture::TearDown(); AllocatorsFixture::TearDown();
} }
void InsertEightEntities() void InsertEntities(size_t count)
{ {
AzFramework::Spawnable::EntityList& entities = m_spawnable->GetEntities(); AzFramework::Spawnable::EntityList& entities = m_spawnable->GetEntities();
entities.reserve(entities.size() + 8); entities.reserve(entities.size() + count);
for (size_t i = 0; i < 8; ++i) for (size_t i = 0; i < count; ++i)
{ {
entities.emplace_back(AZStd::make_unique<AZ::Entity>()); entities.emplace_back(AZStd::make_unique<AZ::Entity>());
} }
} }
void InsertEightEntityAliases( template<size_t Count>
const AZStd::array<uint32_t, 8>& sourceIds, void InsertEntityAliases(
const AZStd::array<uint32_t, 8>& targetIds, const AZStd::array<uint32_t, Count>& sourceIds,
const AZStd::array<AzFramework::Spawnable::EntityAliasType, 8>& aliasTypes, const AZStd::array<uint32_t, Count>& targetIds,
const AZStd::array<AzFramework::Spawnable::EntityAliasType, Count>& aliasTypes,
bool queueLoad = false) bool queueLoad = false)
{ {
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
for (uint32_t i = 0; i < 8; ++i) for (uint32_t i = 0; i < Count; ++i)
{ {
AZ::Data::Asset<AzFramework::Spawnable> spawnable( AZ::Data::Asset<AzFramework::Spawnable> spawnable(
AZ::Data::AssetId(AZ::Uuid("{4CBEC17A-52D6-42D5-9037-F4C05B9CE1D9}"), i), azrtti_typeid<AzFramework::Spawnable>()); AZ::Data::AssetId(AZ::Uuid("{4CBEC17A-52D6-42D5-9037-F4C05B9CE1D9}"), i), azrtti_typeid<AzFramework::Spawnable>());
@ -56,20 +60,30 @@ namespace UnitTest
} }
} }
void InsertEightEntityAliases(bool queueLoad) template<size_t Count>
void InsertEntityAliases(bool queueLoad)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntityAliases(
{ 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, AZStd::array<uint32_t, Count> ids;
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, for (uint32_t i=0; i<aznumeric_cast<uint32_t>(Count); ++i)
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, {
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace }, ids[i] = i;
queueLoad); }
AZStd::array<AzFramework::Spawnable::EntityAliasType, Count> aliasTypes;
for (uint32_t i = 0; i < aznumeric_cast<uint32_t>(Count); ++i)
{
aliasTypes[i] = Spawnable::EntityAliasType::Replace;
}
InsertEntityAliases<Count>(ids, ids, aliasTypes, queueLoad);
} }
void InsertEightEntityAliases() template<size_t Count>
void InsertEntityAliases()
{ {
InsertEightEntityAliases(false); InsertEntityAliases<Count>(false);
} }
protected: protected:
@ -84,25 +98,25 @@ namespace UnitTest
TEST_F(SpawnableTest, TryGetAliasesConst_GetVisitor_VisitorDataIsAvailable) TEST_F(SpawnableTest, TryGetAliasesConst_GetVisitor_VisitorDataIsAvailable)
{ {
AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst(); AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst();
EXPECT_TRUE(visitor.IsSet()); EXPECT_TRUE(visitor.IsValid());
} }
TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsNotReadShared_VisitorDataIsNotAvailable) TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsNotReadShared_VisitorDataIsNotAvailable)
{ {
AzFramework::Spawnable::EntityAliasVisitor readWriteVisitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor readWriteVisitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(readWriteVisitor.IsSet()); ASSERT_TRUE(readWriteVisitor.IsValid());
AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst(); AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst();
EXPECT_FALSE(visitor.IsSet()); EXPECT_FALSE(visitor.IsValid());
} }
TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsAlreadyReadShared_VisitorDataIsAvailable) TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsAlreadyReadShared_VisitorDataIsAvailable)
{ {
AzFramework::Spawnable::EntityAliasConstVisitor readVisitor = m_spawnable->TryGetAliasesConst(); AzFramework::Spawnable::EntityAliasConstVisitor readVisitor = m_spawnable->TryGetAliasesConst();
ASSERT_TRUE(readVisitor.IsSet()); ASSERT_TRUE(readVisitor.IsValid());
AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst(); AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst();
EXPECT_TRUE(visitor.IsSet()); EXPECT_TRUE(visitor.IsValid());
} }
@ -113,16 +127,16 @@ namespace UnitTest
TEST_F(SpawnableTest, TryGetAliases_GetVisitor_VisitorDataIsAvailable) TEST_F(SpawnableTest, TryGetAliases_GetVisitor_VisitorDataIsAvailable)
{ {
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
EXPECT_TRUE(visitor.IsSet()); EXPECT_TRUE(visitor.IsValid());
} }
TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsAlreadyShared_VisitorDataNotIsAvailable) TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsAlreadyShared_VisitorDataNotIsAvailable)
{ {
AzFramework::Spawnable::EntityAliasConstVisitor readVisitor = m_spawnable->TryGetAliasesConst(); AzFramework::Spawnable::EntityAliasConstVisitor readVisitor = m_spawnable->TryGetAliasesConst();
ASSERT_TRUE(readVisitor.IsSet()); ASSERT_TRUE(readVisitor.IsValid());
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
EXPECT_FALSE(visitor.IsSet()); EXPECT_FALSE(visitor.IsValid());
} }
@ -138,17 +152,17 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_HasAliases_EmptyAliasList_ReturnsFalse) TEST_F(SpawnableTest, EntityAliasVisitor_HasAliases_EmptyAliasList_ReturnsFalse)
{ {
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_FALSE(visitor.HasAliases()); EXPECT_FALSE(visitor.HasAliases());
} }
TEST_F(SpawnableTest, EntityAliasVisitor_HasAliases_FilledInAliasList_ReturnsTue) TEST_F(SpawnableTest, EntityAliasVisitor_HasAliases_FilledInAliasList_ReturnsTrue)
{ {
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases(); InsertEntityAliases<8>();
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_TRUE(visitor.HasAliases()); EXPECT_TRUE(visitor.HasAliases());
} }
@ -160,10 +174,10 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_SortEntityAliases_AliasesAreSortedBySourceAndTargetId) TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_SortEntityAliases_AliasesAreSortedBySourceAndTargetId)
{ {
InsertEightEntities(); InsertEntities(DefaultEntityAliasTestCount);
InsertEightEntityAliases(); InsertEntityAliases<DefaultEntityAliasTestCount>();
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
// Optimize doesn't need to be explicitly called because the setup of the aliases will cause the alias list to be sorted and optimized. // Optimize doesn't need to be explicitly called because the setup of the aliases will cause the alias list to be sorted and optimized.
@ -188,15 +202,15 @@ namespace UnitTest
SpawnableTest, EntityAliasVisitor_Optimize_RemoveUnused_OnlySecondToLastAliasRemains) SpawnableTest, EntityAliasVisitor_Optimize_RemoveUnused_OnlySecondToLastAliasRemains)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Disable, { Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Disable,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Disable, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Disable,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original }); Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_EQ(1, AZStd::distance(visitor.begin(), visitor.end())); EXPECT_EQ(1, AZStd::distance(visitor.begin(), visitor.end()));
EXPECT_EQ(Spawnable::EntityAliasType::Replace, visitor.begin()->m_aliasType); EXPECT_EQ(Spawnable::EntityAliasType::Replace, visitor.begin()->m_aliasType);
@ -206,15 +220,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_AddAdditional_ThreeAdditionalAliasesAreAdded) TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_AddAdditional_ThreeAdditionalAliasesAreAdded)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 0, 0, 0, 1, 2, 2, 2 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 0, 0, 0, 1, 2, 2, 2 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, { Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional,
Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional,
Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional }); Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_EQ(11, AZStd::distance(visitor.begin(), visitor.end())); EXPECT_EQ(11, AZStd::distance(visitor.begin(), visitor.end()));
EXPECT_EQ(Spawnable::EntityAliasType::Original, visitor.begin()->m_aliasType); EXPECT_EQ(Spawnable::EntityAliasType::Original, visitor.begin()->m_aliasType);
@ -225,15 +239,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_OriginalsOnly_AliasListIsEmpty) TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_OriginalsOnly_AliasListIsEmpty)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, { Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original,
Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original,
Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original }); Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_EQ(0, AZStd::distance(visitor.begin(), visitor.end())); EXPECT_EQ(0, AZStd::distance(visitor.begin(), visitor.end()));
} }
@ -241,15 +255,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_MixedOriginals_AllOriginalsRemoved) TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_MixedOriginals_AllOriginalsRemoved)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 0, 0, 1, 1, 2, 2, 2 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 0, 0, 1, 1, 2, 2, 2 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, { Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original,
Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Disable, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Disable, Spawnable::EntityAliasType::Original,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original }); Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_EQ(2, AZStd::distance(visitor.begin(), visitor.end())); EXPECT_EQ(2, AZStd::distance(visitor.begin(), visitor.end()));
EXPECT_EQ(Spawnable::EntityAliasType::Disable, visitor.begin()->m_aliasType); EXPECT_EQ(Spawnable::EntityAliasType::Disable, visitor.begin()->m_aliasType);
@ -259,15 +273,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_MergeAfterOriginal_NoAdditionalOriginalIsInserted) TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_MergeAfterOriginal_NoAdditionalOriginalIsInserted)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 0, 1, 1, 2, 2, 2, 2 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 0, 1, 1, 2, 2, 2, 2 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Replace, { Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original,
Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original }); Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_EQ(4, AZStd::distance(visitor.begin(), visitor.end())); EXPECT_EQ(4, AZStd::distance(visitor.begin(), visitor.end()));
EXPECT_EQ(Spawnable::EntityAliasType::Original, visitor.begin()->m_aliasType); EXPECT_EQ(Spawnable::EntityAliasType::Original, visitor.begin()->m_aliasType);
@ -284,15 +298,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliasType_AllToOriginal_NoAliasesAfterOptimization) TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliasType_AllToOriginal_NoAliasesAfterOptimization)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, { Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace }); Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
for (uint32_t i = 0; i < 8; ++i) for (uint32_t i = 0; i < 8; ++i)
{ {
@ -317,15 +331,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliases_AllToOriginal_NoAliasesAfterOptimization) TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliases_AllToOriginal_NoAliasesAfterOptimization)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, { Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace }); Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
auto callback = auto callback =
[](Spawnable::EntityAliasType& aliasType, bool& /*queueLoad*/, const AZ::Data::Asset<Spawnable>& /*aliasedSpawnable*/, [](Spawnable::EntityAliasType& aliasType, bool& /*queueLoad*/, const AZ::Data::Asset<Spawnable>& /*aliasedSpawnable*/,
@ -348,15 +362,15 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliases_FilterByTag_OnlyOneAliasUpdated) TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliases_FilterByTag_OnlyOneAliasUpdated)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases( InsertEntityAliases<8>(
{ 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 1, 2, 3, 4, 5, 6, 7 },
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, { Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace }); Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace });
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
bool correctTag = false; bool correctTag = false;
size_t numberOfUpdates = 0; size_t numberOfUpdates = 0;
@ -381,11 +395,11 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_AreAllSpawnablesReady_CheckFakeLoadedAssets_ReturnsTrue) TEST_F(SpawnableTest, EntityAliasVisitor_AreAllSpawnablesReady_CheckFakeLoadedAssets_ReturnsTrue)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(DefaultEntityAliasTestCount);
InsertEightEntityAliases(); InsertEntityAliases<DefaultEntityAliasTestCount>();
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_TRUE(visitor.AreAllSpawnablesReady()); EXPECT_TRUE(visitor.AreAllSpawnablesReady());
} }
@ -393,11 +407,11 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_AreAllSpawnablesReady_CheckFakeNotLoadedAssets_ReturnsFalse) TEST_F(SpawnableTest, EntityAliasVisitor_AreAllSpawnablesReady_CheckFakeNotLoadedAssets_ReturnsFalse)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(8);
InsertEightEntityAliases(true); InsertEntityAliases<8>(true);
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
EXPECT_FALSE(visitor.AreAllSpawnablesReady()); EXPECT_FALSE(visitor.AreAllSpawnablesReady());
} }
@ -410,11 +424,11 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_ListTargetSpawnables_ListAllTargetAssets_AllTargetsListed) TEST_F(SpawnableTest, EntityAliasVisitor_ListTargetSpawnables_ListAllTargetAssets_AllTargetsListed)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(DefaultEntityAliasTestCount);
InsertEightEntityAliases(); InsertEntityAliases<DefaultEntityAliasTestCount>();
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
size_t count = 0; size_t count = 0;
bool correctAssets = true; bool correctAssets = true;
@ -432,11 +446,11 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_ListTargetSpawnables_ListTaggedTargetAssets_OneAssetListed) TEST_F(SpawnableTest, EntityAliasVisitor_ListTargetSpawnables_ListTaggedTargetAssets_OneAssetListed)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(DefaultEntityAliasTestCount);
InsertEightEntityAliases(); InsertEntityAliases<DefaultEntityAliasTestCount>();
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
size_t count = 0; size_t count = 0;
bool correctAsset = false; bool correctAsset = false;
@ -459,11 +473,11 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_ListSpawnablesRequiringLoad_AllSetToLoaded_AllTargetsListed) TEST_F(SpawnableTest, EntityAliasVisitor_ListSpawnablesRequiringLoad_AllSetToLoaded_AllTargetsListed)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(DefaultEntityAliasTestCount);
InsertEightEntityAliases(true); InsertEntityAliases<DefaultEntityAliasTestCount>(true);
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
size_t count = 0; size_t count = 0;
bool correctAssets = true; bool correctAssets = true;
@ -481,11 +495,11 @@ namespace UnitTest
TEST_F(SpawnableTest, EntityAliasVisitor_ListSpawnablesRequiringLoad_AllSetToNotLoaded_NoTargetsListed) TEST_F(SpawnableTest, EntityAliasVisitor_ListSpawnablesRequiringLoad_AllSetToNotLoaded_NoTargetsListed)
{ {
using namespace AzFramework; using namespace AzFramework;
InsertEightEntities(); InsertEntities(DefaultEntityAliasTestCount);
InsertEightEntityAliases(false); InsertEntityAliases<DefaultEntityAliasTestCount>(false);
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
ASSERT_TRUE(visitor.IsSet()); ASSERT_TRUE(visitor.IsValid());
size_t count = 0; size_t count = 0;
auto callback = [&count](const AZ::Data::Asset<Spawnable>& /*targetSpawnable*/) auto callback = [&count](const AZ::Data::Asset<Spawnable>& /*targetSpawnable*/)

@ -220,7 +220,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
if (it == aliasVisitors.end()) if (it == aliasVisitors.end())
{ {
AzFramework::Spawnable::EntityAliasVisitor visitor = source->m_spawnable.TryGetAliases(); AzFramework::Spawnable::EntityAliasVisitor visitor = source->m_spawnable.TryGetAliases();
AZ_Assert(visitor.IsSet(), "Unable to obtain lock for a newly create spawnable."); AZ_Assert(visitor.IsValid(), "Unable to obtain lock for a newly create spawnable.");
it = aliasVisitors.emplace(source->m_spawnable.GetId(), AZStd::move(visitor)).first; it = aliasVisitors.emplace(source->m_spawnable.GetId(), AZStd::move(visitor)).first;
} }
it->second.AddAlias( it->second.AddAlias(

@ -30,7 +30,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
Disable, //!< No alias is added. Disable, //!< No alias is added.
OptionalReplace, //!< At runtime the entity might be replaced. If the alias is disabled the original entity will be spawned. OptionalReplace, //!< At runtime the entity might be replaced. If the alias is disabled the original entity will be spawned.
//!< The original entity will be left in the spawnable and a copy is returned. //!< The original entity will be left in the spawnable and a copy is returned.
Replace, //!< At runtime the entity will be replaced. If the alias is disabled nothing will be spawned not. The original Replace, //!< At runtime the entity will be replaced. If the alias is disabled nothing will be spawned. The original
//!< entity is returned and a blank entity is left. //!< entity is returned and a blank entity is left.
Additional, //!< At runtime the alias entity will be added as an additional but unrelated entity with a new entity id. Additional, //!< At runtime the alias entity will be added as an additional but unrelated entity with a new entity id.
//!< An empty entity will be returned. //!< An empty entity will be returned.

@ -32,38 +32,38 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
return result; return result;
} }
AZ::Entity* FindEntity(AZ::EntityId entity, AzToolsFramework::Prefab::Instance& source) AZ::Entity* FindEntity(AZ::EntityId entityId, AzToolsFramework::Prefab::Instance& source)
{ {
AZ::Entity* result = nullptr; AZ::Entity* result = nullptr;
source.GetEntities( source.GetEntities(
[&result, entity](AZStd::unique_ptr<AZ::Entity>& instance) [&result, entityId](AZStd::unique_ptr<AZ::Entity>& entity)
{ {
if (instance->GetId() != entity) if (entity->GetId() != entityId)
{ {
return true; return true;
} }
else else
{ {
result = instance.get(); result = entity.get();
return false; return false;
} }
}); });
return result; return result;
} }
AZ::Entity* FindEntity(AZ::EntityId entity, AzFramework::Spawnable& source) AZ::Entity* FindEntity(AZ::EntityId entityId, AzFramework::Spawnable& source)
{ {
uint32_t index = AzToolsFramework::Prefab::SpawnableUtils::FindEntityIndex(entity, source); uint32_t index = AzToolsFramework::Prefab::SpawnableUtils::FindEntityIndex(entityId, source);
return index != InvalidEntityIndex ? source.GetEntities()[index].get() : nullptr; return index != InvalidEntityIndex ? source.GetEntities()[index].get() : nullptr;
} }
template<typename T> template<typename T>
AZStd::unique_ptr<AZ::Entity> CloneEntity(AZ::EntityId entity, T& source) AZStd::unique_ptr<AZ::Entity> CloneEntity(AZ::EntityId entityId, T& source)
{ {
AZ::Entity* target = Internal::FindEntity(entity, source); AZ::Entity* target = Internal::FindEntity(entityId, source);
AZ_Assert( AZ_Assert(
target, "SpawnbleUtils were unable to locate entity with id %zu in Instance or Spawnable for cloning.", target, "SpawnbleUtils were unable to locate entity with id %zu in Instance or Spawnable for cloning.",
aznumeric_cast<AZ::u64>(entity)); aznumeric_cast<AZ::u64>(entityId));
auto clone = AZStd::make_unique<AZ::Entity>(); auto clone = AZStd::make_unique<AZ::Entity>();
static AZ::SerializeContext* sc = GetSerializeContext(); static AZ::SerializeContext* sc = GetSerializeContext();
@ -73,12 +73,12 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
return clone; return clone;
} }
AZStd::unique_ptr<AZ::Entity> ReplaceEntityWithPlaceholder(AZ::EntityId entity, AzToolsFramework::Prefab::Instance& source) AZStd::unique_ptr<AZ::Entity> ReplaceEntityWithPlaceholder(AZ::EntityId entityId, AzToolsFramework::Prefab::Instance& source)
{ {
auto&& [instance, alias] = source.FindInstanceAndAlias(entity); auto&& [instance, alias] = source.FindInstanceAndAlias(entityId);
AZ_Assert( AZ_Assert(
instance, "SpawnbleUtils were unable to locate entity alias with id %zu in Instance '%s' for replacing.", instance, "SpawnbleUtils were unable to locate entity alias with id %zu in Instance '%s' for replacing.",
aznumeric_cast<AZ::u64>(entity), source.GetTemplateSourcePath().c_str()); aznumeric_cast<AZ::u64>(entityId), source.GetTemplateSourcePath().c_str());
EntityOptionalReference entityData = instance->GetEntity(alias); EntityOptionalReference entityData = instance->GetEntity(alias);
AZ_Assert( AZ_Assert(
@ -88,17 +88,17 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
return instance->ReplaceEntity(AZStd::move(placeholder), alias); return instance->ReplaceEntity(AZStd::move(placeholder), alias);
} }
AZStd::unique_ptr<AZ::Entity> ReplaceEntityWithPlaceholder(AZ::EntityId entity, AzFramework::Spawnable& source) AZStd::unique_ptr<AZ::Entity> ReplaceEntityWithPlaceholder(AZ::EntityId entityId, AzFramework::Spawnable& source)
{ {
uint32_t index = AzToolsFramework::Prefab::SpawnableUtils::FindEntityIndex(entity, source); uint32_t index = AzToolsFramework::Prefab::SpawnableUtils::FindEntityIndex(entityId, source);
AZ_Assert( AZ_Assert(
index != InvalidEntityIndex, "SpawnbleUtils were unable to locate entity alias with id %zu in Spawnable for replacing.", index != InvalidEntityIndex, "SpawnbleUtils were unable to locate entity alias with id %zu in Spawnable for replacing.",
aznumeric_cast<AZ::u64>(entity)); aznumeric_cast<AZ::u64>(entityId));
AZStd::unique_ptr<AZ::Entity> original = AZStd::move(source.GetEntities()[index]); AZStd::unique_ptr<AZ::Entity> original = AZStd::move(source.GetEntities()[index]);
AZ_Assert( AZ_Assert(
original, "SpawnbleUtils were unable to locate entity with id %zu in Spawnable for replacing.", original, "SpawnbleUtils were unable to locate entity with id %zu in Spawnable for replacing.",
aznumeric_cast<AZ::u64>(entity)); aznumeric_cast<AZ::u64>(entityId));
source.GetEntities()[index] = AZStd::make_unique<AZ::Entity>(original->GetId(), original->GetName()); source.GetEntities()[index] = AZStd::make_unique<AZ::Entity>(original->GetId(), original->GetName());
@ -107,7 +107,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
template<typename Source> template<typename Source>
AZStd::pair<AZStd::unique_ptr<AZ::Entity>, AzFramework::Spawnable::EntityAliasType> ApplyAlias( AZStd::pair<AZStd::unique_ptr<AZ::Entity>, AzFramework::Spawnable::EntityAliasType> ApplyAlias(
Source& source, AZ::EntityId entity, AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType) Source& source, AZ::EntityId entityId, AzToolsFramework::Prefab::PrefabConversionUtils::EntityAliasType aliasType)
{ {
namespace PCU = AzToolsFramework::Prefab::PrefabConversionUtils; namespace PCU = AzToolsFramework::Prefab::PrefabConversionUtils;
using ResultPair = AZStd::pair<AZStd::unique_ptr<AZ::Entity>, AzFramework::Spawnable::EntityAliasType>; using ResultPair = AZStd::pair<AZStd::unique_ptr<AZ::Entity>, AzFramework::Spawnable::EntityAliasType>;
@ -118,14 +118,14 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
// No need to do anything as the alias is disabled. // No need to do anything as the alias is disabled.
return ResultPair(nullptr, AzFramework::Spawnable::EntityAliasType::Disable); return ResultPair(nullptr, AzFramework::Spawnable::EntityAliasType::Disable);
case PCU::EntityAliasType::OptionalReplace: case PCU::EntityAliasType::OptionalReplace:
return ResultPair(CloneEntity(entity, source), AzFramework::Spawnable::EntityAliasType::Replace); return ResultPair(CloneEntity(entityId, source), AzFramework::Spawnable::EntityAliasType::Replace);
case PCU::EntityAliasType::Replace: case PCU::EntityAliasType::Replace:
return ResultPair(ReplaceEntityWithPlaceholder(entity, source), AzFramework::Spawnable::EntityAliasType::Replace); return ResultPair(ReplaceEntityWithPlaceholder(entityId, source), AzFramework::Spawnable::EntityAliasType::Replace);
case PCU::EntityAliasType::Additional: case PCU::EntityAliasType::Additional:
ResultPair(AZStd::make_unique<AZ::Entity>(AZ::Entity::MakeId()), AzFramework::Spawnable::EntityAliasType::Additional); ResultPair(AZStd::make_unique<AZ::Entity>(AZ::Entity::MakeId()), AzFramework::Spawnable::EntityAliasType::Additional);
case PCU::EntityAliasType::Merge: case PCU::EntityAliasType::Merge:
// Use the same entity id as the original entity so at runtime the entity ids can be verified to match. // Use the same entity id as the original entity so at runtime the entity ids can be verified to match.
ResultPair(AZStd::make_unique<AZ::Entity>(entity), AzFramework::Spawnable::EntityAliasType::Merge); ResultPair(AZStd::make_unique<AZ::Entity>(entityId), AzFramework::Spawnable::EntityAliasType::Merge);
default: default:
AZ_Assert( AZ_Assert(
false, "Invalid PrefabProcessorContext::EntityAliasType type (%i) provided.", aznumeric_cast<uint64_t>(aliasType)); false, "Invalid PrefabProcessorContext::EntityAliasType type (%i) provided.", aznumeric_cast<uint64_t>(aliasType));
@ -236,7 +236,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
} }
else else
{ {
AZ_Assert(false, "Entity with id %zu was not found in the source prefab.", static_cast<AZ::u64>(entity)); AZ_Assert(false, "Entity with id %llu was not found in the source prefab.", static_cast<AZ::u64>(entity));
return nullptr; return nullptr;
} }
} }

Loading…
Cancel
Save