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; }