#pragma once #include #include #include #include #include #include #include bool operator>(const GameObject& a, const GameObject& b) { return a.id > b.id; } bool operator<(const GameObject& a, const GameObject& b) { return a.id < b.id; } 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) { this->Remove(id); GameObject tmp{id, name, x, y}; this->byId.insert(std::pair(id, tmp)); this->byPos[std::pair(x, y)].insert(tmp); this->byName[name].insert(tmp); } /// удаляет элемент по id /// если такого элемента нет, ничего не делает void Remove(ObjectId id) { if (this->byId.find(id) != this->byId.end()){ GameObject tmp = this->byId.at(id); this->byPos[{tmp.x, tmp.y}].erase(tmp); this->byName[tmp.name].erase(tmp); this->byId.erase(id); } } /// возвращает вектор объектов c именем [name] /// сортировка по убыванию id std::vector DataByName(std::string name) const { std::vector tmp; if (this->byName.find(name) != this->byName.end()) { for (auto obj: this->byName.at(name)) { tmp.push_back(obj); } } return tmp; } /// возвращает вектор объектов, находящихся в позиции [x, y] /// сортировка по убыванию id std::vector DataByPosition(size_t x, size_t y) const { std::vector tmp; if (this->byPos.find({x,y}) != this->byPos.end()) { for (auto obj: this->byPos.at({x, y})) { tmp.push_back(obj); } } return tmp; } /// возвращает вектор всех объектов из базы /// сортировка по убыванию id std::vector Data() const { std::vector tmp; for (auto pair : this->byId){ tmp.push_back(pair.second); } return tmp; } private: /// быстрый доступ по id std::map byId{}; /// быстрый доступ по позиции std::map, std::set> byPos; /// быстрый доступ по имени std::unordered_map> byName; };