예제 #1
0
void CComponentManager::FlushDestroyedComponents()
{
	PROFILE2("Flush Destroyed Components");
	while (!m_DestructionQueue.empty())
	{
		// 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
		std::vector<entity_id_t> queue;
		queue.swap(m_DestructionQueue);

		// Flatten all the dynamic subscriptions to ensure there are no dangling
		// references in the 'removed' lists to components we're going to delete
		FlattenDynamicSubscriptions();

		for (std::vector<entity_id_t>::iterator it = queue.begin(); it != queue.end(); ++it)
		{
			entity_id_t ent = *it;
			CEntityHandle handle = LookupEntityHandle(ent);

			CMessageDestroy msg(ent);
			PostMessage(ent, msg);

			// Destroy the components, and remove from m_ComponentsByTypeId:
			std::map<ComponentTypeId, std::map<entity_id_t, IComponent*> >::iterator iit = m_ComponentsByTypeId.begin();
			for (; iit != m_ComponentsByTypeId.end(); ++iit)
			{
				std::map<entity_id_t, IComponent*>::iterator eit = iit->second.find(ent);
				if (eit != iit->second.end())
				{
					eit->second->Deinit();
					RemoveComponentDynamicSubscriptions(eit->second);
					m_ComponentTypesById[iit->first].dealloc(eit->second);
					iit->second.erase(ent);
					handle.GetComponentCache()->interfaces[m_ComponentTypesById[iit->first].iid] = NULL;
				}
			}

			free(handle.GetComponentCache());
			m_ComponentCaches.erase(ent);

			// Remove from m_ComponentsByInterface
			std::vector<boost::unordered_map<entity_id_t, IComponent*> >::iterator ifcit = m_ComponentsByInterface.begin();
			for (; ifcit != m_ComponentsByInterface.end(); ++ifcit)
			{
				ifcit->erase(ent);
			}
		}
	}
}
예제 #2
0
void CComponentManager::AddMockComponent(CEntityHandle ent, InterfaceId iid, IComponent& component)
{
	// Just add it into the by-interface map, not the by-component-type map,
	// so it won't be considered for messages or deletion etc

	boost::unordered_map<entity_id_t, IComponent*>& emap1 = m_ComponentsByInterface.at(iid);
	if (emap1.find(ent.GetId()) != emap1.end())
		debug_warn(L"Multiple components for interface");
	emap1.insert(std::make_pair(ent.GetId(), &component));

	SEntityComponentCache* cache = ent.GetComponentCache();
	ENSURE(cache != NULL && iid < (int)cache->numInterfaces && cache->interfaces[iid] == NULL);
	cache->interfaces[iid] = &component;
}