#include #include #include #include #include #include #include using std::vector; using std::string; 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, const string &name, size_t x, size_t y); /// удаляет элемент по id /// если такого элемента нет, ничего не делает void Remove(ObjectId id); /// возвращает вектор объектов c именем [name] /// сортировка по убыванию id vector DataByName(string name) const; /// возвращает вектор объектов, находящихся в позиции [x, y] /// сортировка по убыванию id vector DataByPosition(size_t x, size_t y) const; /// возвращает вектор всех объектов из базы /// сортировка по убыванию id vector Data() const; private: /// быстрый доступ по id std::map> _data_id; /// быстрый доступ по позиции std::map, std::set>> _data_pos; /// быстрый доступ по имени std::unordered_map>> _data_name; }; bool cmp(const GameObject &a, const GameObject &b) { return a.id > b.id; } void GameDatabase::Insert(ObjectId id, const string &name, size_t x, size_t y) { _data_id[id] = {id, name, x, y}; _data_pos[{x, y}].insert(&_data_id[id]); _data_name[name].insert(&_data_id[id]); } void GameDatabase::Remove(ObjectId id) { auto item = _data_id[id]; _data_pos[{item.x, item.y}].erase(&item); _data_name[item.name].erase(&item); _data_id.erase(id); } vector GameDatabase::DataByName(string name) const { vector data; if (_data_name.find(name) == _data_name.end()) return data; for (auto gmObj : _data_name.at(name)) data.push_back(*gmObj); return data; } vector GameDatabase::DataByPosition(size_t x, size_t y) const { vector data; if (_data_pos.find({x, y}) == _data_pos.end()) return data; for (auto gmObj : _data_pos.at({x, y})) data.push_back(*gmObj); return data; } vector GameDatabase::Data() const { vector data; for (const auto &item : _data_id) { data.push_back(item.second); } return data; }