Store the spawn ticket id inside entity instead of maintaining a map of entity to ticket

Signed-off-by: srikappa-amzn <srikappa@amazon.com>
This commit is contained in:
srikappa-amzn
2021-09-23 15:25:15 -07:00
parent a4af34423a
commit 3c882230ed
11 changed files with 179 additions and 192 deletions
@@ -655,6 +655,16 @@ namespace AZ
m_stateEvent.Signal(oldState, m_state);
}
void Entity::SetSpawnTicketId(u32 spawnTicketId)
{
m_spawnTicketId = AZStd::move(spawnTicketId);
}
u32 Entity::GetSpawnTicketId() const
{
return m_spawnTicketId;
}
void Entity::OnNameChanged() const
{
EBUS_EVENT_ID(GetId(), EntityBus, OnEntityNameChanged, m_name);
@@ -133,6 +133,9 @@ namespace AZ
//! @return The state of the entity. For example, the entity has been initialized, the entity is active, and so on.
State GetState() const { return m_state; }
u32 GetSpawnTicketId() const;
void SetSpawnTicketId(u32);
//! Connects an entity state event handler to the entity.
//! All state changes will be signaled through this event.
//! @param handler reference to the EntityStateEvent handler to attach to the entities state event.
@@ -411,6 +414,8 @@ namespace AZ
//! A user-friendly name for the entity. This makes error messages easier to read.
AZStd::string m_name;
u32 m_spawnTicketId = 0;
//! The state of the entity.
State m_state;
@@ -14,7 +14,7 @@
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Entity/EntityContext.h>
#include <AzFramework/Components/TransformComponent.h>
#include <AzFramework/Spawnable/SpawnedEntityTicketMapperInterface.h>
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
#include "GameEntityContextComponent.h"
@@ -290,10 +290,21 @@ namespace AzFramework
isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (isPrefabSystemEnabled)
{
SpawnedEntityTicketMapperInterface* spawnedEntityTicketMapperInterface =
AZ::Interface<SpawnedEntityTicketMapperInterface>::Get();
AZ_Assert(spawnedEntityTicketMapperInterface != nullptr, "SpawnedEntityTicketMapperInterface is not found.");
spawnedEntityTicketMapperInterface->RemoveSpawnedEntity(currentEntity->GetId());
if (currentEntity->GetSpawnTicketId() > 0)
{
SpawnableEntitiesDefinition* spawnableEntitiesInterface = SpawnableEntitiesInterface::Get();
AZ_Assert(spawnableEntitiesInterface != nullptr, "SpawnableEntitiesInterface is not found.");
spawnableEntitiesInterface->GetEntitySpawnTicket(
currentEntity->GetSpawnTicketId(),
[spawnableEntitiesInterface, currentEntity](EntitySpawnTicket* entitySpawnTicket)
{
if (entitySpawnTicket != nullptr)
{
spawnableEntitiesInterface->DespawnEntity(currentEntity->GetId(), *entitySpawnTicket);
}
});
return;
}
}
if (currentEntity->GetState() == AZ::Entity::State::Active)
@@ -227,10 +227,16 @@ namespace AzFramework
EntitySpawnTicket::EntitySpawnTicket(EntitySpawnTicket&& rhs)
: m_payload(rhs.m_payload)
, m_id(rhs.m_id)
{
auto manager = SpawnableEntitiesInterface::Get();
AZ_Assert(manager, "SpawnableEntitiesInterface has no implementation.");
rhs.m_payload = nullptr;
Id previousId = m_id;
m_id = rhs.m_id;
rhs.m_id = 0;
AZStd::scoped_lock lock(manager->m_entitySpawnTicketMapMutex);
manager->m_entitySpawnTicketMap.erase(previousId);
manager->m_entitySpawnTicketMap.insert_or_assign(rhs.m_id, this);
}
EntitySpawnTicket::EntitySpawnTicket(AZ::Data::Asset<Spawnable> spawnable)
@@ -240,6 +246,8 @@ namespace AzFramework
AZStd::pair<EntitySpawnTicket::Id, void*> result = manager->CreateTicket(AZStd::move(spawnable));
m_id = result.first;
m_payload = result.second;
AZStd::scoped_lock lock(manager->m_entitySpawnTicketMapMutex);
manager->m_entitySpawnTicketMap.insert_or_assign(m_id, this);
}
EntitySpawnTicket::~EntitySpawnTicket()
@@ -250,6 +258,8 @@ namespace AzFramework
AZ_Assert(manager, "Attempting to destroy an entity spawn ticket while the SpawnableEntitiesInterface has no implementation.");
manager->DestroyTicket(m_payload);
m_payload = nullptr;
AZStd::scoped_lock lock(manager->m_entitySpawnTicketMapMutex);
manager->m_entitySpawnTicketMap.erase(m_id);
m_id = 0;
}
}
@@ -258,17 +268,23 @@ namespace AzFramework
{
if (this != &rhs)
{
auto manager = SpawnableEntitiesInterface::Get();
AZ_Assert(manager, "Attempting to destroy an entity spawn ticket while the SpawnableEntitiesInterface has no implementation.");
if (m_payload)
{
auto manager = SpawnableEntitiesInterface::Get();
AZ_Assert(manager, "Attempting to destroy an entity spawn ticket while the SpawnableEntitiesInterface has no implementation.");
manager->DestroyTicket(m_payload);
}
Id previousId = m_id;
m_id = rhs.m_id;
rhs.m_id = 0;
m_payload = rhs.m_payload;
rhs.m_payload = nullptr;
AZStd::scoped_lock lock(manager->m_entitySpawnTicketMapMutex);
manager->m_entitySpawnTicketMap.erase(previousId);
manager->m_entitySpawnTicketMap.insert_or_assign(m_id, this);
}
return *this;
}
@@ -140,7 +140,7 @@ namespace AzFramework
public:
friend class SpawnableEntitiesDefinition;
using Id = uint64_t;
using Id = uint32_t;
EntitySpawnTicket() = default;
EntitySpawnTicket(const EntitySpawnTicket&) = delete;
@@ -162,6 +162,7 @@ namespace AzFramework
using EntitySpawnCallback = AZStd::function<void(EntitySpawnTicket::Id, SpawnableConstEntityContainerView)>;
using EntityPreInsertionCallback = AZStd::function<void(EntitySpawnTicket::Id, SpawnableEntityContainerView)>;
using EntityDespawnCallback = AZStd::function<void(EntitySpawnTicket::Id)>;
using GetEntitySpawnTicketCallback = AZStd::function<void(EntitySpawnTicket*)>;
using ReloadSpawnableCallback = AZStd::function<void(EntitySpawnTicket::Id, SpawnableConstEntityContainerView)>;
using ListEntitiesCallback = AZStd::function<void(EntitySpawnTicket::Id, SpawnableConstEntityContainerView)>;
using ListIndicesEntitiesCallback = AZStd::function<void(EntitySpawnTicket::Id, SpawnableConstIndexEntityContainerView)>;
@@ -206,12 +207,21 @@ namespace AzFramework
struct DespawnAllEntitiesOptionalArgs final
{
//! Callback that's called when despawning entities has completed. This can be triggered from a different thread than the one that
//! made the function call to despawn. The returned list of entities contains all the newly created entities.
//! made the function call to despawn.
EntityDespawnCallback m_completionCallback;
//! The priority at which this call will be executed.
SpawnablePriority m_priority { SpawnablePriority_Default };
};
struct DespawnEntityOptionalArgs final
{
//! Callback that's called when despawning entity has completed. This can be triggered from a different thread than the one that
//! made the function call to despawn.
EntityDespawnCallback m_completionCallback;
//! The priority at which this call will be executed.
SpawnablePriority m_priority{ SpawnablePriority_Default };
};
struct ReloadSpawnableOptionalArgs final
{
//! Callback that's called when respawning entities has completed. This can be triggered from a different thread than the one that
@@ -235,12 +245,6 @@ namespace AzFramework
SpawnablePriority m_priority{ SpawnablePriority_Default };
};
struct ClaimEntityOptionalArgs final
{
//! The priority at which this call will be executed.
SpawnablePriority m_priority{ SpawnablePriority_Default };
};
struct BarrierOptionalArgs final
{
//! The priority at which this call will be executed.
@@ -283,9 +287,18 @@ namespace AzFramework
EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices, SpawnEntitiesOptionalArgs optionalArgs = {}) = 0;
//! Removes all entities in the provided list from the environment.
//! @param ticket The ticket previously used to spawn entities with.
//! @param priority The priority at which this call will be executed.
//! @param optionalArgs Optional additional arguments, see DespawnAllEntitiesOptionalArgs.
virtual void DespawnAllEntities(EntitySpawnTicket& ticket, DespawnAllEntitiesOptionalArgs optionalArgs = {}) = 0;
//! Removes the entity with the provided id from the spawned list of entities.
//! @param entityId the id of entity to despawn.
//! @param ticket The ticket previously used to spawn entities with.
//! @param optionalArgs Optional additional arguments, see DespawnEntityOptionalArgs.
virtual void DespawnEntity(AZ::EntityId entityId, EntitySpawnTicket& ticket, DespawnEntityOptionalArgs optionalArgs = {}) = 0;
//! Gets the EntitySpawnTicket associated with the entitySpawnTicketId.
//! @param entitySpawnTicketId the id of EntitySpawnTicket to get.
//! @param getEntitySpawnTicketCallback The callback to execute upon fetching the ticket.
virtual void GetEntitySpawnTicket(
EntitySpawnTicket::Id entitySpawnTicketId, GetEntitySpawnTicketCallback getEntitySpawnTicketCallback) = 0;
//! Removes all entities in the provided list from the environment and reconstructs the entities from the provided spawnable.
//! @param ticket Holds the information on the entities to reload.
//! @param priority The priority at which this call will be executed.
@@ -320,8 +333,6 @@ namespace AzFramework
virtual void ClaimEntities(
EntitySpawnTicket& ticket, ClaimEntitiesCallback listCallback, ClaimEntitiesOptionalArgs optionalArgs = {}) = 0;
virtual void ClaimEntity(AZ::EntityId entityId, void* ticket, ClaimEntityOptionalArgs optionalArgs = {}) = 0;
//! Blocks until all operations made on the provided ticket before the barrier call have completed.
//! @param ticket The ticket to monitor.
//! @param completionCallback Required callback that will be called as soon as the barrier has been reached.
@@ -355,6 +366,9 @@ namespace AzFramework
{
return reinterpret_cast<const T*>(ticket->m_payload);
}
AZStd::unordered_map<EntitySpawnTicket::Id, EntitySpawnTicket*> m_entitySpawnTicketMap;
AZStd::mutex m_entitySpawnTicketMapMutex;
};
using SpawnableEntitiesInterface = AZ::Interface<SpawnableEntitiesDefinition>;
@@ -21,13 +21,13 @@
namespace AzFramework
{
template<typename T>
void SpawnableEntitiesManager::QueueRequest(Ticket* ticket, SpawnablePriority priority, T&& request)
void SpawnableEntitiesManager::QueueRequest(EntitySpawnTicket& ticket, SpawnablePriority priority, T&& request)
{
request.m_ticket = ticket;
request.m_ticket = &GetTicketPayload<Ticket>(ticket);
Queue& queue = priority <= m_highPriorityThreshold ? m_highPriorityQueue : m_regularPriorityQueue;
{
AZStd::scoped_lock queueLock(queue.m_pendingRequestMutex);
request.m_requestId = ticket->m_nextRequestId++;
request.m_requestId = GetTicketPayload<Ticket>(ticket).m_nextRequestId++;
queue.m_pendingRequest.push(AZStd::move(request));
}
}
@@ -56,7 +56,7 @@ namespace AzFramework
optionalArgs.m_serializeContext == nullptr ? m_defaultSerializeContext : optionalArgs.m_serializeContext;
queueEntry.m_completionCallback = AZStd::move(optionalArgs.m_completionCallback);
queueEntry.m_preInsertionCallback = AZStd::move(optionalArgs.m_preInsertionCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::SpawnEntities(
@@ -72,7 +72,7 @@ namespace AzFramework
queueEntry.m_completionCallback = AZStd::move(optionalArgs.m_completionCallback);
queueEntry.m_preInsertionCallback = AZStd::move(optionalArgs.m_preInsertionCallback);
queueEntry.m_referencePreviouslySpawnedEntities = optionalArgs.m_referencePreviouslySpawnedEntities;
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::DespawnAllEntities(EntitySpawnTicket& ticket, DespawnAllEntitiesOptionalArgs optionalArgs)
@@ -82,7 +82,36 @@ namespace AzFramework
DespawnAllEntitiesCommand queueEntry;
queueEntry.m_ticketId = ticket.GetId();
queueEntry.m_completionCallback = AZStd::move(optionalArgs.m_completionCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::DespawnEntity(AZ::EntityId entityId, EntitySpawnTicket& ticket, DespawnEntityOptionalArgs optionalArgs)
{
AZ_Assert(ticket.IsValid(), "Ticket provided to DespawnEntity hasn't been initialized.");
DespawnEntityCommand queueEntry;
queueEntry.m_ticketId = ticket.GetId();
queueEntry.m_entityId = entityId;
queueEntry.m_completionCallback = AZStd::move(optionalArgs.m_completionCallback);
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::GetEntitySpawnTicket(
EntitySpawnTicket::Id entitySpawnTicketId, GetEntitySpawnTicketCallback getEntitySpawnTicketCallback)
{
if (entitySpawnTicketId == 0)
{
AZ_Error("Spawnable", false, "Ticket id provided to GetEntitySpawnTicket is invalid.");
return;
}
auto entitySpawnTicketIterator = m_entitySpawnTicketMap.find(entitySpawnTicketId);
if (entitySpawnTicketIterator == m_entitySpawnTicketMap.end())
{
AZ_Error("Spawnable", false, "The EntitySpawnTicket corresponding to id '%lu' cannot be found", entitySpawnTicketId);
return;
}
getEntitySpawnTicketCallback(entitySpawnTicketIterator->second);
}
void SpawnableEntitiesManager::ReloadSpawnable(
@@ -96,7 +125,7 @@ namespace AzFramework
queueEntry.m_serializeContext =
optionalArgs.m_serializeContext == nullptr ? m_defaultSerializeContext : optionalArgs.m_serializeContext;
queueEntry.m_completionCallback = AZStd::move(optionalArgs.m_completionCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::ListEntities(
@@ -108,7 +137,7 @@ namespace AzFramework
ListEntitiesCommand queueEntry;
queueEntry.m_ticketId = ticket.GetId();
queueEntry.m_listCallback = AZStd::move(listCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::ListIndicesAndEntities(
@@ -120,7 +149,7 @@ namespace AzFramework
ListIndicesEntitiesCommand queueEntry;
queueEntry.m_ticketId = ticket.GetId();
queueEntry.m_listCallback = AZStd::move(listCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::ClaimEntities(
@@ -132,18 +161,7 @@ namespace AzFramework
ClaimEntitiesCommand queueEntry;
queueEntry.m_ticketId = ticket.GetId();
queueEntry.m_listCallback = AZStd::move(listCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::ClaimEntity(
AZ::EntityId entityId, void* ticket,
ClaimEntityOptionalArgs optionalArgs)
{
AZ_Assert(ticket == nullptr, "Ticket provided to ClaimEntity is invalid.");
ClaimEntityCommand queueEntry;
queueEntry.m_entityId = entityId;
QueueRequest(reinterpret_cast<Ticket*>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
void SpawnableEntitiesManager::Barrier(EntitySpawnTicket& ticket, BarrierCallback completionCallback, BarrierOptionalArgs optionalArgs)
@@ -154,7 +172,7 @@ namespace AzFramework
BarrierCommand queueEntry;
queueEntry.m_ticketId = ticket.GetId();
queueEntry.m_completionCallback = AZStd::move(completionCallback);
QueueRequest(&GetTicketPayload<Ticket>(ticket), optionalArgs.m_priority, AZStd::move(queueEntry));
QueueRequest(ticket, optionalArgs.m_priority, AZStd::move(queueEntry));
}
auto SpawnableEntitiesManager::ProcessQueue(CommandQueuePriority priority) -> CommandQueueStatus
@@ -234,12 +252,13 @@ namespace AzFramework
return queue.m_delayed.empty() ? CommandQueueStatus::NoCommandsLeft : CommandQueueStatus::HasCommandsLeft;
}
AZStd::pair<uint64_t, void*> SpawnableEntitiesManager::CreateTicket(AZ::Data::Asset<Spawnable>&& spawnable)
AZStd::pair<EntitySpawnTicket::Id, void*> SpawnableEntitiesManager::CreateTicket(AZ::Data::Asset<Spawnable>&& spawnable)
{
static AZStd::atomic_uint64_t idCounter { 1 };
static AZStd::atomic_uint32_t idCounter { 1 };
auto result = aznew Ticket();
result->m_spawnable = AZStd::move(spawnable);
return AZStd::make_pair<EntitySpawnTicket::Id, void*>(idCounter++, result);
}
@@ -351,7 +370,7 @@ namespace AzFramework
for (auto it = ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount; it != ticket.m_spawnedEntities.end(); ++it)
{
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
m_spawnedEntityTicketMapper.AddSpawnedEntity((*it)->GetId(), &ticket);
(*it)->SetSpawnTicketId(request.m_ticketId);
}
// Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context.
@@ -433,7 +452,7 @@ namespace AzFramework
for (auto it = ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount; it != ticket.m_spawnedEntities.end(); ++it)
{
GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, *it);
m_spawnedEntityTicketMapper.AddSpawnedEntity((*it)->GetId(), &ticket);
(*it)->SetSpawnTicketId(request.m_ticketId);
}
if (request.m_completionCallback)
@@ -460,6 +479,7 @@ namespace AzFramework
{
if (entity != nullptr)
{
entity->SetSpawnTicketId(0);
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
}
@@ -482,6 +502,39 @@ namespace AzFramework
}
}
bool SpawnableEntitiesManager::ProcessRequest(DespawnEntityCommand& request)
{
Ticket& ticket = *request.m_ticket;
if (request.m_requestId == ticket.m_currentRequestId)
{
AZStd::vector<AZ::Entity*>& spawnedEntities = request.m_ticket->m_spawnedEntities;
for (auto entityIterator = spawnedEntities.begin(); entityIterator != spawnedEntities.end(); ++entityIterator)
{
if (*entityIterator != nullptr && (*entityIterator)->GetId() == request.m_entityId)
{
(*entityIterator)->SetSpawnTicketId(0);
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, (*entityIterator)->GetId());
AZStd::iter_swap(entityIterator, spawnedEntities.rbegin());
spawnedEntities.pop_back();
break;
}
}
if (request.m_completionCallback)
{
request.m_completionCallback(request.m_ticketId);
}
ticket.m_currentRequestId++;
return true;
}
else
{
return false;
}
}
bool SpawnableEntitiesManager::ProcessRequest(ReloadSpawnableCommand& request)
{
Ticket& ticket = *request.m_ticket;
@@ -495,6 +548,7 @@ namespace AzFramework
{
if (entity != nullptr)
{
entity->SetSpawnTicketId(0);
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
}
@@ -622,29 +676,6 @@ namespace AzFramework
}
}
bool SpawnableEntitiesManager::ProcessRequest(ClaimEntityCommand& request)
{
Ticket* ticket = request.m_ticket;
if (request.m_requestId == ticket->m_currentRequestId)
{
AZStd::vector<AZ::Entity*>& spawnedEntities = ticket->m_spawnedEntities;
for (auto entityIterator = spawnedEntities.begin(); entityIterator != spawnedEntities.end(); ++entityIterator)
{
if ((*entityIterator)->GetId() == request.m_entityId)
{
AZStd::iter_swap(entityIterator, spawnedEntities.rbegin());
spawnedEntities.pop_back();
return true;
}
}
return true;
}
else
{
return false;
}
}
bool SpawnableEntitiesManager::ProcessRequest(BarrierCommand& request)
{
Ticket& ticket = *request.m_ticket;
@@ -672,6 +703,7 @@ namespace AzFramework
{
if (entity != nullptr)
{
entity->SetSpawnTicketId(0);
GameEntityContextRequestBus::Broadcast(
&GameEntityContextRequestBus::Events::DestroyGameEntity, entity->GetId());
}
@@ -16,7 +16,6 @@
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/parallel/mutex.h>
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
#include <AzFramework/Spawnable/SpawnedEntityTicketMapper.h>
namespace AZ
{
@@ -58,6 +57,9 @@ namespace AzFramework
void SpawnEntities(
EntitySpawnTicket& ticket, AZStd::vector<size_t> entityIndices, SpawnEntitiesOptionalArgs optionalArgs = {}) override;
void DespawnAllEntities(EntitySpawnTicket& ticket, DespawnAllEntitiesOptionalArgs optionalArgs = {}) override;
void DespawnEntity(AZ::EntityId entityId, EntitySpawnTicket& ticket, DespawnEntityOptionalArgs optionalArgs = {}) override;
void GetEntitySpawnTicket(
EntitySpawnTicket::Id entitySpawnTicketId, GetEntitySpawnTicketCallback getEntitySpawnTicketCallback) override;
void ReloadSpawnable(
EntitySpawnTicket& ticket, AZ::Data::Asset<Spawnable> spawnable, ReloadSpawnableOptionalArgs optionalArgs = {}) override;
@@ -67,8 +69,6 @@ namespace AzFramework
EntitySpawnTicket& ticket, ListIndicesEntitiesCallback listCallback, ListEntitiesOptionalArgs optionalArgs = {}) override;
void ClaimEntities(
EntitySpawnTicket& ticket, ClaimEntitiesCallback listCallback, ClaimEntitiesOptionalArgs optionalArgs = {}) override;
void ClaimEntity(
AZ::EntityId entityId, void* ticket, ClaimEntityOptionalArgs optionalArgs = {}) override;
void Barrier(EntitySpawnTicket& spawnInfo, BarrierCallback completionCallback, BarrierOptionalArgs optionalArgs = {}) override;
@@ -135,6 +135,14 @@ namespace AzFramework
EntitySpawnTicket::Id m_ticketId;
uint32_t m_requestId;
};
struct DespawnEntityCommand
{
EntityDespawnCallback m_completionCallback;
Ticket* m_ticket;
EntitySpawnTicket::Id m_ticketId;
uint32_t m_requestId;
AZ::EntityId m_entityId;
};
struct ReloadSpawnableCommand
{
AZ::Data::Asset<Spawnable> m_spawnable;
@@ -165,12 +173,6 @@ namespace AzFramework
EntitySpawnTicket::Id m_ticketId;
uint32_t m_requestId;
};
struct ClaimEntityCommand
{
Ticket* m_ticket;
uint32_t m_requestId;
AZ::EntityId m_entityId;
};
struct BarrierCommand
{
BarrierCallback m_completionCallback;
@@ -185,8 +187,16 @@ namespace AzFramework
};
using Requests = AZStd::variant<
SpawnAllEntitiesCommand, SpawnEntitiesCommand, DespawnAllEntitiesCommand, ReloadSpawnableCommand, ListEntitiesCommand,
ListIndicesEntitiesCommand, ClaimEntitiesCommand, ClaimEntityCommand, BarrierCommand, DestroyTicketCommand>;
SpawnAllEntitiesCommand,
SpawnEntitiesCommand,
DespawnAllEntitiesCommand,
DespawnEntityCommand,
ReloadSpawnableCommand,
ListEntitiesCommand,
ListIndicesEntitiesCommand,
ClaimEntitiesCommand,
BarrierCommand,
DestroyTicketCommand>;
struct Queue
{
@@ -196,7 +206,7 @@ namespace AzFramework
};
template<typename T>
void QueueRequest(Ticket* ticket, SpawnablePriority priority, T&& request);
void QueueRequest(EntitySpawnTicket& ticket, SpawnablePriority priority, T&& request);
AZStd::pair<EntitySpawnTicket::Id, void*> CreateTicket(AZ::Data::Asset<Spawnable>&& spawnable) override;
void DestroyTicket(void* ticket) override;
@@ -208,11 +218,11 @@ namespace AzFramework
bool ProcessRequest(SpawnAllEntitiesCommand& request);
bool ProcessRequest(SpawnEntitiesCommand& request);
bool ProcessRequest(DespawnAllEntitiesCommand& request);
bool ProcessRequest(DespawnEntityCommand& request);
bool ProcessRequest(ReloadSpawnableCommand& request);
bool ProcessRequest(ListEntitiesCommand& request);
bool ProcessRequest(ListIndicesEntitiesCommand& request);
bool ProcessRequest(ClaimEntitiesCommand& request);
bool ProcessRequest(ClaimEntityCommand& request);
bool ProcessRequest(BarrierCommand& request);
bool ProcessRequest(DestroyTicketCommand& request);
@@ -234,8 +244,6 @@ namespace AzFramework
//! SpawnablePriority_Default which gives users a bit of room to fine tune the priorities as this value can be configured
//! through the Settings Registry under the key "/O3DE/AzFramework/Spawnables/HighPriorityThreshold".
SpawnablePriority m_highPriorityThreshold { 64 };
private:
SpawnedEntityTicketMapper m_spawnedEntityTicketMapper;
};
AZ_DEFINE_ENUM_BITWISE_OPERATORS(AzFramework::SpawnableEntitiesManager::CommandQueuePriority);
@@ -1,44 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzFramework/Spawnable/SpawnableEntitiesInterface.h>
#include <AzFramework/Spawnable/SpawnedEntityTicketMapper.h>
namespace AzFramework
{
SpawnedEntityTicketMapper::SpawnedEntityTicketMapper()
{
spawnableEntitiesInterface = SpawnableEntitiesInterface::Get();
AZ_Assert(spawnableEntitiesInterface != nullptr, "SpawnableEntitiesInterface is not found.");
AZ::Interface<SpawnedEntityTicketMapperInterface>::Register(this);
}
SpawnedEntityTicketMapper::~SpawnedEntityTicketMapper()
{
AZ::Interface<SpawnedEntityTicketMapperInterface>::Unregister(this);
}
void SpawnedEntityTicketMapper::RemoveSpawnedEntity(AZ::EntityId entityId)
{
auto spawnedGameEntitiesIterator = m_spawnedEntities.find(entityId);
if (spawnedGameEntitiesIterator != m_spawnedEntities.end())
{
spawnableEntitiesInterface->ClaimEntity(
spawnedGameEntitiesIterator->first, spawnedGameEntitiesIterator->second);
m_spawnedEntities.erase(entityId);
}
}
void SpawnedEntityTicketMapper::AddSpawnedEntity(AZ::EntityId entityId, void* ticket)
{
m_spawnedEntities.emplace(entityId, ticket);
}
}
@@ -1,38 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/EntityId.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzFramework/Spawnable/SpawnedEntityTicketMapperInterface.h>
namespace AzFramework
{
class SpawnedEntityTicketMapper
: public SpawnedEntityTicketMapperInterface
{
public:
AZ_RTTI(SpawnedEntityTicketMapper, "{5C803604-E949-44F4-94A4-F835E5794C77}", SpawnedEntityTicketMapperInterface);
SpawnedEntityTicketMapper();
~SpawnedEntityTicketMapper();
//! Removes the entityId from the spawned entities map if present.
//! @param entityId The id of the entity to remove.
void RemoveSpawnedEntity(AZ::EntityId entityId) override;
//! Adds the entityId,ticket pair to the spawned entities map.
//! @param entityId The id of the entity to add.
//! @param ticket The ticket pointer to add.
void AddSpawnedEntity(AZ::EntityId entityId, void* ticket) override;
private:
SpawnableEntitiesDefinition* spawnableEntitiesInterface = nullptr;
AZStd::unordered_map<AZ::EntityId, void*> m_spawnedEntities;
};
} // namespace AzFramework
@@ -1,24 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/EntityId.h>
#include <AzCore/RTTI/RTTI.h>
namespace AzFramework
{
class SpawnedEntityTicketMapperInterface
{
public:
AZ_RTTI(SpawnedEntityTicketMapperInterface, "{D407E96B-635C-44F2-B089-084EBAB8B036}");
virtual void RemoveSpawnedEntity(AZ::EntityId entityId) = 0;
virtual void AddSpawnedEntity(AZ::EntityId entityId, void* ticket) = 0;
};
}
@@ -294,9 +294,6 @@ set(FILES
Spawnable/SpawnableMonitor.cpp
Spawnable/SpawnableSystemComponent.h
Spawnable/SpawnableSystemComponent.cpp
Spawnable/SpawnedEntityTicketMapper.h
Spawnable/SpawnedEntityTicketMapper.cpp
Spawnable/SpawnedEntityTicketMapperInterface.h
Terrain/TerrainDataRequestBus.h
Terrain/TerrainDataRequestBus.cpp
Thermal/ThermalInfo.h