Merge remote-tracking branch 'upstream/development' into compiletime_filerequest_code2

This commit is contained in:
nemerle
2022-01-08 21:25:48 +01:00
785 changed files with 141969 additions and 22455 deletions
@@ -10,6 +10,7 @@
#include <AzCore/Asset/AssetCommon.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/RTTI/TypeSafeIntegral.h>
#include <AzCore/std/functional.h>
#include <AzFramework/Spawnable/Spawnable.h>
@@ -164,6 +165,8 @@ namespace AzFramework
public:
friend class SpawnableEntitiesDefinition;
AZ_CLASS_ALLOCATOR(AzFramework::EntitySpawnTicket, AZ::SystemAllocator, 0);
using Id = uint32_t;
EntitySpawnTicket() = default;
@@ -499,12 +499,8 @@ namespace AzFramework
for (auto it = newEntitiesBegin; it != newEntitiesEnd; ++it)
{
AZ::Entity* clone = (*it);
// The entity component framework doesn't handle entities without TransformComponent safely.
if (!clone->GetComponents().empty())
{
clone->SetSpawnTicketId(request.m_ticketId);
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
}
clone->SetSpawnTicketId(request.m_ticketId);
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, clone);
}
// Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context.
@@ -636,12 +632,8 @@ namespace AzFramework
for (auto it = ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount; it != ticket.m_spawnedEntities.end(); ++it)
{
AZ::Entity* clone = (*it);
// The entity component framework doesn't handle entities without TransformComponent safely.
if (!clone->GetComponents().empty())
{
clone->SetSpawnTicketId(request.m_ticketId);
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
}
clone->SetSpawnTicketId(request.m_ticketId);
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
}
if (request.m_completionCallback)
@@ -668,7 +660,7 @@ namespace AzFramework
{
if (entity != nullptr)
{
// Setting it to 0 is needed to avoid the infite loop between GameEntityContext and SpawnableEntitiesManager.
// Setting it to 0 is needed to avoid the infinite loop between GameEntityContext and SpawnableEntitiesManager.
entity->SetSpawnTicketId(0);
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
@@ -702,7 +694,7 @@ namespace AzFramework
{
if (*entityIterator != nullptr && (*entityIterator)->GetId() == request.m_entityId)
{
// Setting it to 0 is needed to avoid the infite loop between GameEntityContext and SpawnableEntitiesManager.
// Setting it to 0 is needed to avoid the infinite loop between GameEntityContext and SpawnableEntitiesManager.
(*entityIterator)->SetSpawnTicketId(0);
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, (*entityIterator)->GetId());
@@ -949,11 +941,6 @@ namespace AzFramework
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
}
else
{
// Entities without components wouldn't have been send to the GameEntityContext.
delete entity;
}
}
delete request.m_ticket;
@@ -270,8 +270,6 @@ set(FILES
Physics/WindBus.h
Process/ProcessCommunicator.cpp
Process/ProcessCommunicator.h
Process/ProcessWatcher.cpp
Process/ProcessWatcher.h
Process/ProcessCommon_fwd.h
Process/ProcessCommunicator.h
Process/ProcessWatcher.cpp
@@ -83,4 +83,9 @@ namespace AzFramework
{
}
AZStd::string ProcessLauncher::ProcessLaunchInfo::GetCommandLineParametersAsString() const
{
return AZStd::string{};
}
} //namespace AzFramework
@@ -77,6 +77,12 @@ namespace UnitTest
public:
AZ_COMPONENT(TargetSpawnableComponent, "{B4041561-63A7-4E1E-80F1-78C08D497960}");
TargetSpawnableComponent() = default;
explicit TargetSpawnableComponent(AZ::EntityId parent)
: m_parent(parent)
{
}
void Activate() override {}
void Deactivate() override {}
@@ -84,14 +90,19 @@ namespace UnitTest
{
if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflection))
{
serializeContext->Class<TargetSpawnableComponent, AZ::Component>();
serializeContext->Class<TargetSpawnableComponent, AZ::Component>()
->Field("Parent", &TargetSpawnableComponent::m_parent);
}
}
AZ::EntityId m_parent;
};
class SpawnableEntitiesManagerTest : public AllocatorsFixture
{
public:
constexpr static AZ::u64 EntityIdStartId = 40;
void SetUp() override
{
AllocatorsFixture::SetUp();
@@ -111,7 +122,7 @@ namespace UnitTest
m_spawnable = aznew AzFramework::Spawnable(
AZ::Data::AssetId::CreateString("{EB2E8A2B-F253-4A90-BBF4-55F2EED786B8}:0"), AZ::Data::AssetData::AssetStatus::Ready);
m_spawnableAsset = new AZ::Data::Asset<AzFramework::Spawnable>(m_spawnable, AZ::Data::AssetLoadBehavior::Default);
m_ticket = new AzFramework::EntitySpawnTicket(*m_spawnableAsset);
m_ticket = aznew AzFramework::EntitySpawnTicket(*m_spawnableAsset);
auto managerInterface = AzFramework::SpawnableEntitiesInterface::Get();
m_manager = azrtti_cast<AzFramework::SpawnableEntitiesManager*>(managerInterface);
@@ -147,22 +158,43 @@ namespace UnitTest
{
auto entry = AZStd::make_unique<AZ::Entity>();
entry->AddComponent(aznew SourceSpawnableComponent());
entry->SetId(AZ::EntityId(EntityIdStartId + i));
entities.push_back(AZStd::move(entry));
}
}
AZ::Data::Asset<AzFramework::Spawnable> CreateTargetSpawnable(size_t numElements)
AZ::Data::Asset<AzFramework::Spawnable> CreateTargetSpawnable(size_t numElements, bool requiresMatchingEntityIds)
{
auto target = aznew AzFramework::Spawnable(
AZ::Data::AssetId(AZ::Uuid("{716CD8C3-0BA8-4F32-B579-0EC7C967796F}")), AZ::Data::AssetData::AssetStatus::Ready);
AzFramework::Spawnable::EntityList& entities = target->GetEntities();
entities.reserve(numElements);
for (size_t i = 0; i < numElements; ++i)
if (requiresMatchingEntityIds)
{
auto entry = AZStd::make_unique<AZ::Entity>();
entry->AddComponent(aznew TargetSpawnableComponent());
entities.push_back(AZStd::move(entry));
for (size_t i = 0; i < numElements; ++i)
{
auto entry = AZStd::make_unique<AZ::Entity>();
if (i != 0)
{
entry->AddComponent(aznew TargetSpawnableComponent(AZ::EntityId(EntityIdStartId + i - 1)));
}
else
{
entry->AddComponent(aznew TargetSpawnableComponent());
}
entry->SetId(AZ::EntityId(EntityIdStartId + i));
entities.push_back(AZStd::move(entry));
}
}
else
{
for (size_t i = 0; i < numElements; ++i)
{
auto entry = AZStd::make_unique<AZ::Entity>();
entry->AddComponent(aznew TargetSpawnableComponent());
entities.push_back(AZStd::move(entry));
}
}
return AZ::Data::Asset<AzFramework::Spawnable>(target, AZ::Data::AssetLoadBehavior::NoLoad);
@@ -212,6 +244,38 @@ namespace UnitTest
return true;
}
static bool DoParentEntityIdsMatch(AzFramework::SpawnableConstEntityContainerView entities)
{
if (entities.empty())
{
return false;
}
const AZ::Entity* previous = nullptr;
for (const AZ::Entity* entity : entities)
{
if (entity)
{
if (previous)
{
if (TargetSpawnableComponent* link = entity->FindComponent<TargetSpawnableComponent>(); link != nullptr)
{
if (link->m_parent != previous->GetId())
{
return false;
}
}
previous = entity;
}
}
else
{
return false;
}
}
return true;
}
static bool IsEveryOtherEntityAReplacement(AzFramework::SpawnableConstEntityContainerView entities)
{
bool onAlternative = true;
@@ -516,7 +580,7 @@ namespace UnitTest
// Make sure we start with a fresh ticket each time, or else each iteration through this loop would continue to build up
// more and more entities.
delete m_ticket;
m_ticket = new AzFramework::EntitySpawnTicket(*m_spawnableAsset);
m_ticket = aznew AzFramework::EntitySpawnTicket(*m_spawnableAsset);
constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
@@ -599,7 +663,8 @@ namespace UnitTest
using namespace AzFramework;
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
constexpr bool requiresMatchingEntityIds = true;
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4, requiresMatchingEntityIds);
InsertEntityAliases<4>(
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
@@ -608,11 +673,13 @@ namespace UnitTest
size_t spawnedEntitiesCount = 0;
bool allReplaced = false;
auto callback = [&spawnedEntitiesCount, &allReplaced](
bool allEntityIdsPatched = false;
auto callback = [&spawnedEntitiesCount, &allReplaced, &allEntityIdsPatched](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{
spawnedEntitiesCount += entities.size();
allReplaced = AreAllEntitiesReplaced(entities);
allEntityIdsPatched = DoParentEntityIdsMatch(entities);
};
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback);
@@ -621,6 +688,7 @@ namespace UnitTest
EXPECT_EQ(4, spawnedEntitiesCount);
EXPECT_TRUE(allReplaced);
EXPECT_TRUE(allEntityIdsPatched);
}
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithAdditional_SourceAndTargetComponentsMerged)
@@ -628,7 +696,8 @@ namespace UnitTest
using namespace AzFramework;
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
constexpr bool requiresMatchingEntityIds = false;
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4, requiresMatchingEntityIds);
InsertEntityAliases<4>(
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
{ Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional,
@@ -637,11 +706,13 @@ namespace UnitTest
size_t spawnedEntitiesCount = 0;
bool allAdded = false;
auto callback = [&spawnedEntitiesCount, &allAdded](
bool allEntityIdsPatched = false;
auto callback = [&spawnedEntitiesCount, &allAdded, &allEntityIdsPatched](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{
spawnedEntitiesCount += entities.size();
allAdded = IsEveryOtherEntityAReplacement(entities);
allEntityIdsPatched = DoParentEntityIdsMatch(entities);
};
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback);
@@ -650,6 +721,7 @@ namespace UnitTest
EXPECT_EQ(8, spawnedEntitiesCount);
EXPECT_TRUE(allAdded);
EXPECT_TRUE(allEntityIdsPatched);
}
TEST_F(SpawnableEntitiesManagerTest, SpawnAllEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
@@ -657,7 +729,8 @@ namespace UnitTest
using namespace AzFramework;
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
constexpr bool requiresMatchingEntityIds = true;
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4, requiresMatchingEntityIds);
InsertEntityAliases<4>(
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
{ Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge,
@@ -666,11 +739,13 @@ namespace UnitTest
size_t spawnedEntitiesCount = 0;
bool allMerged = false;
auto callback = [&spawnedEntitiesCount, &allMerged](
bool allEntityIdsPatched = false;
auto callback = [&spawnedEntitiesCount, &allMerged, &allEntityIdsPatched](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{
spawnedEntitiesCount += entities.size();
allMerged = AreAllMerged(entities);
allEntityIdsPatched = DoParentEntityIdsMatch(entities);
};
AzFramework::SpawnAllEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback);
@@ -679,6 +754,7 @@ namespace UnitTest
EXPECT_EQ(4, spawnedEntitiesCount);
EXPECT_TRUE(allMerged);
EXPECT_TRUE(allEntityIdsPatched);
}
//
@@ -1095,7 +1171,8 @@ namespace UnitTest
using namespace AzFramework;
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
constexpr bool requiresMatchingEntityIds = true;
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4, requiresMatchingEntityIds);
InsertEntityAliases<4>(
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
{ Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace, Spawnable::EntityAliasType::Replace,
@@ -1106,11 +1183,13 @@ namespace UnitTest
size_t spawnedEntitiesCount = 0;
bool allReplaced = false;
auto callback = [&spawnedEntitiesCount, &allReplaced](
bool allEntityIdsPatched = false;
auto callback = [&spawnedEntitiesCount, &allReplaced, &allEntityIdsPatched](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{
spawnedEntitiesCount += entities.size();
allReplaced = AreAllEntitiesReplaced(entities);
allEntityIdsPatched = DoParentEntityIdsMatch(entities);
};
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback);
@@ -1119,6 +1198,7 @@ namespace UnitTest
EXPECT_EQ(4, spawnedEntitiesCount);
EXPECT_TRUE(allReplaced);
EXPECT_TRUE(allEntityIdsPatched);
}
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithAdditional_SourceAndTargetComponentsMerged)
@@ -1126,7 +1206,8 @@ namespace UnitTest
using namespace AzFramework;
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
constexpr bool requiresMatchingEntityIds = false;
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4, requiresMatchingEntityIds);
InsertEntityAliases<4>(
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
{ Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional, Spawnable::EntityAliasType::Additional,
@@ -1137,12 +1218,14 @@ namespace UnitTest
size_t spawnedEntitiesCount = 0;
bool allAdded = false;
bool allEntityIdsPatched = false;
auto callback =
[&spawnedEntitiesCount, &allAdded](
[&spawnedEntitiesCount, &allAdded, &allEntityIdsPatched](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{
spawnedEntitiesCount += entities.size();
allAdded = IsEveryOtherEntityAReplacement(entities);
allEntityIdsPatched = DoParentEntityIdsMatch(entities);
};
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback);
@@ -1151,6 +1234,7 @@ namespace UnitTest
EXPECT_EQ(8, spawnedEntitiesCount);
EXPECT_TRUE(allAdded);
EXPECT_TRUE(allEntityIdsPatched);
}
TEST_F(SpawnableEntitiesManagerTest, SpawnEntities_AllAliasesWithMerge_SourceAndTargetComponentsMerged)
@@ -1158,7 +1242,8 @@ namespace UnitTest
using namespace AzFramework;
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4);
constexpr bool requiresMatchingEntityIds = true;
AZ::Data::Asset<Spawnable> target = CreateTargetSpawnable(4, requiresMatchingEntityIds);
InsertEntityAliases<4>(
{ 0, 1, 2, 3 }, { 0, 1, 2, 3 },
{ Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge, Spawnable::EntityAliasType::Merge,
@@ -1169,11 +1254,13 @@ namespace UnitTest
size_t spawnedEntitiesCount = 0;
bool allMerged = false;
auto callback = [&spawnedEntitiesCount, &allMerged](
bool allEntityIdsPatched = false;
auto callback = [&spawnedEntitiesCount, &allMerged, &allEntityIdsPatched](
AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableConstEntityContainerView entities)
{
spawnedEntitiesCount += entities.size();
allMerged = AreAllMerged(entities);
allEntityIdsPatched = DoParentEntityIdsMatch(entities);
};
AzFramework::SpawnEntitiesOptionalArgs optionalArgs;
optionalArgs.m_completionCallback = AZStd::move(callback);
@@ -1182,6 +1269,7 @@ namespace UnitTest
EXPECT_EQ(4, spawnedEntitiesCount);
EXPECT_TRUE(allMerged);
EXPECT_TRUE(allEntityIdsPatched);
}
//
@@ -1302,6 +1390,36 @@ namespace UnitTest
// ClaimEntities
//
TEST_F(SpawnableEntitiesManagerTest, ClaimEntities_Call_AllEntitiesWereClaimedAndNotDeleted)
{
static constexpr size_t NumEntities = 4;
FillSpawnable(NumEntities);
AZStd::vector<AZ::Entity*> claimedEntities;
auto callback = [&claimedEntities](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableEntityContainerView container)
{
for (AZ::Entity* entity : container)
{
claimedEntities.push_back(entity);
}
};
{
AzFramework::EntitySpawnTicket ticket(*m_spawnableAsset);
m_manager->SpawnAllEntities(ticket);
m_manager->ClaimEntities(ticket, AZStd::move(callback));
m_manager->ProcessQueue(AzFramework::SpawnableEntitiesManager::CommandQueuePriority::Regular);
}
EXPECT_EQ(NumEntities, claimedEntities.size());
// If these calls fail it means that the ticket has still deleted the entities, so they weren't properly claimed.
for (AZ::Entity* entity : claimedEntities)
{
delete entity;
}
}
TEST_F(SpawnableEntitiesManagerTest, ClaimEntities_DeleteTicketBeforeCall_NoCrash)
{
auto callback = [](AzFramework::EntitySpawnTicket::Id, AzFramework::SpawnableEntityContainerView) {};