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
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<char>(ID_REPLICA_MANAGER_SERIALIZE));
stream.Write(static_cast<unsigned short>(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<Player*>(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<Entity*> EntityManager::GetEntitiesByComponent(const int componentTy
std::vector<Entity*> 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<char>(ID_REPLICA_MANAGER_CONSTRUCTION));
stream.Write(true);
stream.Write(static_cast<unsigned short>(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<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;
}
@ -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<SwitchComponent>();
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();
}