#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.begin(); pair != this->byId.end(); ++pair) { tmp.push_back(pair->second); } return tmp; } private: /// быстрый доступ по id std::map byId{}; /// быстрый доступ по позиции std::map, std::set> byPos; /// быстрый доступ по имени std::unordered_map> byName; };