From 5523b6aafc346f1e368682badda9b4fe49279e84 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Thu, 21 Jul 2022 21:09:25 -0500 Subject: [PATCH] Refactor UpdateEntities to not lose items if we add them while processing (#664) * if we are deleting entities, and we add an entity to delete, dont throw it out * made it all uniform * change update back to how it was since it's an unordere map and wouldn't be guaranteed to update even in this secnario --- dGame/EntityManager.cpp | 125 +++++++++++++++------------------------- 1 file changed, 48 insertions(+), 77 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index da0cf685..d6e6256f 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -74,7 +74,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE // For non player entites, we'll generate a new ID or set the appropiate flags else if (user == nullptr || info.lot != 1) { - + // Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID if (info.id == 0) { id = ObjectIDManager::Instance()->GenerateObjectID(); @@ -104,7 +104,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE } info.id = id; - + Entity* entity; // Check if the entitty if a player, in case use the extended player entity class @@ -117,7 +117,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE // Initialize the entity entity->Initialize(); - + // Add the entity to the entity map m_Entities.insert_or_assign(id, entity); @@ -162,110 +162,81 @@ void EntityManager::DestroyEntity(Entity* entity) { void EntityManager::UpdateEntities(const float deltaTime) { for (const auto& e : m_Entities) { - e.second->Update(deltaTime); + e.second->Update(deltaTime); } - for (const auto entityId : m_EntitiesToSerialize) - { - auto* entity = GetEntity(entityId); + for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) { + auto* entity = GetEntity(*entry); if (entity == nullptr) continue; m_SerializationCounter++; RakNet::BitStream stream; - stream.Write(static_cast(ID_REPLICA_MANAGER_SERIALIZE)); stream.Write(static_cast(entity->GetNetworkId())); entity->WriteBaseReplicaData(&stream, PACKET_TYPE_SERIALIZATION); entity->WriteComponents(&stream, PACKET_TYPE_SERIALIZATION); - if (entity->GetIsGhostingCandidate()) - { - for (auto* player : Player::GetAllPlayers()) - { - if (player->IsObserved(entityId)) - { + if (entity->GetIsGhostingCandidate()) { + for (auto* player : Player::GetAllPlayers()) { + if (player->IsObserved(*entry)) { Game::server->Send(&stream, player->GetSystemAddress(), false); } } - } - else - { + } else { Game::server->Send(&stream, UNASSIGNED_SYSTEM_ADDRESS, true); } } - m_EntitiesToSerialize.clear(); - for (const auto& entry : m_EntitiesToKill) - { - auto* entity = GetEntity(entry); + for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) { + auto* entity = GetEntity(*entry); if (!entity) continue; - if (entity->GetScheduledKiller()) - { + if (entity->GetScheduledKiller()) { entity->Smash(entity->GetScheduledKiller()->GetObjectID(), SILENT); - } - else - { - entity->Smash(LWOOBJID_EMPTY, SILENT); + } else { + entity->Smash(LWOOBJID_EMPTY, SILENT); } } - m_EntitiesToKill.clear(); - for (const auto entry : m_EntitiesToDelete) - { + for (auto entry = m_EntitiesToDelete.begin(); entry != m_EntitiesToDelete.end(); entry++) { + // Get all this info first before we delete the player. - auto entityToDelete = GetEntity(entry); - + auto entityToDelete = GetEntity(*entry); auto networkIdToErase = entityToDelete->GetNetworkId(); - const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); - if (entityToDelete) - { + if (entityToDelete) { // If we are a player run through the player destructor. - if (entityToDelete->IsPlayer()) - { + if (entityToDelete->IsPlayer()) { delete dynamic_cast(entityToDelete); - } - else - { + } else { delete entityToDelete; } - entityToDelete = nullptr; - - if (networkIdToErase != 0) - { - m_LostNetworkIds.push(networkIdToErase); - } + if (networkIdToErase != 0) m_LostNetworkIds.push(networkIdToErase); } - if (ghostingToDelete != m_EntitiesToGhost.end()) - { - m_EntitiesToGhost.erase(ghostingToDelete); - } + if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete); - m_Entities.erase(entry); - + m_Entities.erase(*entry); } - m_EntitiesToDelete.clear(); } Entity * EntityManager::GetEntity(const LWOOBJID& objectId) const { const auto& index = m_Entities.find(objectId); - + if (index == m_Entities.end()) { return nullptr; } - + return index->second; } @@ -286,7 +257,7 @@ std::vector EntityManager::GetEntitiesByComponent(const int componentTy std::vector withComp; for (const auto& entity : m_Entities) { if (componentType != -1 && !entity.second->HasComponent(componentType)) continue; - + withComp.push_back(entity.second); } return withComp; @@ -331,7 +302,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr if (entity->GetNetworkId() == 0) { uint16_t networkId; - + if (!m_LostNetworkIds.empty()) { networkId = m_LostNetworkIds.top(); @@ -344,7 +315,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr entity->SetNetworkId(networkId); } - + const auto checkGhosting = entity->GetIsGhostingCandidate(); if (checkGhosting) @@ -365,13 +336,13 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr } m_SerializationCounter++; - + RakNet::BitStream stream; stream.Write(static_cast(ID_REPLICA_MANAGER_CONSTRUCTION)); stream.Write(true); stream.Write(static_cast(entity->GetNetworkId())); - + entity->WriteBaseReplicaData(&stream, PACKET_TYPE_CONSTRUCTION); entity->WriteComponents(&stream, PACKET_TYPE_CONSTRUCTION); @@ -430,7 +401,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) { return; } - + RakNet::BitStream stream; stream.Write(static_cast(ID_REPLICA_MANAGER_DESTRUCTION)); @@ -467,7 +438,7 @@ void EntityManager::DestructAllEntities(const SystemAddress& sysAddr) { } } -void EntityManager::SetGhostDistanceMax(float value) +void EntityManager::SetGhostDistanceMax(float value) { m_GhostDistanceMaxSquared = value * value; } @@ -477,7 +448,7 @@ float EntityManager::GetGhostDistanceMax() const return std::sqrt(m_GhostDistanceMaxSquared); } -void EntityManager::SetGhostDistanceMin(float value) +void EntityManager::SetGhostDistanceMin(float value) { m_GhostDistanceMinSqaured = value * value; } @@ -487,7 +458,7 @@ float EntityManager::GetGhostDistanceMin() const return std::sqrt(m_GhostDistanceMinSqaured); } -void EntityManager::QueueGhostUpdate(LWOOBJID playerID) +void EntityManager::QueueGhostUpdate(LWOOBJID playerID) { const auto& iter = std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID); @@ -497,7 +468,7 @@ void EntityManager::QueueGhostUpdate(LWOOBJID playerID) } } -void EntityManager::UpdateGhosting() +void EntityManager::UpdateGhosting() { for (const auto playerID : m_PlayersToUpdateGhosting) { @@ -514,7 +485,7 @@ void EntityManager::UpdateGhosting() m_PlayersToUpdateGhosting.clear(); } -void EntityManager::UpdateGhosting(Player* player) +void EntityManager::UpdateGhosting(Player* player) { if (player == nullptr) { @@ -575,15 +546,15 @@ void EntityManager::UpdateGhosting(Player* player) } player->ObserveEntity(id); - + ConstructEntity(entity, player->GetSystemAddress()); - + entity->SetObservers(entity->GetObservers() + 1); } } } -void EntityManager::CheckGhosting(Entity* entity) +void EntityManager::CheckGhosting(Entity* entity) { if (entity == nullptr) { @@ -591,7 +562,7 @@ void EntityManager::CheckGhosting(Entity* entity) } const auto& referencePoint = entity->GetPosition(); - + auto ghostingDistanceMax = m_GhostDistanceMaxSquared; auto ghostingDistanceMin = m_GhostDistanceMinSqaured; @@ -618,15 +589,15 @@ void EntityManager::CheckGhosting(Entity* entity) else if (!observed && ghostingDistanceMin > distance) { player->ObserveEntity(id); - + ConstructEntity(entity, player->GetSystemAddress()); - + entity->SetObservers(entity->GetObservers() + 1); } } } -Entity* EntityManager::GetGhostCandidate(int32_t id) +Entity* EntityManager::GetGhostCandidate(int32_t id) { for (auto* entity : m_EntitiesToGhost) { @@ -635,7 +606,7 @@ Entity* EntityManager::GetGhostCandidate(int32_t id) return entity; } } - + return nullptr; } @@ -654,7 +625,7 @@ void EntityManager::ScheduleForKill(Entity* entity) { // Deactivate switches if they die if (!entity) return; - + SwitchComponent* switchComp = entity->GetComponent(); if (switchComp) { entity->TriggerEvent("OnDectivated"); @@ -670,7 +641,7 @@ void EntityManager::ScheduleForKill(Entity* entity) { m_EntitiesToKill.push_back(objectId); } -void EntityManager::ScheduleForDeletion(LWOOBJID entity) +void EntityManager::ScheduleForDeletion(LWOOBJID entity) { if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity)) { @@ -689,7 +660,7 @@ void EntityManager::FireEventServerSide(Entity* origin, std::string args) { } } -bool EntityManager::IsExcludedFromGhosting(LOT lot) +bool EntityManager::IsExcludedFromGhosting(LOT lot) { return std::find(m_GhostingExcludedLOTs.begin(), m_GhostingExcludedLOTs.end(), lot) != m_GhostingExcludedLOTs.end(); }