Updates for the spawnable entity aliases based on provided feedback.
Signed-off-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com>
This commit is contained in:
@@ -32,7 +32,7 @@ namespace AzFramework
|
||||
// EntityAliasVisitorBase
|
||||
//
|
||||
|
||||
bool Spawnable::EntityAliasVisitorBase::IsSet(const EntityAliasList* aliases) const
|
||||
bool Spawnable::EntityAliasVisitorBase::IsValid(const EntityAliasList* aliases) const
|
||||
{
|
||||
return aliases != nullptr;
|
||||
}
|
||||
@@ -139,7 +139,7 @@ namespace AzFramework
|
||||
|
||||
Spawnable::EntityAliasVisitor::~EntityAliasVisitor()
|
||||
{
|
||||
if (IsSet())
|
||||
if (IsValid())
|
||||
{
|
||||
Optimize();
|
||||
|
||||
@@ -170,9 +170,9 @@ namespace AzFramework
|
||||
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
|
||||
@@ -413,7 +413,7 @@ namespace AzFramework
|
||||
|
||||
Spawnable::EntityAliasConstVisitor::~EntityAliasConstVisitor()
|
||||
{
|
||||
if (IsSet())
|
||||
if (IsValid())
|
||||
{
|
||||
AZ_Assert(
|
||||
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
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace AzFramework
|
||||
class EntityAliasVisitorBase
|
||||
{
|
||||
protected:
|
||||
bool IsSet(const EntityAliasList* aliases) const;
|
||||
bool IsValid(const EntityAliasList* aliases) const;
|
||||
|
||||
bool HasAliases(const EntityAliasList* aliases) const;
|
||||
bool AreAllSpawnablesReady(const EntityAliasList* aliases) const;
|
||||
@@ -100,7 +100,7 @@ namespace AzFramework
|
||||
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.
|
||||
bool IsSet() const;
|
||||
bool IsValid() const;
|
||||
|
||||
bool HasAliases() const;
|
||||
bool AreAllSpawnablesReady() const;
|
||||
@@ -153,7 +153,7 @@ namespace AzFramework
|
||||
~EntityAliasConstVisitor();
|
||||
|
||||
//! 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 AreAllSpawnablesReady() const;
|
||||
@@ -179,7 +179,7 @@ namespace AzFramework
|
||||
Spawnable(const Spawnable& rhs) = delete;
|
||||
Spawnable(Spawnable&& other) = delete;
|
||||
~Spawnable() override = default;
|
||||
|
||||
|
||||
Spawnable& operator=(const Spawnable& rhs) = delete;
|
||||
Spawnable& operator=(Spawnable&& other) = delete;
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace AzFramework
|
||||
const AZ::Data::AssetFilterCB& assetLoadFilterCB)
|
||||
{
|
||||
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())
|
||||
{
|
||||
AZ_Assert(
|
||||
|
||||
@@ -300,20 +300,20 @@ namespace AzFramework
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate,
|
||||
EntityIdMap& templateToCloneMap, AZ::SerializeContext& serializeContext)
|
||||
AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityPrototype,
|
||||
EntityIdMap& prototypeToCloneMap, AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
// 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(
|
||||
&entityTemplate, templateToCloneMap, &serializeContext);
|
||||
&entityPrototype, prototypeToCloneMap, &serializeContext);
|
||||
}
|
||||
|
||||
AZ::Entity* SpawnableEntitiesManager::CloneSingleAliasedEntity(
|
||||
const AZ::Entity& entityTemplate,
|
||||
const AZ::Entity& entityPrototype,
|
||||
const Spawnable::EntityAlias& alias,
|
||||
EntityIdMap& templateToCloneMap,
|
||||
EntityIdMap& prototypeToCloneMap,
|
||||
AZ::Entity* previouslySpawnedEntity,
|
||||
AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
@@ -324,26 +324,27 @@ namespace AzFramework
|
||||
{
|
||||
case Spawnable::EntityAliasType::Original:
|
||||
// Behave as the original version.
|
||||
clone = CloneSingleEntity(entityTemplate, templateToCloneMap, serializeContext);
|
||||
clone = CloneSingleEntity(entityPrototype, prototypeToCloneMap, serializeContext);
|
||||
AZ_Assert(clone != nullptr, "Failed to clone spawnable entity.");
|
||||
return clone;
|
||||
case Spawnable::EntityAliasType::Disable:
|
||||
// Do nothing.
|
||||
return nullptr;
|
||||
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.");
|
||||
return clone;
|
||||
case Spawnable::EntityAliasType::Additional:
|
||||
// The asset handler will have sorted and inserted a Spawnable::EntityAliasType::Original, so the just
|
||||
// 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.");
|
||||
return clone;
|
||||
case Spawnable::EntityAliasType::Merge:
|
||||
AZ_Assert(previouslySpawnedEntity != nullptr, "Merging components but there's no entity to add to yet.");
|
||||
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;
|
||||
default:
|
||||
AZ_Assert(false, "Unsupported spawnable entity alias type: %i", alias.m_aliasType);
|
||||
@@ -353,17 +354,17 @@ namespace AzFramework
|
||||
|
||||
void SpawnableEntitiesManager::AppendComponents(
|
||||
AZ::Entity& target,
|
||||
const AZ::Entity::ComponentArrayType& componentTemplates,
|
||||
EntityIdMap& templateToCloneMap,
|
||||
const AZ::Entity::ComponentArrayType& componentPrototypes,
|
||||
EntityIdMap& prototypeToCloneMap,
|
||||
AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
// Only components are added and entities are looked up so no duplicate entity ids should be encountered.
|
||||
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(
|
||||
component, templateToCloneMap, &serializeContext);
|
||||
component, prototypeToCloneMap, &serializeContext);
|
||||
AZ_Assert(clone, "Unable to clone component for entity '%s' (%zu).", target.GetName().c_str(), target.GetId());
|
||||
[[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());
|
||||
@@ -409,7 +410,7 @@ namespace AzFramework
|
||||
if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId)
|
||||
{
|
||||
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<uint32_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
|
||||
@@ -417,7 +418,7 @@ namespace AzFramework
|
||||
// Keep track how many entities there were in the array initially
|
||||
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();
|
||||
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 (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<uint32_t>& spawnedEntityIndices = ticket.m_spawnedEntityIndices;
|
||||
@@ -538,13 +539,13 @@ namespace AzFramework
|
||||
// Keep track of how many entities there were in the array initially
|
||||
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();
|
||||
size_t entitiesToSpawnSize = request.m_entityIndices.size();
|
||||
|
||||
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.
|
||||
// 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.
|
||||
@@ -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,
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
if (ticket.m_loadAll)
|
||||
@@ -819,7 +820,7 @@ namespace AzFramework
|
||||
Ticket& ticket = *request.m_ticket;
|
||||
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)
|
||||
{
|
||||
@@ -921,7 +922,7 @@ namespace AzFramework
|
||||
if (request.m_checkAliasSpawnables)
|
||||
{
|
||||
if (Spawnable::EntityAliasConstVisitor visitor = ticket.m_spawnable->TryGetAliasesConst();
|
||||
!visitor.IsSet() || !visitor.AreAllSpawnablesReady())
|
||||
!visitor.IsValid() || !visitor.AreAllSpawnablesReady())
|
||||
{
|
||||
return CommandResult::Requeue;
|
||||
}
|
||||
|
||||
@@ -96,9 +96,9 @@ namespace AzFramework
|
||||
AZ_CLASS_ALLOCATOR(Ticket, AZ::ThreadPoolAllocator, 0);
|
||||
static constexpr uint32_t Processing = AZStd::numeric_limits<uint32_t>::max();
|
||||
|
||||
//! Map of template 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.
|
||||
//! Since template entities can reference other entities, this map is used to fix up those references across calls
|
||||
//! Map of prototype entity ids to their associated instance ids.
|
||||
//! Tickets can be used to spawn the same prototype entities multiple times, in any order, across multiple calls.
|
||||
//! Since prototype entities can reference other entities, this map is used to fix up those references across calls
|
||||
//! 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
|
||||
//! 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);
|
||||
|
||||
AZ::Entity* CloneSingleEntity(
|
||||
const AZ::Entity& entityTemplate, EntityIdMap& templateToCloneMap, AZ::SerializeContext& serializeContext);
|
||||
const AZ::Entity& entityPrototype, EntityIdMap& prototypeToCloneMap, AZ::SerializeContext& serializeContext);
|
||||
AZ::Entity* CloneSingleAliasedEntity(
|
||||
const AZ::Entity& entityTemplate,
|
||||
const AZ::Entity& entityPrototype,
|
||||
const Spawnable::EntityAlias& alias,
|
||||
EntityIdMap& templateToCloneMap,
|
||||
EntityIdMap& prototypeToCloneMap,
|
||||
AZ::Entity* previouslySpawnedEntity,
|
||||
AZ::SerializeContext& serializeContext);
|
||||
void AppendComponents(
|
||||
AZ::Entity& target,
|
||||
const AZ::Entity::ComponentArrayType& componentTemplates,
|
||||
EntityIdMap& templateToCloneMap,
|
||||
const AZ::Entity::ComponentArrayType& componentPrototypes,
|
||||
EntityIdMap& prototypeToCloneMap,
|
||||
AZ::SerializeContext& serializeContext);
|
||||
|
||||
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()
|
||||
{
|
||||
AzFramework::Spawnable::EntityList& entities = m_spawnable->GetEntities();
|
||||
@@ -539,18 +612,7 @@ namespace UnitTest
|
||||
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;
|
||||
}
|
||||
}
|
||||
allReplaced = AreAllEntitiesReplaced(entities);
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
@@ -574,33 +636,12 @@ namespace UnitTest
|
||||
&target);
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
bool allAdded = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allAdded](
|
||||
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;
|
||||
}
|
||||
}
|
||||
allAdded = IsEveryOtherEntityAReplacement(entities);
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
@@ -608,7 +649,7 @@ namespace UnitTest
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(8, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
EXPECT_TRUE(allAdded);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
|
||||
@@ -624,23 +665,12 @@ namespace UnitTest
|
||||
&target);
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
bool allMerged = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allMerged](
|
||||
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;
|
||||
}
|
||||
}
|
||||
allMerged = AreAllMerged(entities);
|
||||
};
|
||||
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
@@ -648,7 +678,7 @@ namespace UnitTest
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(4, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
EXPECT_TRUE(allMerged);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1080,18 +1110,7 @@ namespace UnitTest
|
||||
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;
|
||||
}
|
||||
}
|
||||
allReplaced = AreAllEntitiesReplaced(entities);
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
@@ -1117,33 +1136,13 @@ namespace UnitTest
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
bool allAdded = true;
|
||||
auto callback =
|
||||
[&spawnedEntitiesCount, &allAdded](
|
||||
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;
|
||||
}
|
||||
}
|
||||
allAdded = IsEveryOtherEntityAReplacement(entities);
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
@@ -1151,7 +1150,7 @@ namespace UnitTest
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
EXPECT_EQ(8, spawnedEntitiesCount);
|
||||
EXPECT_TRUE(allReplaced);
|
||||
EXPECT_TRUE(allAdded);
|
||||
}
|
||||
|
||||
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
|
||||
@@ -1169,23 +1168,12 @@ namespace UnitTest
|
||||
AZStd::vector<uint32_t> indices = { 0, 2, 3, 1 };
|
||||
|
||||
size_t spawnedEntitiesCount = 0;
|
||||
bool allReplaced = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allReplaced](
|
||||
bool allMerged = true;
|
||||
auto callback = [&spawnedEntitiesCount, &allMerged](
|
||||
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;
|
||||
}
|
||||
}
|
||||
allMerged = AreAllMerged(entities);
|
||||
};
|
||||
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
|
||||
optionalArgs.m_completionCallback = AZStd::move(callback);
|
||||
@@ -1193,7 +1181,7 @@ namespace UnitTest
|
||||
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
|
||||
|
||||
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 <AzFramework/Spawnable/Spawnable.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
@@ -15,6 +16,8 @@ namespace UnitTest
|
||||
class SpawnableTest : public AllocatorsFixture
|
||||
{
|
||||
public:
|
||||
static constexpr size_t DefaultEntityAliasTestCount = 8;
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
@@ -30,25 +33,26 @@ namespace UnitTest
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
|
||||
void InsertEightEntities()
|
||||
void InsertEntities(size_t count)
|
||||
{
|
||||
AzFramework::Spawnable::EntityList& entities = m_spawnable->GetEntities();
|
||||
entities.reserve(entities.size() + 8);
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
entities.reserve(entities.size() + count);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
entities.emplace_back(AZStd::make_unique<AZ::Entity>());
|
||||
}
|
||||
}
|
||||
|
||||
void InsertEightEntityAliases(
|
||||
const AZStd::array<uint32_t, 8>& sourceIds,
|
||||
const AZStd::array<uint32_t, 8>& targetIds,
|
||||
const AZStd::array<AzFramework::Spawnable::EntityAliasType, 8>& aliasTypes,
|
||||
template<size_t Count>
|
||||
void InsertEntityAliases(
|
||||
const AZStd::array<uint32_t, Count>& sourceIds,
|
||||
const AZStd::array<uint32_t, Count>& targetIds,
|
||||
const AZStd::array<AzFramework::Spawnable::EntityAliasType, Count>& aliasTypes,
|
||||
bool queueLoad = false)
|
||||
{
|
||||
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::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;
|
||||
InsertEightEntityAliases(
|
||||
{ 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 },
|
||||
queueLoad);
|
||||
|
||||
AZStd::array<uint32_t, Count> ids;
|
||||
for (uint32_t i=0; i<aznumeric_cast<uint32_t>(Count); ++i)
|
||||
{
|
||||
ids[i] = i;
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -84,25 +98,25 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, TryGetAliasesConst_GetVisitor_VisitorDataIsAvailable)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst();
|
||||
EXPECT_TRUE(visitor.IsSet());
|
||||
EXPECT_TRUE(visitor.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsNotReadShared_VisitorDataIsNotAvailable)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasVisitor readWriteVisitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(readWriteVisitor.IsSet());
|
||||
ASSERT_TRUE(readWriteVisitor.IsValid());
|
||||
|
||||
AzFramework::Spawnable::EntityAliasConstVisitor visitor = m_spawnable->TryGetAliasesConst();
|
||||
EXPECT_FALSE(visitor.IsSet());
|
||||
EXPECT_FALSE(visitor.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsAlreadyReadShared_VisitorDataIsAvailable)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasConstVisitor readVisitor = m_spawnable->TryGetAliasesConst();
|
||||
ASSERT_TRUE(readVisitor.IsSet());
|
||||
ASSERT_TRUE(readVisitor.IsValid());
|
||||
|
||||
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)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
EXPECT_TRUE(visitor.IsSet());
|
||||
EXPECT_TRUE(visitor.IsValid());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableTest, TryGetAliasesConst_VisitorThatIsAlreadyShared_VisitorDataNotIsAvailable)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasConstVisitor readVisitor = m_spawnable->TryGetAliasesConst();
|
||||
ASSERT_TRUE(readVisitor.IsSet());
|
||||
ASSERT_TRUE(readVisitor.IsValid());
|
||||
|
||||
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)
|
||||
{
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
EXPECT_FALSE(visitor.HasAliases());
|
||||
}
|
||||
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_HasAliases_FilledInAliasList_ReturnsTue)
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_HasAliases_FilledInAliasList_ReturnsTrue)
|
||||
{
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases();
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>();
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
EXPECT_TRUE(visitor.HasAliases());
|
||||
}
|
||||
@@ -160,10 +174,10 @@ namespace UnitTest
|
||||
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_SortEntityAliases_AliasesAreSortedBySourceAndTargetId)
|
||||
{
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases();
|
||||
InsertEntities(DefaultEntityAliasTestCount);
|
||||
InsertEntityAliases<DefaultEntityAliasTestCount>();
|
||||
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.
|
||||
|
||||
@@ -188,15 +202,15 @@ namespace UnitTest
|
||||
SpawnableTest, EntityAliasVisitor_Optimize_RemoveUnused_OnlySecondToLastAliasRemains)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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 });
|
||||
|
||||
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(Spawnable::EntityAliasType::Replace, visitor.begin()->m_aliasType);
|
||||
@@ -206,15 +220,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_AddAdditional_ThreeAdditionalAliasesAreAdded)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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 });
|
||||
|
||||
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(Spawnable::EntityAliasType::Original, visitor.begin()->m_aliasType);
|
||||
@@ -225,15 +239,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_OriginalsOnly_AliasListIsEmpty)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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 });
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
EXPECT_EQ(0, AZStd::distance(visitor.begin(), visitor.end()));
|
||||
}
|
||||
@@ -241,15 +255,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_MixedOriginals_AllOriginalsRemoved)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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::Disable, Spawnable::EntityAliasType::Original,
|
||||
Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Original });
|
||||
|
||||
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(Spawnable::EntityAliasType::Disable, visitor.begin()->m_aliasType);
|
||||
@@ -259,15 +273,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_Optimize_MergeAfterOriginal_NoAdditionalOriginalIsInserted)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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::Merge, Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original,
|
||||
Spawnable::EntityAliasType::Original, Spawnable::EntityAliasType::Original });
|
||||
|
||||
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(Spawnable::EntityAliasType::Original, visitor.begin()->m_aliasType);
|
||||
@@ -284,15 +298,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliasType_AllToOriginal_NoAliasesAfterOptimization)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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 });
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
for (uint32_t i = 0; i < 8; ++i)
|
||||
{
|
||||
@@ -317,15 +331,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliases_AllToOriginal_NoAliasesAfterOptimization)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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 });
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
auto callback =
|
||||
[](Spawnable::EntityAliasType& aliasType, bool& /*queueLoad*/, const AZ::Data::Asset<Spawnable>& /*aliasedSpawnable*/,
|
||||
@@ -348,15 +362,15 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_UpdateAliases_FilterByTag_OnlyOneAliasUpdated)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(
|
||||
{ 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 });
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
bool correctTag = false;
|
||||
size_t numberOfUpdates = 0;
|
||||
@@ -381,11 +395,11 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_AreAllSpawnablesReady_CheckFakeLoadedAssets_ReturnsTrue)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases();
|
||||
InsertEntities(DefaultEntityAliasTestCount);
|
||||
InsertEntityAliases<DefaultEntityAliasTestCount>();
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
EXPECT_TRUE(visitor.AreAllSpawnablesReady());
|
||||
}
|
||||
@@ -393,11 +407,11 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_AreAllSpawnablesReady_CheckFakeNotLoadedAssets_ReturnsFalse)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(true);
|
||||
InsertEntities(8);
|
||||
InsertEntityAliases<8>(true);
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
EXPECT_FALSE(visitor.AreAllSpawnablesReady());
|
||||
}
|
||||
@@ -410,11 +424,11 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_ListTargetSpawnables_ListAllTargetAssets_AllTargetsListed)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases();
|
||||
InsertEntities(DefaultEntityAliasTestCount);
|
||||
InsertEntityAliases<DefaultEntityAliasTestCount>();
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
size_t count = 0;
|
||||
bool correctAssets = true;
|
||||
@@ -432,11 +446,11 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_ListTargetSpawnables_ListTaggedTargetAssets_OneAssetListed)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases();
|
||||
InsertEntities(DefaultEntityAliasTestCount);
|
||||
InsertEntityAliases<DefaultEntityAliasTestCount>();
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
size_t count = 0;
|
||||
bool correctAsset = false;
|
||||
@@ -459,11 +473,11 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_ListSpawnablesRequiringLoad_AllSetToLoaded_AllTargetsListed)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(true);
|
||||
InsertEntities(DefaultEntityAliasTestCount);
|
||||
InsertEntityAliases<DefaultEntityAliasTestCount>(true);
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
size_t count = 0;
|
||||
bool correctAssets = true;
|
||||
@@ -481,11 +495,11 @@ namespace UnitTest
|
||||
TEST_F(SpawnableTest, EntityAliasVisitor_ListSpawnablesRequiringLoad_AllSetToNotLoaded_NoTargetsListed)
|
||||
{
|
||||
using namespace AzFramework;
|
||||
InsertEightEntities();
|
||||
InsertEightEntityAliases(false);
|
||||
InsertEntities(DefaultEntityAliasTestCount);
|
||||
InsertEntityAliases<DefaultEntityAliasTestCount>(false);
|
||||
|
||||
AzFramework::Spawnable::EntityAliasVisitor visitor = m_spawnable->TryGetAliases();
|
||||
ASSERT_TRUE(visitor.IsSet());
|
||||
ASSERT_TRUE(visitor.IsValid());
|
||||
|
||||
size_t count = 0;
|
||||
auto callback = [&count](const AZ::Data::Asset<Spawnable>& /*targetSpawnable*/)
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
if (it == aliasVisitors.end())
|
||||
{
|
||||
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->second.AddAlias(
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ namespace AzToolsFramework::Prefab::PrefabConversionUtils
|
||||
Disable, //!< No alias is added.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
+21
-21
@@ -32,38 +32,38 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
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;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = instance.get();
|
||||
result = entity.get();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
||||
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(
|
||||
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>();
|
||||
|
||||
static AZ::SerializeContext* sc = GetSerializeContext();
|
||||
@@ -73,12 +73,12 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
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(
|
||||
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);
|
||||
AZ_Assert(
|
||||
@@ -88,17 +88,17 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
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(
|
||||
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]);
|
||||
AZ_Assert(
|
||||
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());
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
|
||||
template<typename Source>
|
||||
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;
|
||||
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.
|
||||
return ResultPair(nullptr, AzFramework::Spawnable::EntityAliasType::Disable);
|
||||
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:
|
||||
return ResultPair(ReplaceEntityWithPlaceholder(entity, source), AzFramework::Spawnable::EntityAliasType::Replace);
|
||||
return ResultPair(ReplaceEntityWithPlaceholder(entityId, source), AzFramework::Spawnable::EntityAliasType::Replace);
|
||||
case PCU::EntityAliasType::Additional:
|
||||
ResultPair(AZStd::make_unique<AZ::Entity>(AZ::Entity::MakeId()), AzFramework::Spawnable::EntityAliasType::Additional);
|
||||
case PCU::EntityAliasType::Merge:
|
||||
// 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:
|
||||
AZ_Assert(
|
||||
false, "Invalid PrefabProcessorContext::EntityAliasType type (%i) provided.", aznumeric_cast<uint64_t>(aliasType));
|
||||
@@ -236,7 +236,7 @@ namespace AzToolsFramework::Prefab::SpawnableUtils
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user