#pragma once
#include <unordered_map>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <functional>
#include <utility>
#include <memory>
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 {
map<ObjectId, GameObject, std::greater<ObjectId>> a;
std::unordered_map<string,
std::set<GameObject*, DereferenceCompare<GameObject, std::greater>>> b;
map<pair<size_t, size_t>,
std::set<GameObject*, DereferenceCompare<GameObject, std::greater>>> c;
public:
GameDatabase() = default;
void Insert(ObjectId id, string name, size_t x, size_t y) {
GameObject* d = new GameObject();
d->id = id;
d->name = name;
d->x = x;
d->y = y;
Remove(id);
a[id] = *d;
c[make_pair(x, y)].insert(d);
b[name].insert(d);
}
void Remove(ObjectId id) {
GameObject a1 = a[id];
a.erase(id);
c[{a1.x, a1.y}].erase(&a1);
b[a1.name].erase(&a1);
}
vector<GameObject> DataByPosition(size_t x, size_t y) const {
vector<GameObject> a1;
if (c.find({ x, y }) != c.end()) {
std::set<GameObject*,
DereferenceCompare<GameObject, std::greater>>
c2 = c.at({ x, y });
for (auto a2 : c2) {
a1.push_back(*a2);
}
}
return a1;
}
vector<GameObject> DataByName(string name) const {
vector<GameObject> a1;
if (b.find(name) != b.end()) {
std::set<GameObject*,
DereferenceCompare<GameObject, std::greater>>
b2 = b.at(name);
for (auto a2 : b2) {
(a1).push_back(*a2);
}
}
return a1;
}
vector<GameObject> Data() const {
vector<GameObject> a1;
for (auto el : a) {
a1.push_back(el.second);
}
return a1;
}
};