Standardized on using only DinkyECS:Entity for most inventory:::Model operations, then create swap based on the same entities.

master
Zed A. Shaw 1 day ago
parent 8c8d6dc9e7
commit 784f753e72
  1. 3
      gui/status_ui.cpp
  2. 47
      inventory.cpp
  3. 18
      inventory.hpp
  4. 5
      systems.cpp
  5. 2
      systems.hpp
  6. 34
      tests/inventory.cpp

@ -129,7 +129,8 @@ namespace gui {
dbc::log(fmt::format("removing slot: {}", slot_id));
auto& slot_name = $slot_to_name.at(slot_id);
auto& inventory = $level.world->get_the<inventory::Model>();
inventory.remove(slot_name);
auto world_entity = inventory.get(slot_name);
inventory.remove(world_entity);
$gui.remove<guecs::GrabSource>(slot_id);
$gui.remove<guecs::Sprite>(slot_id);

@ -1,7 +1,7 @@
#include "inventory.hpp"
namespace inventory {
bool Model::add(const Slot &in_slot, DinkyECS::Entity ent) {
bool Model::add(const std::string &in_slot, DinkyECS::Entity ent) {
invariant();
if(by_slot.contains(in_slot)) return false;
@ -12,11 +12,11 @@ namespace inventory {
return true;
}
Slot& Model::get(DinkyECS::Entity ent) {
const std::string& Model::get(DinkyECS::Entity ent) {
return by_entity.at(ent);
}
DinkyECS::Entity Model::get(const Slot& slot) {
DinkyECS::Entity Model::get(const std::string& slot) {
return by_slot.at(slot);
}
@ -24,25 +24,14 @@ namespace inventory {
return by_entity.contains(ent);
}
bool Model::has(const Slot& slot) {
bool Model::has(const std::string& slot) {
return by_slot.contains(slot);
}
void Model::remove(const Slot& slot, DinkyECS::Entity ent) {
by_entity.erase(ent);
by_slot.erase(slot);
invariant();
}
void Model::remove(DinkyECS::Entity ent) {
auto& slot = by_entity.at(ent);
remove(slot, ent);
invariant();
}
void Model::remove(const Slot& slot) {
auto ent = by_slot.at(slot);
remove(slot, ent);
by_entity.erase(ent);
by_slot.erase(slot);
invariant();
}
@ -70,4 +59,28 @@ namespace inventory {
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();
}
}

@ -6,21 +6,19 @@
// dance when using it. Idea is the System:: ops for this would get it
// and then look at the bool and add the constant ops as needed.
namespace inventory {
using Slot = std::string;
struct Model {
std::unordered_map<Slot, DinkyECS::Entity> by_slot;
std::unordered_map<DinkyECS::Entity, Slot> by_entity;
std::unordered_map<std::string, DinkyECS::Entity> by_slot;
std::unordered_map<DinkyECS::Entity, std::string> by_entity;
bool add(const Slot &in_slot, DinkyECS::Entity ent);
Slot& get(DinkyECS::Entity ent);
DinkyECS::Entity get(const Slot& slot);
bool add(const std::string &in_slot, DinkyECS::Entity ent);
const std::string& get(DinkyECS::Entity ent);
DinkyECS::Entity get(const std::string& slot);
bool has(DinkyECS::Entity ent);
bool has(const Slot& slot);
void remove(const Slot& slot, DinkyECS::Entity ent);
bool has(const std::string& slot);
void remove(DinkyECS::Entity ent);
void remove(const Slot& slot);
void invariant();
void dump();
void swap(DinkyECS::Entity a_ent, DinkyECS::Entity b_ent);
size_t count();
};
}

@ -548,7 +548,8 @@ bool System::place_in_container(World& world, Entity cont_id, const std::string&
}
}
void System::remove_from_container(World& world, Entity cont_id, const std::string& name) {
void System::remove_from_container(World& world, Entity cont_id, const std::string& slot_id) {
auto& container = world.get<inventory::Model>(cont_id);
container.remove(name);
auto entity = container.get(slot_id);
container.remove(entity);
}

@ -34,6 +34,6 @@ namespace System {
bool place_in_container(World& world, Entity cont_id, const string& name, Entity world_entity);
void remove_from_container(World& world, Entity cont_id, const string& name);
void remove_from_container(World& world, Entity cont_id, const std::string& name);
void remove_from_world(GameLevel &level, Entity entity);
}

@ -27,28 +27,24 @@ TEST_CASE("base test", "[inventory]") {
REQUIRE(inv.has(slot));
// test base remove
inv.remove(slot, ent);
inv.remove(ent);
REQUIRE(!inv.has(slot));
REQUIRE(!inv.has(ent));
}
// test remove just by slot
good = inv.add("hand_r", test_ent);
REQUIRE(good);
REQUIRE(inv.has("hand_r"));
REQUIRE(inv.has(test_ent));
inv.invariant();
TEST_CASE("test swapping items", "[inventory-swap]") {
inventory::Model inv;
DinkyECS::Entity hand_l_ent = 10;
DinkyECS::Entity hand_r_ent = 20;
inv.remove("hand_r");
REQUIRE(!inv.has("hand_r"));
REQUIRE(!inv.has(test_ent));
inv.add("hand_l", hand_l_ent);
inv.add("hand_r", hand_r_ent);
REQUIRE(inv.count() == 2);
// test remove just by entity
good = inv.add("pocket_l", test_ent);
REQUIRE(good);
REQUIRE(inv.has("pocket_l"));
REQUIRE(inv.has(test_ent));
inv.invariant();
inv.remove(test_ent);
REQUIRE(!inv.has("pocket_l"));
REQUIRE(!inv.has(test_ent));
inv.swap(hand_l_ent, hand_r_ent);
REQUIRE(inv.get("hand_l") == hand_r_ent);
REQUIRE(inv.get("hand_r") == hand_l_ent);
REQUIRE(inv.count() == 2);
}

Loading…
Cancel
Save