#pragma once
#include <map>
#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:
map<ObjectId, GameObject, greater<ObjectId>> ID;
map<pair<size_t, size_t>, set<GameObject*, DereferenceCompare<GameObject, greater>>> pos;
unordered_map<string, set<GameObject*, DereferenceCompare<GameObject, greater>>> title;
GameDatabase() = default;
void Insert(ObjectId id, string name, size_t x, size_t y) {
GameObject chk{ id, name, x, y };
if (ID.find(id) != ID.end()) {
Remove(id);
}
ID.insert({ id, chk });
auto add = &ID.at(id);
pos[{x, y}].insert(add);
title[name].insert(add);
}
void Remove(ObjectId id) {
if (ID.find(id) != ID.end()) {
GameObject* del = &ID.find(id)->second;
pos.find({ del->x, del->y })->second.erase(del);
title.find({ del->name })->second.erase(del);
ID.erase(ID.find(id));
}
}
vector<GameObject> DataByName(string name) const {
vector<GameObject> res;
auto it = title.find(name);
if (it == title.end()) {
return res;
}
for (auto x : it->second) {
res.push_back(*x);
}
return res;
}
vector<GameObject> DataByPosition(size_t x, size_t y) const {
vector<GameObject> res;
auto it = pos.find({ x, y });
if (it == pos.end()) {
return res;
}
for (auto x : it->second) {
res.push_back(*x);
}
return res;
}
vector<GameObject> Data() const {
vector<GameObject> res;
for (auto x : ID) {
res.push_back(x.second);
}
return res;
}
};