You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.1 KiB
99 lines
3.1 KiB
#include "inventory.hpp"
|
|
|
|
namespace inventory {
|
|
bool Model::add(const std::string in_slot, DinkyECS::Entity ent) {
|
|
// NOTE: for the C++ die hards, copy the in_slot on purpose to avoid dangling reference
|
|
if(by_slot.contains(in_slot) || by_entity.contains(ent)) return false;
|
|
|
|
by_entity.insert_or_assign(ent, in_slot);
|
|
by_slot.insert_or_assign(in_slot, ent);
|
|
|
|
invariant();
|
|
|
|
return true;
|
|
}
|
|
|
|
const std::string& Model::get(DinkyECS::Entity ent) {
|
|
return by_entity.at(ent);
|
|
}
|
|
|
|
DinkyECS::Entity Model::get(const std::string& slot) {
|
|
return by_slot.at(slot);
|
|
}
|
|
|
|
bool Model::has(DinkyECS::Entity ent) {
|
|
return by_entity.contains(ent);
|
|
}
|
|
|
|
bool Model::has(const std::string& slot) {
|
|
return by_slot.contains(slot);
|
|
}
|
|
|
|
void Model::remove(DinkyECS::Entity ent) {
|
|
dbc::check(by_entity.contains(ent), "attempt to remove entity that isn't in by_entity");
|
|
// NOTE: this was a reference but that caused corruption, just copy
|
|
auto slot = by_entity.at(ent);
|
|
|
|
dbc::log(fmt::format("removing entity {} and slot {}", ent, slot));
|
|
dbc::check(by_slot.contains(slot), "entity is in by_entity but the slot is not in by_slot");
|
|
|
|
// NOTE: you have to erase the entity after the slot or else you get corruption
|
|
by_slot.erase(slot);
|
|
by_entity.erase(ent);
|
|
|
|
invariant();
|
|
}
|
|
|
|
void Model::invariant() {
|
|
for(auto& [slot, ent] : by_slot) {
|
|
dbc::check(by_entity.contains(ent),
|
|
fmt::format("entity {} in by_slot isn't in by_entity?", ent));
|
|
dbc::check(by_entity.at(ent) == slot,
|
|
fmt::format("mismatched slot {} in by_slot doesn't match entity {}", slot, ent));
|
|
}
|
|
|
|
for(auto& [ent, slot] : by_entity) {
|
|
dbc::check(by_slot.contains(slot),
|
|
fmt::format("slot {} in by_entity isn't in by_slot?", ent));
|
|
dbc::check(by_slot.at(slot) == ent,
|
|
fmt::format("mismatched entity {} in by_entity doesn't match entity {}", ent, slot));
|
|
}
|
|
|
|
dbc::check(by_slot.size() == by_entity.size(), "by_slot and by_entity have differing sizes");
|
|
}
|
|
|
|
void Model::dump() {
|
|
invariant();
|
|
fmt::println("INVENTORY has {} slots, sizes equal? {}, contents:",
|
|
by_entity.size(), by_entity.size() == by_slot.size());
|
|
|
|
for(auto [slot, ent] : by_slot) {
|
|
fmt::println("slot={}, ent={}, both={}, equal={}",
|
|
slot, ent, by_entity.contains(ent), by_entity.at(ent) == slot);
|
|
}
|
|
}
|
|
|
|
void Model::swap(DinkyECS::Entity a_ent, DinkyECS::Entity b_ent) {
|
|
dbc::check(by_entity.contains(a_ent), "a_entity not in inventory");
|
|
dbc::check(by_entity.contains(b_ent), "b_entity not in inventory");
|
|
|
|
if(a_ent == b_ent) return;
|
|
|
|
auto a_slot = get(a_ent);
|
|
auto b_slot = get(b_ent);
|
|
|
|
dbc::check(a_slot != b_slot, "somehow I got two different entities but they gave the same slot?");
|
|
|
|
by_slot.insert_or_assign(a_slot, b_ent);
|
|
by_entity.insert_or_assign(b_ent, a_slot);
|
|
|
|
by_slot.insert_or_assign(b_slot, a_ent);
|
|
by_entity.insert_or_assign(a_ent, b_slot);
|
|
}
|
|
|
|
size_t Model::count() {
|
|
dbc::check(by_slot.size() == by_entity.size(), "entity and slot maps have different sizes");
|
|
|
|
return by_entity.size();
|
|
}
|
|
}
|
|
|