#include <unordered_map>
#include <string>
#include <set>
#include <utility>
#include <map>
#include <functional>
#include <vector>
bool operator>(const GameObject &a, const GameObject &b) {
return a.id > b.id;
}
template<class Tp, template<class> class Compare>
class DereferenceCompare {
Compare<Tp> comp;
public:
bool operator()(const Tp *const a, const Tp *const b) const {
return comp(*a, *b);
}
};
class GameDatabase {
public:
GameDatabase() = default;
void Insert(ObjectId id, string name, size_t x, size_t y) {
fastId.erase(id);
fastId.insert({id, GameObject{id, name, x, y}});
fastPos[pair<size_t, size_t>(x, y)].insert(&fastId[id]);
fastName[name].insert(&fastId[id]);
}
void Remove(ObjectId id) {
fastId.erase(id);
}
vector<GameObject> DataByName(string name) const {
vector<GameObject> out;
if (fastName.count(name)) {
for (auto it : fastName.find(name)->second) {
out.push_back(*it);
}
}
return out;
}
vector<GameObject> DataByPosition(size_t x, size_t y) const {
vector<GameObject> out;
if (fastPos.count(pair<size_t, size_t>(x, y))) {
for (auto it : fastPos.find(pair<size_t, size_t>(x, y))->second) {
out.push_back(*it);
}
}
return out;
}
vector<GameObject> Data() const {
vector<GameObject> out;
for (auto it : fastId) {
out.push_back(it.second);
}
return out;
}
private:
map<ObjectId, GameObject, std::greater<ObjectId>> fastId;
map<std::pair<size_t, size_t>, std::set<GameObject *,
DereferenceCompare<GameObject, std::greater>>> fastPos;
unordered_map<string, std::set<GameObject *,
DereferenceCompare<GameObject, std::greater>>> fastName;
};