Пример #1
0
std::set<Entity*> EntityManager::getEntities(const Filter& filter)
{
	std::set<Entity*> entities;
	if (!filter.getOne().empty())
	{
		for (auto& iter : filter.getOne())
			getEntities(iter, entities);
	}
	if (!filter.getAll().empty())
	{
		auto iter = filter.getAll().begin();
		Type typeId = *iter;
		std::set<Entity*> suspects;
		getEntities(typeId, suspects);
		if (!suspects.empty())
		{
			iter++;
			for (; iter != filter.getAll().end(); ++iter)
			{
				typeId = *iter;
				std::set<Entity*> ents;
				getEntities(typeId, ents);
				if (ents.empty())
				{
					suspects.clear();
					break;
				}
				std::set<Entity*> newSuspects;
				for (auto& siter : suspects)
				{
					if (ents.find(siter) != ents.end())
						newSuspects.insert(siter);
				}
				suspects = newSuspects;
			}
		}
		// if there's no "one of" requirement, add all these entities
		if (filter.getOne().empty())
			entities = suspects;
		else
		{
			std::set<Entity*> newEntities;
			// otherwise, we have to check that the entity exists in both sets
			for (auto iter = entities.begin(); iter != entities.end(); ++iter)
			{
				if (suspects.end() != suspects.find(*iter))
					newEntities.insert(*iter);
			}
			entities = newEntities;
		}
	}
	if (!filter.getExcept().empty())
	{
		std::set<Entity*> excluded;
		// add all entities that don't have those things in
		for (auto iter = m_componentTypeToEntities.begin(); iter != m_componentTypeToEntities.end(); ++iter)
		{
			for (auto fIter = filter.getExcept().begin(); fIter != filter.getExcept().end(); ++fIter)
			{
				if (fIter->isDerivedFrom(iter->first))
					excluded.insert(iter->second.begin(), iter->second.end());
			}
		}
		if (filter.getAll().empty() && filter.getOne().empty())
			entities = excluded;
		else
		{
			std::set<Entity*> newEntities;
			// otherwise, we have to check that the entity exists in both sets
			for (auto iter = entities.begin(); iter != entities.end(); ++iter)
			{
				if (excluded.end() != excluded.find(*iter))
					newEntities.insert(*iter);
			}
			entities = newEntities;
		}
	}
	return entities;
}