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