#include #include "dinkyecs.hpp" #include #include using namespace fmt; using DinkyECS::Entity; struct Player { std::string name; Entity eid; }; struct Position { double x, y; }; struct Velocity { double x, y; }; struct Gravity { double level; }; struct DaGUI { int event; }; /* * Using a function catches instances where I'm not copying * the data into the world. */ void configure(DinkyECS::World &world, Entity &test) { println("---Configuring the base system."); Entity test2 = world.entity(); world.set(test, {10,20}); world.set(test, {1,2}); world.set(test2, {1,1}); world.set(test2, {9,19}); println("---- Setting up the player as a fact in the system."); auto player_eid = world.entity(); Player player_info{"Zed", player_eid}; // just set some player info as a fact with the entity id world.set_the(player_info); world.set(player_eid, {0,0}); world.set(player_eid, {0,0}); auto enemy = world.entity(); world.set(enemy, {0,0}); world.set(enemy, {0,0}); println("--- Creating facts (singletons)"); world.set_the({0.9}); } TEST_CASE("confirm ECS system works", "[ecs]") { DinkyECS::World world; Entity test = world.entity(); configure(world, test); Position &pos = world.get(test); REQUIRE(pos.x == 10); REQUIRE(pos.y == 20); Velocity &vel = world.get(test); REQUIRE(vel.x == 1); REQUIRE(vel.y == 2); world.query([](const auto &ent, auto &pos) { REQUIRE(ent > 0); REQUIRE(pos.x >= 0); REQUIRE(pos.y >= 0); }); world.query([](const auto &ent, auto &vel) { REQUIRE(ent > 0); REQUIRE(vel.x >= 0); REQUIRE(vel.y >= 0); }); println("--- Manually get the velocity in position system:"); world.query([&](const auto &ent, auto &pos) { Velocity &vel = world.get(ent); REQUIRE(ent > 0); REQUIRE(pos.x >= 0); REQUIRE(pos.y >= 0); REQUIRE(ent > 0); REQUIRE(vel.x >= 0); REQUIRE(vel.y >= 0); }); println("--- Query only entities with Position and Velocity:"); world.query([&](const auto &ent, auto &pos, auto &vel) { Gravity &grav = world.get_the(); REQUIRE(grav.level <= 1.0f); REQUIRE(grav.level > 0.5f); REQUIRE(ent > 0); REQUIRE(pos.x >= 0); REQUIRE(pos.y >= 0); REQUIRE(ent > 0); REQUIRE(vel.x >= 0); REQUIRE(vel.y >= 0); }); // now remove Velocity REQUIRE(world.has(test)); world.remove(test); REQUIRE_THROWS(world.get(test)); REQUIRE(!world.has(test)); println("--- After remove test, should only result in test2:"); world.query([&](const auto &ent, auto &pos, auto &vel) { REQUIRE(pos.x >= 0); REQUIRE(pos.y >= 0); }); } enum GUIEvent { HIT, MISS }; TEST_CASE("confirm that the event system works", "[ecs]") { DinkyECS::World world; DinkyECS::Entity gui_ent = world.entity(); DinkyECS::Entity player = world.entity(); GUIEvent gui{GUIEvent::HIT}; world.set(gui_ent, gui); auto &gui_test = world.get(gui_ent); REQUIRE(gui == gui_test); world.send(GUIEvent::HIT, player); bool ready = world.has_event(); REQUIRE(ready == true); auto [event, entity] = world.recv(); REQUIRE(event == GUIEvent::HIT); REQUIRE(entity == player); ready = world.has_event(); REQUIRE(ready == false); }