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
This commit is contained in:
Aaron Kimbrell 2022-07-21 21:09:25 -05:00 committed by GitHub
parent 40a9aefb5b
commit 5523b6aafc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 // For non player entites, we'll generate a new ID or set the appropiate flags
else if (user == nullptr || info.lot != 1) { else if (user == nullptr || info.lot != 1) {
// Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID // Entities with no ID already set, often spawned entities, we'll generate a new sequencial ID
if (info.id == 0) { if (info.id == 0) {
id = ObjectIDManager::Instance()->GenerateObjectID(); id = ObjectIDManager::Instance()->GenerateObjectID();
@ -104,7 +104,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE
} }
info.id = id; info.id = id;
Entity* entity; Entity* entity;
// Check if the entitty if a player, in case use the extended player entity class // 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 // Initialize the entity
entity->Initialize(); entity->Initialize();
// Add the entity to the entity map // Add the entity to the entity map
m_Entities.insert_or_assign(id, entity); m_Entities.insert_or_assign(id, entity);
@ -162,110 +162,81 @@ void EntityManager::DestroyEntity(Entity* entity) {
void EntityManager::UpdateEntities(const float deltaTime) { void EntityManager::UpdateEntities(const float deltaTime) {
for (const auto& e : m_Entities) { for (const auto& e : m_Entities) {
e.second->Update(deltaTime); e.second->Update(deltaTime);
} }
for (const auto entityId : m_EntitiesToSerialize) for (auto entry = m_EntitiesToSerialize.begin(); entry != m_EntitiesToSerialize.end(); entry++) {
{ auto* entity = GetEntity(*entry);
auto* entity = GetEntity(entityId);
if (entity == nullptr) continue; if (entity == nullptr) continue;
m_SerializationCounter++; m_SerializationCounter++;
RakNet::BitStream stream; RakNet::BitStream stream;
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_SERIALIZE)); stream.Write(static_cast<char>(ID_REPLICA_MANAGER_SERIALIZE));
stream.Write(static_cast<unsigned short>(entity->GetNetworkId())); stream.Write(static_cast<unsigned short>(entity->GetNetworkId()));
entity->WriteBaseReplicaData(&stream, PACKET_TYPE_SERIALIZATION); entity->WriteBaseReplicaData(&stream, PACKET_TYPE_SERIALIZATION);
entity->WriteComponents(&stream, PACKET_TYPE_SERIALIZATION); entity->WriteComponents(&stream, PACKET_TYPE_SERIALIZATION);
if (entity->GetIsGhostingCandidate()) if (entity->GetIsGhostingCandidate()) {
{ for (auto* player : Player::GetAllPlayers()) {
for (auto* player : Player::GetAllPlayers()) if (player->IsObserved(*entry)) {
{
if (player->IsObserved(entityId))
{
Game::server->Send(&stream, player->GetSystemAddress(), false); Game::server->Send(&stream, player->GetSystemAddress(), false);
} }
} }
} } else {
else
{
Game::server->Send(&stream, UNASSIGNED_SYSTEM_ADDRESS, true); Game::server->Send(&stream, UNASSIGNED_SYSTEM_ADDRESS, true);
} }
} }
m_EntitiesToSerialize.clear(); m_EntitiesToSerialize.clear();
for (const auto& entry : m_EntitiesToKill) for (auto entry = m_EntitiesToKill.begin(); entry != m_EntitiesToKill.end(); entry++) {
{ auto* entity = GetEntity(*entry);
auto* entity = GetEntity(entry);
if (!entity) continue; if (!entity) continue;
if (entity->GetScheduledKiller()) if (entity->GetScheduledKiller()) {
{
entity->Smash(entity->GetScheduledKiller()->GetObjectID(), SILENT); entity->Smash(entity->GetScheduledKiller()->GetObjectID(), SILENT);
} } else {
else entity->Smash(LWOOBJID_EMPTY, SILENT);
{
entity->Smash(LWOOBJID_EMPTY, SILENT);
} }
} }
m_EntitiesToKill.clear(); 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. // Get all this info first before we delete the player.
auto entityToDelete = GetEntity(entry); auto entityToDelete = GetEntity(*entry);
auto networkIdToErase = entityToDelete->GetNetworkId(); auto networkIdToErase = entityToDelete->GetNetworkId();
const auto& ghostingToDelete = std::find(m_EntitiesToGhost.begin(), m_EntitiesToGhost.end(), entityToDelete); 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 we are a player run through the player destructor.
if (entityToDelete->IsPlayer()) if (entityToDelete->IsPlayer()) {
{
delete dynamic_cast<Player*>(entityToDelete); delete dynamic_cast<Player*>(entityToDelete);
} } else {
else
{
delete entityToDelete; delete entityToDelete;
} }
entityToDelete = nullptr; entityToDelete = nullptr;
if (networkIdToErase != 0) m_LostNetworkIds.push(networkIdToErase);
if (networkIdToErase != 0)
{
m_LostNetworkIds.push(networkIdToErase);
}
} }
if (ghostingToDelete != m_EntitiesToGhost.end()) if (ghostingToDelete != m_EntitiesToGhost.end()) m_EntitiesToGhost.erase(ghostingToDelete);
{
m_EntitiesToGhost.erase(ghostingToDelete);
}
m_Entities.erase(entry); m_Entities.erase(*entry);
} }
m_EntitiesToDelete.clear(); m_EntitiesToDelete.clear();
} }
Entity * EntityManager::GetEntity(const LWOOBJID& objectId) const { Entity * EntityManager::GetEntity(const LWOOBJID& objectId) const {
const auto& index = m_Entities.find(objectId); const auto& index = m_Entities.find(objectId);
if (index == m_Entities.end()) if (index == m_Entities.end())
{ {
return nullptr; return nullptr;
} }
return index->second; return index->second;
} }
@ -286,7 +257,7 @@ std::vector<Entity*> EntityManager::GetEntitiesByComponent(const int componentTy
std::vector<Entity*> withComp; std::vector<Entity*> withComp;
for (const auto& entity : m_Entities) { for (const auto& entity : m_Entities) {
if (componentType != -1 && !entity.second->HasComponent(componentType)) continue; if (componentType != -1 && !entity.second->HasComponent(componentType)) continue;
withComp.push_back(entity.second); withComp.push_back(entity.second);
} }
return withComp; return withComp;
@ -331,7 +302,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
if (entity->GetNetworkId() == 0) if (entity->GetNetworkId() == 0)
{ {
uint16_t networkId; uint16_t networkId;
if (!m_LostNetworkIds.empty()) if (!m_LostNetworkIds.empty())
{ {
networkId = m_LostNetworkIds.top(); networkId = m_LostNetworkIds.top();
@ -344,7 +315,7 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
entity->SetNetworkId(networkId); entity->SetNetworkId(networkId);
} }
const auto checkGhosting = entity->GetIsGhostingCandidate(); const auto checkGhosting = entity->GetIsGhostingCandidate();
if (checkGhosting) if (checkGhosting)
@ -365,13 +336,13 @@ void EntityManager::ConstructEntity(Entity* entity, const SystemAddress& sysAddr
} }
m_SerializationCounter++; m_SerializationCounter++;
RakNet::BitStream stream; RakNet::BitStream stream;
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_CONSTRUCTION)); stream.Write(static_cast<char>(ID_REPLICA_MANAGER_CONSTRUCTION));
stream.Write(true); stream.Write(true);
stream.Write(static_cast<unsigned short>(entity->GetNetworkId())); stream.Write(static_cast<unsigned short>(entity->GetNetworkId()));
entity->WriteBaseReplicaData(&stream, PACKET_TYPE_CONSTRUCTION); entity->WriteBaseReplicaData(&stream, PACKET_TYPE_CONSTRUCTION);
entity->WriteComponents(&stream, PACKET_TYPE_CONSTRUCTION); entity->WriteComponents(&stream, PACKET_TYPE_CONSTRUCTION);
@ -430,7 +401,7 @@ void EntityManager::DestructEntity(Entity* entity, const SystemAddress& sysAddr)
{ {
return; return;
} }
RakNet::BitStream stream; RakNet::BitStream stream;
stream.Write(static_cast<char>(ID_REPLICA_MANAGER_DESTRUCTION)); stream.Write(static_cast<char>(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; m_GhostDistanceMaxSquared = value * value;
} }
@ -477,7 +448,7 @@ float EntityManager::GetGhostDistanceMax() const
return std::sqrt(m_GhostDistanceMaxSquared); return std::sqrt(m_GhostDistanceMaxSquared);
} }
void EntityManager::SetGhostDistanceMin(float value) void EntityManager::SetGhostDistanceMin(float value)
{ {
m_GhostDistanceMinSqaured = value * value; m_GhostDistanceMinSqaured = value * value;
} }
@ -487,7 +458,7 @@ float EntityManager::GetGhostDistanceMin() const
return std::sqrt(m_GhostDistanceMinSqaured); 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); 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) for (const auto playerID : m_PlayersToUpdateGhosting)
{ {
@ -514,7 +485,7 @@ void EntityManager::UpdateGhosting()
m_PlayersToUpdateGhosting.clear(); m_PlayersToUpdateGhosting.clear();
} }
void EntityManager::UpdateGhosting(Player* player) void EntityManager::UpdateGhosting(Player* player)
{ {
if (player == nullptr) if (player == nullptr)
{ {
@ -575,15 +546,15 @@ void EntityManager::UpdateGhosting(Player* player)
} }
player->ObserveEntity(id); player->ObserveEntity(id);
ConstructEntity(entity, player->GetSystemAddress()); ConstructEntity(entity, player->GetSystemAddress());
entity->SetObservers(entity->GetObservers() + 1); entity->SetObservers(entity->GetObservers() + 1);
} }
} }
} }
void EntityManager::CheckGhosting(Entity* entity) void EntityManager::CheckGhosting(Entity* entity)
{ {
if (entity == nullptr) if (entity == nullptr)
{ {
@ -591,7 +562,7 @@ void EntityManager::CheckGhosting(Entity* entity)
} }
const auto& referencePoint = entity->GetPosition(); const auto& referencePoint = entity->GetPosition();
auto ghostingDistanceMax = m_GhostDistanceMaxSquared; auto ghostingDistanceMax = m_GhostDistanceMaxSquared;
auto ghostingDistanceMin = m_GhostDistanceMinSqaured; auto ghostingDistanceMin = m_GhostDistanceMinSqaured;
@ -618,15 +589,15 @@ void EntityManager::CheckGhosting(Entity* entity)
else if (!observed && ghostingDistanceMin > distance) else if (!observed && ghostingDistanceMin > distance)
{ {
player->ObserveEntity(id); player->ObserveEntity(id);
ConstructEntity(entity, player->GetSystemAddress()); ConstructEntity(entity, player->GetSystemAddress());
entity->SetObservers(entity->GetObservers() + 1); entity->SetObservers(entity->GetObservers() + 1);
} }
} }
} }
Entity* EntityManager::GetGhostCandidate(int32_t id) Entity* EntityManager::GetGhostCandidate(int32_t id)
{ {
for (auto* entity : m_EntitiesToGhost) for (auto* entity : m_EntitiesToGhost)
{ {
@ -635,7 +606,7 @@ Entity* EntityManager::GetGhostCandidate(int32_t id)
return entity; return entity;
} }
} }
return nullptr; return nullptr;
} }
@ -654,7 +625,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
// Deactivate switches if they die // Deactivate switches if they die
if (!entity) if (!entity)
return; return;
SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>(); SwitchComponent* switchComp = entity->GetComponent<SwitchComponent>();
if (switchComp) { if (switchComp) {
entity->TriggerEvent("OnDectivated"); entity->TriggerEvent("OnDectivated");
@ -670,7 +641,7 @@ void EntityManager::ScheduleForKill(Entity* entity) {
m_EntitiesToKill.push_back(objectId); 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)) 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(); return std::find(m_GhostingExcludedLOTs.begin(), m_GhostingExcludedLOTs.end(), lot) != m_GhostingExcludedLOTs.end();
} }