From dfb2fd93b403a7f06899b457a5edf7980fcbabad Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 11 Feb 2024 12:28:25 -0800 Subject: [PATCH] chore: use ranges in EntityManager and touch up (#1451) * EntityManager: ranges and cleanup Use LWOOBJID for ghosting entities use ranges::views::values for associative container iteration remove dead code comment magic numbers little bit of optimization (not enough to be game changing or take the time to measure, they are free speedups anyways, we take those) use cstdint types * use size_t * use lwoobjid for ghost candidate --- dGame/EntityManager.cpp | 143 +++++++++++---------------- dGame/EntityManager.h | 4 +- dGame/dComponents/GhostComponent.cpp | 8 +- dGame/dComponents/GhostComponent.h | 8 +- 4 files changed, 66 insertions(+), 97 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index e1f2f46e..fc9fa0f0 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -24,6 +24,7 @@ #include "eReplicaPacketType.h" #include "PlayerManager.h" #include "GhostComponent.h" +#include // Configure which zones have ghosting disabled, mostly small worlds. std::vector EntityManager::m_GhostingExcludedZones = { @@ -165,8 +166,8 @@ void EntityManager::DestroyEntity(Entity* entity) { } void EntityManager::SerializeEntities() { - for (int32_t i = 0; i < m_EntitiesToSerialize.size(); i++) { - const LWOOBJID toSerialize = m_EntitiesToSerialize.at(i); + for (size_t i = 0; i < m_EntitiesToSerialize.size(); i++) { + const LWOOBJID toSerialize = m_EntitiesToSerialize[i]; auto* entity = GetEntity(toSerialize); if (!entity) continue; @@ -195,8 +196,8 @@ void EntityManager::SerializeEntities() { } void EntityManager::KillEntities() { - for (int32_t i = 0; i < m_EntitiesToKill.size(); i++) { - const LWOOBJID toKill = m_EntitiesToKill.at(i); + for (size_t i = 0; i < m_EntitiesToKill.size(); i++) { + const LWOOBJID toKill = m_EntitiesToKill[i]; auto* entity = GetEntity(toKill); if (!entity) { @@ -214,8 +215,8 @@ void EntityManager::KillEntities() { } void EntityManager::DeleteEntities() { - for (int32_t i = 0; i < m_EntitiesToDelete.size(); i++) { - const LWOOBJID toDelete = m_EntitiesToDelete.at(i); + for (size_t i = 0; i < m_EntitiesToDelete.size(); i++) { + const LWOOBJID toDelete = m_EntitiesToDelete[i]; auto entityToDelete = GetEntity(toDelete); if (entityToDelete) { // Get all this info first before we delete the player. @@ -238,8 +239,8 @@ void EntityManager::DeleteEntities() { } void EntityManager::UpdateEntities(const float deltaTime) { - for (const auto& e : m_Entities) { - e.second->Update(deltaTime); + for (auto* entity : m_Entities | std::views::values) { + entity->Update(deltaTime); } SerializeEntities(); @@ -259,10 +260,10 @@ Entity* EntityManager::GetEntity(const LWOOBJID& objectId) const { std::vector EntityManager::GetEntitiesInGroup(const std::string& group) { std::vector entitiesInGroup; - for (const auto& entity : m_Entities) { - for (const auto& entityGroup : entity.second->GetGroups()) { + for (auto* entity : m_Entities | std::views::values) { + for (const auto& entityGroup : entity->GetGroups()) { if (entityGroup == group) { - entitiesInGroup.push_back(entity.second); + entitiesInGroup.push_back(entity); } } } @@ -272,10 +273,12 @@ std::vector EntityManager::GetEntitiesInGroup(const std::string& group) std::vector EntityManager::GetEntitiesByComponent(const eReplicaComponentType componentType) const { std::vector withComp; - for (const auto& entity : m_Entities) { - if (componentType != eReplicaComponentType::INVALID && !entity.second->HasComponent(componentType)) continue; + if (componentType != eReplicaComponentType::INVALID) { + for (auto* entity : m_Entities | std::views::values) { + if (!entity->HasComponent(componentType)) continue; - withComp.push_back(entity.second); + withComp.push_back(entity); + } } return withComp; } @@ -283,19 +286,19 @@ std::vector EntityManager::GetEntitiesByComponent(const eReplicaCompone std::vector EntityManager::GetEntitiesByLOT(const LOT& lot) const { std::vector entities; - for (const auto& entity : m_Entities) { - if (entity.second->GetLOT() == lot) - entities.push_back(entity.second); + for (auto* entity : m_Entities | std::views::values) { + if (entity->GetLOT() == lot) entities.push_back(entity); } return entities; } -std::vector EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const{ - std::vector entities = {}; - if (radius > 1000.0f) return entities; - for (const auto& entity : m_Entities) { - if (NiPoint3::Distance(reference, entity.second->GetPosition()) <= radius) entities.push_back(entity.second); +std::vector EntityManager::GetEntitiesByProximity(NiPoint3 reference, float radius) const { + std::vector entities; + if (radius <= 1000.0f) { // The client has a 1000 unit limit on this same logic, so we'll use the same limit + for (auto* entity : m_Entities | std::views::values) { + if (NiPoint3::Distance(reference, entity->GetPosition()) <= radius) entities.push_back(entity); + } } return entities; } @@ -309,12 +312,8 @@ Entity* EntityManager::GetSpawnPointEntity(const std::string& spawnName) const { // Lookup the spawn point entity in the map const auto& spawnPoint = m_SpawnPoints.find(spawnName); - if (spawnPoint == m_SpawnPoints.end()) { - return nullptr; - } - // Check if the spawn point entity is valid just in case - return GetEntity(spawnPoint->second); + return spawnPoint == m_SpawnPoints.end() ? nullptr : GetEntity(spawnPoint->second); } const std::unordered_map& EntityManager::GetSpawnPointEntities() const { @@ -340,29 +339,25 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr entity->SetNetworkId(networkId); } - const auto checkGhosting = entity->GetIsGhostingCandidate(); - - if (checkGhosting) { - const auto& iter = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity); - - if (iter == m_EntitiesToGhost.end()) { + if (entity->GetIsGhostingCandidate()) { + if (std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entity) == m_EntitiesToGhost.end()) { m_EntitiesToGhost.push_back(entity); } - } - if (checkGhosting && sysAddr == UNASSIGNED_SYSTEM_ADDRESS) { - CheckGhosting(entity); + if (sysAddr == UNASSIGNED_SYSTEM_ADDRESS) { + CheckGhosting(entity); - return; + return; + } } m_SerializationCounter++; RakNet::BitStream stream; - stream.Write(ID_REPLICA_MANAGER_CONSTRUCTION); + stream.Write(ID_REPLICA_MANAGER_CONSTRUCTION); stream.Write(true); - stream.Write(entity->GetNetworkId()); + stream.Write(entity->GetNetworkId()); entity->WriteBaseReplicaData(&stream, eReplicaPacketType::CONSTRUCTION); entity->WriteComponents(&stream, eReplicaPacketType::CONSTRUCTION); @@ -395,9 +390,9 @@ void EntityManager::ConstructAllEntities(const SystemAddress& sysAddr) { //ZoneControl is special: ConstructEntity(m_ZoneControlEntity, sysAddr); - for (const auto& e : m_Entities) { - if (e.second && (e.second->GetSpawnerID() != 0 || e.second->GetLOT() == 1) && !e.second->GetIsGhostingCandidate()) { - ConstructEntity(e.second, sysAddr); + for (auto* entity : m_Entities | std::views::values) { + if (entity && (entity->GetSpawnerID() != 0 || entity->GetLOT() == 1) && !entity->GetIsGhostingCandidate()) { + ConstructEntity(entity, sysAddr); } } @@ -409,8 +404,8 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr) RakNet::BitStream stream; - stream.Write(ID_REPLICA_MANAGER_DESTRUCTION); - stream.Write(entity->GetNetworkId()); + stream.Write(ID_REPLICA_MANAGER_DESTRUCTION); + stream.Write(entity->GetNetworkId()); Game::server->Send(&stream, sysAddr, sysAddr == UNASSIGNED_SYSTEM_ADDRESS); @@ -431,8 +426,8 @@ void EntityManager::SerializeEntity(Entity* entity) { } void EntityManager::DestructAllEntities(const SystemAddress& sysAddr) { - for (const auto& e : m_Entities) { - DestructEntity(e.second, sysAddr); + for (auto* entity : m_Entities | std::views::values) { + DestructEntity(entity, sysAddr); } } @@ -440,22 +435,12 @@ void EntityManager::SetGhostDistanceMax(float value) { m_GhostDistanceMaxSquared = value * value; } -float EntityManager::GetGhostDistanceMax() const { - return std::sqrt(m_GhostDistanceMaxSquared); -} - void EntityManager::SetGhostDistanceMin(float value) { m_GhostDistanceMinSqaured = value * value; } -float EntityManager::GetGhostDistanceMin() const { - return std::sqrt(m_GhostDistanceMinSqaured); -} - void EntityManager::QueueGhostUpdate(LWOOBJID playerID) { - const auto& iter = std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID); - - if (iter == m_PlayersToUpdateGhosting.end()) { + if (std::find(m_PlayersToUpdateGhosting.begin(), m_PlayersToUpdateGhosting.end(), playerID) == m_PlayersToUpdateGhosting.end()) { m_PlayersToUpdateGhosting.push_back(playerID); } } @@ -475,26 +460,20 @@ void EntityManager::UpdateGhosting() { } void EntityManager::UpdateGhosting(Entity* player) { - if (player == nullptr) { - return; - } + if (!player) return; auto* missionComponent = player->GetComponent(); auto* ghostComponent = player->GetComponent(); - if (missionComponent == nullptr || !ghostComponent) { - return; - } + if (!missionComponent || !ghostComponent) return; const auto& referencePoint = ghostComponent->GetGhostReferencePoint(); const auto isOverride = ghostComponent->GetGhostOverride(); for (auto* entity : m_EntitiesToGhost) { - const auto isAudioEmitter = entity->GetLOT() == 6368; - const auto& entityPoint = entity->GetPosition(); - const int32_t id = entity->GetObjectID(); + const auto id = entity->GetObjectID(); const auto observed = ghostComponent->IsObserved(id); @@ -503,6 +482,7 @@ void EntityManager::UpdateGhosting(Entity* player) { auto ghostingDistanceMax = m_GhostDistanceMaxSquared; auto ghostingDistanceMin = m_GhostDistanceMinSqaured; + const auto isAudioEmitter = entity->GetLOT() == 6368; // https://explorer.lu/objects/6368 if (isAudioEmitter) { ghostingDistanceMax = ghostingDistanceMin; } @@ -541,30 +521,25 @@ void EntityManager::CheckGhosting(Entity* entity) { const auto& referencePoint = entity->GetPosition(); - auto ghostingDistanceMax = m_GhostDistanceMaxSquared; - auto ghostingDistanceMin = m_GhostDistanceMinSqaured; - - const auto isAudioEmitter = entity->GetLOT() == 6368; - for (auto* player : PlayerManager::GetAllPlayers()) { auto* ghostComponent = player->GetComponent(); if (!ghostComponent) continue; const auto& entityPoint = ghostComponent->GetGhostReferencePoint(); - const int32_t id = entity->GetObjectID(); + const auto id = entity->GetObjectID(); const auto observed = ghostComponent->IsObserved(id); const auto distance = NiPoint3::DistanceSquared(referencePoint, entityPoint); - if (observed && distance > ghostingDistanceMax) { + if (observed && distance > m_GhostDistanceMaxSquared) { ghostComponent->GhostEntity(id); DestructEntity(entity, player->GetSystemAddress()); entity->SetObservers(entity->GetObservers() - 1); - } else if (!observed && ghostingDistanceMin > distance) { + } else if (!observed && m_GhostDistanceMinSqaured > distance) { ghostComponent->ObserveEntity(id); ConstructEntity(entity, player->GetSystemAddress()); @@ -574,7 +549,7 @@ void EntityManager::CheckGhosting(Entity* entity) { } } -Entity* EntityManager::GetGhostCandidate(int32_t id) { +Entity* EntityManager::GetGhostCandidate(LWOOBJID id) const { for (auto* entity : m_EntitiesToGhost) { if (entity->GetObjectID() == id) { return entity; @@ -600,26 +575,22 @@ void EntityManager::ScheduleForKill(Entity* entity) { const auto objectId = entity->GetObjectID(); - if (std::count(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId)) { - return; + if (std::find(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId) != m_EntitiesToKill.end()) { + m_EntitiesToKill.push_back(objectId); } - - m_EntitiesToKill.push_back(objectId); } void EntityManager::ScheduleForDeletion(LWOOBJID entity) { - if (std::count(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity)) { - return; + if (std::find(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity) != m_EntitiesToDelete.end()) { + m_EntitiesToDelete.push_back(entity); } - - m_EntitiesToDelete.push_back(entity); } void EntityManager::FireEventServerSide(Entity* origin, std::string args) { - for (std::pair e : m_Entities) { - if (e.second) { - e.second->OnFireEventServerSide(origin, args); + for (const auto entity : m_Entities | std::views::values) { + if (entity) { + entity->OnFireEventServerSide(origin, args); } } } diff --git a/dGame/EntityManager.h b/dGame/EntityManager.h index 352b927b..abffe546 100644 --- a/dGame/EntityManager.h +++ b/dGame/EntityManager.h @@ -50,14 +50,12 @@ public: void DestructAllEntities(const SystemAddress& sysAddr); void SetGhostDistanceMax(float value); - float GetGhostDistanceMax() const; void SetGhostDistanceMin(float value); - float GetGhostDistanceMin() const; void QueueGhostUpdate(LWOOBJID playerID); void UpdateGhosting(); void UpdateGhosting(Entity* player); void CheckGhosting(Entity* entity); - Entity* GetGhostCandidate(int32_t id); + Entity* GetGhostCandidate(LWOOBJID id) const; bool GetGhostingEnabled() const; void ScheduleForKill(Entity* entity); diff --git a/dGame/dComponents/GhostComponent.cpp b/dGame/dComponents/GhostComponent.cpp index db12ce4d..3aea329a 100644 --- a/dGame/dComponents/GhostComponent.cpp +++ b/dGame/dComponents/GhostComponent.cpp @@ -8,7 +8,7 @@ GhostComponent::GhostComponent(Entity* parent) : Component(parent) { GhostComponent::~GhostComponent() { for (auto& observedEntity : m_ObservedEntities) { - if (observedEntity == 0) continue; + if (observedEntity == LWOOBJID_EMPTY) continue; auto* entity = Game::entityManager->GetGhostCandidate(observedEntity); if (!entity) continue; @@ -44,14 +44,14 @@ void GhostComponent::ConstructLimboEntities() { m_LimboConstructions.clear(); } -void GhostComponent::ObserveEntity(int32_t id) { +void GhostComponent::ObserveEntity(LWOOBJID id) { m_ObservedEntities.insert(id); } -bool GhostComponent::IsObserved(int32_t id) { +bool GhostComponent::IsObserved(LWOOBJID id) { return m_ObservedEntities.contains(id); } -void GhostComponent::GhostEntity(int32_t id) { +void GhostComponent::GhostEntity(LWOOBJID id) { m_ObservedEntities.erase(id); } diff --git a/dGame/dComponents/GhostComponent.h b/dGame/dComponents/GhostComponent.h index bc4f158d..de0fb886 100644 --- a/dGame/dComponents/GhostComponent.h +++ b/dGame/dComponents/GhostComponent.h @@ -33,18 +33,18 @@ public: void ConstructLimboEntities(); - void ObserveEntity(const int32_t id); + void ObserveEntity(const LWOOBJID id); - bool IsObserved(const int32_t id); + bool IsObserved(const LWOOBJID id); - void GhostEntity(const int32_t id); + void GhostEntity(const LWOOBJID id); private: NiPoint3 m_GhostReferencePoint; NiPoint3 m_GhostOverridePoint; - std::unordered_set m_ObservedEntities; + std::unordered_set m_ObservedEntities; std::unordered_set m_LimboConstructions;