Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/simulation2/system/ComponentManager.cpp
/* Copyright (C) 2018 Wildfire Games. | /* Copyright (C) 2019 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
▲ Show 20 Lines • Show All 801 Lines • ▼ Show 20 Lines | void CComponentManager::AddMockComponent(CEntityHandle ent, InterfaceId iid, IComponent& component) | ||||
SEntityComponentCache* cache = ent.GetComponentCache(); | SEntityComponentCache* cache = ent.GetComponentCache(); | ||||
ENSURE(cache != NULL && iid < (int)cache->numInterfaces && cache->interfaces[iid] == NULL); | ENSURE(cache != NULL && iid < (int)cache->numInterfaces && cache->interfaces[iid] == NULL); | ||||
cache->interfaces[iid] = &component; | cache->interfaces[iid] = &component; | ||||
} | } | ||||
CEntityHandle CComponentManager::AllocateEntityHandle(entity_id_t ent) | CEntityHandle CComponentManager::AllocateEntityHandle(entity_id_t ent) | ||||
{ | { | ||||
ENSURE(!EntityExists(ent)); | |||||
// Interface IDs start at 1, and SEntityComponentCache is defined with a 1-sized array, | // Interface IDs start at 1, and SEntityComponentCache is defined with a 1-sized array, | ||||
// so we need space for an extra m_InterfaceIdsByName.size() items | // so we need space for an extra m_InterfaceIdsByName.size() items | ||||
SEntityComponentCache* cache = (SEntityComponentCache*)calloc(1, | SEntityComponentCache* cache = (SEntityComponentCache*)calloc(1, | ||||
sizeof(SEntityComponentCache) + sizeof(IComponent*) * m_InterfaceIdsByName.size()); | sizeof(SEntityComponentCache) + sizeof(IComponent*) * m_InterfaceIdsByName.size()); | ||||
ENSURE(cache != NULL); | ENSURE(cache != NULL); | ||||
cache->numInterfaces = m_InterfaceIdsByName.size() + 1; | cache->numInterfaces = m_InterfaceIdsByName.size() + 1; | ||||
ENSURE(m_ComponentCaches.find(ent) == m_ComponentCaches.end()); | |||||
m_ComponentCaches[ent] = cache; | m_ComponentCaches[ent] = cache; | ||||
return CEntityHandle(ent, cache); | return CEntityHandle(ent, cache); | ||||
} | } | ||||
CEntityHandle CComponentManager::LookupEntityHandle(entity_id_t ent, bool allowCreate) | CEntityHandle CComponentManager::LookupEntityHandle(entity_id_t ent, bool allowCreate) | ||||
{ | { | ||||
std::unordered_map<entity_id_t, SEntityComponentCache*>::iterator it; | std::unordered_map<entity_id_t, SEntityComponentCache*>::iterator it; | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | entity_id_t CComponentManager::AddEntity(const std::wstring& templateName, entity_id_t ent) | ||||
} | } | ||||
CMessageCreate msg(ent); | CMessageCreate msg(ent); | ||||
PostMessage(ent, msg); | PostMessage(ent, msg); | ||||
return ent; | return ent; | ||||
} | } | ||||
bool CComponentManager::EntityExists(entity_id_t ent) const | |||||
{ | |||||
return m_ComponentCaches.find(ent) != m_ComponentCaches.end(); | |||||
} | |||||
void CComponentManager::DestroyComponentsSoon(entity_id_t ent) | void CComponentManager::DestroyComponentsSoon(entity_id_t ent) | ||||
{ | { | ||||
m_DestructionQueue.push_back(ent); | m_DestructionQueue.push_back(ent); | ||||
} | } | ||||
void CComponentManager::FlushDestroyedComponents() | void CComponentManager::FlushDestroyedComponents() | ||||
{ | { | ||||
PROFILE2("Flush Destroyed Components"); | PROFILE2("Flush Destroyed Components"); | ||||
while (!m_DestructionQueue.empty()) | while (!m_DestructionQueue.empty()) | ||||
{ | { | ||||
// Make a copy of the destruction queue, so that the iterators won't be invalidated if the | // Make a copy of the destruction queue, so that the iterators won't be invalidated if the | ||||
// CMessageDestroy handlers try to destroy more entities themselves | // CMessageDestroy handlers try to destroy more entities themselves | ||||
std::vector<entity_id_t> queue; | std::vector<entity_id_t> queue; | ||||
queue.swap(m_DestructionQueue); | queue.swap(m_DestructionQueue); | ||||
for (std::vector<entity_id_t>::iterator it = queue.begin(); it != queue.end(); ++it) | for (std::vector<entity_id_t>::iterator it = queue.begin(); it != queue.end(); ++it) | ||||
{ | { | ||||
entity_id_t ent = *it; | entity_id_t ent = *it; | ||||
// Do nothing if invalid, destroyed, etc. | |||||
if (!EntityExists(ent)) | |||||
continue; | |||||
elexis: (possibly ENSURE) | |||||
CEntityHandle handle = LookupEntityHandle(ent); | CEntityHandle handle = LookupEntityHandle(ent); | ||||
CMessageDestroy msg(ent); | CMessageDestroy msg(ent); | ||||
PostMessage(ent, msg); | PostMessage(ent, msg); | ||||
// Flatten all the dynamic subscriptions to ensure there are no dangling | // Flatten all the dynamic subscriptions to ensure there are no dangling | ||||
// references in the 'removed' lists to components we're going to delete | // references in the 'removed' lists to components we're going to delete | ||||
// Some components may have dynamically unsubscribed following the Destroy message | // Some components may have dynamically unsubscribed following the Destroy message | ||||
▲ Show 20 Lines • Show All 252 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator
(possibly ENSURE)