#pragma once #include #include #include #include #include #include #include template class Compare> class DereferenceCompare { Compare comp; public: bool operator()(const Tp *const a, const Tp *const b) const { return comp(*a, *b); } }; class GameDatabase { public: GameDatabase() = default; /// вставляет в базу объект с именем [name] и позицией [x, y] /// если объект с таким id в базе уже есть, заменяет его новым void Insert(ObjectId id, std::string name, size_t x, size_t y) { GameObject *newGameObject = new GameObject{id, name, x, y}; this->byId[id] = newGameObject; this->byName[name].insert(newGameObject); this->byPos[std::pair(x, y)].insert(newGameObject); } /// удаляет элемент по id /// если такого элемента нет, ничего не делает void Remove(ObjectId id) { if (this->byId.find(id) != this->byId.end()) { GameObject* tmp = this->byId[id]; this->byId.erase(id); this->byPos.find(std::pair(tmp->x, tmp->y))->second.erase(tmp); this->byName.find(tmp->name)->second.erase(tmp); } } /// возвращает вектор объектов c именем [name] /// сортировка по убыванию id std::vector DataByName(std::string name) const { std::vector ans; if (this->byName.find(name) != this->byName.end()) { for (auto it : this->byName.at(name)) { ans.push_back(*it); } } return ans; } /// возвращает вектор объектов, находящихся в позиции [x, y] /// сортировка по убыванию id std::vector DataByPosition(size_t x, size_t y) const { std::vector ans; if (this->byPos.find(std::pair(x, y)) != this->byPos.end()) { for (auto it : this->byPos.at(std::pair(x, y))) { ans.push_back(*it); } } return ans; } /// возвращает вектор всех объектов из базы /// сортировка по убыванию id std::vector Data() const { std::vector ans; for (auto it : this->byId) { ans.push_back(*it.second); } return ans; } private: /// быстрый доступ по id std::map> byId; /// быстрый доступ по позиции std::map, std::set>> byPos; /// быстрый доступ по имени std::unordered_map>> byName; };