#include #include #include #include #include #include struct C0 { C0(int x = 0, int y = 0) : x(x), y(y) {} int x, y; }; struct C1 { int vx, vy; }; struct C2 {}; struct C3 {}; struct T0 {}; struct T1 {}; using ListComponentsAll = EC::Meta::TypeList; using ListComponentsSome = EC::Meta::TypeList; using ListTagsAll = EC::Meta::TypeList; using ListAll = EC::Meta::TypeList; using EmptyList = EC::Meta::TypeList<>; using MixedList = EC::Meta::TypeList; typedef std::unique_ptr C0Ptr; struct Base { virtual int getInt() { return 0; } }; struct Derived : public Base { virtual int getInt() override { return 1; } }; typedef std::unique_ptr TestPtr; TEST(EC, Bitset) { { EC::Bitset bitset; bitset[1] = true; bitset[3] = true; auto genBitset = EC::Bitset::generateBitset(); EXPECT_EQ(bitset, genBitset); } { EC::Bitset bitset; bitset[2] = true; bitset[5] = true; auto genBitset = EC::Bitset::generateBitset(); EXPECT_EQ(bitset, genBitset); } } TEST(EC, Manager) { EC::Manager manager; std::size_t e0 = manager.addEntity(); std::size_t e1 = manager.addEntity(); manager.addComponent(e0, 5, 5); manager.addComponent(e0); manager.addComponent(e1); manager.addComponent(e1); manager.addTag(e1); { auto& vel = manager.getEntityData(e0); vel.vx = 1; vel.vy = 1; } auto posUpdate = [] (std::size_t id, C0& pos, C1& vel) { pos.x += vel.vx; pos.y += vel.vy; }; auto updateTag = [] (std::size_t id, C0& pos, C1& vel) { pos.x = pos.y = vel.vx = vel.vy = 0; }; manager.forMatchingSignature >(posUpdate); manager.forMatchingSignature >(posUpdate); manager.forMatchingSignature >(updateTag); { auto& pos = manager.getEntityData(e0); EXPECT_EQ(pos.x, 7); EXPECT_EQ(pos.y, 7); } { bool has = manager.hasComponent(e1); EXPECT_TRUE(has); has = manager.hasTag(e1); EXPECT_TRUE(has); } manager.deleteEntity(e0); manager.cleanup(); std::size_t edata = std::get(manager.getEntityInfo(0)); EXPECT_EQ(edata, 1); std::size_t e2 = manager.addEntity(); manager.addTag(e2); std::size_t count = 0; auto updateTagOnly = [&count] (std::size_t id) { std::cout << "UpdateTagOnly was run." << std::endl; ++count; }; manager.forMatchingSignature >(updateTagOnly); EXPECT_EQ(2, count); manager.deleteEntity(e1); manager.deleteEntity(e2); manager.cleanup(); } TEST(EC, MoveComponentWithUniquePtr) { { EC::Manager, EC::Meta::TypeList<> > manager; std::size_t e = manager.addEntity(); { C0Ptr ptr = std::make_unique(5, 10); manager.addComponent(e, std::move(ptr)); } int x = 0; int y = 0; manager.forMatchingSignature >([&x, &y] (std::size_t eID, C0Ptr& ptr) { x = ptr->x; y = ptr->y; }); EXPECT_EQ(5, x); EXPECT_EQ(10, y); } { EC::Manager, EC::Meta::TypeList<> > manager; std::size_t e = manager.addEntity(); { TestPtr ptrBase = std::make_unique(); manager.addComponent(e, std::move(ptrBase)); } int result = 0; auto getResultFunction = [&result] (std::size_t eID, TestPtr& ptr) { result = ptr->getInt(); }; manager.forMatchingSignature >(getResultFunction); EXPECT_EQ(0, result); { TestPtr ptrDerived = std::make_unique(); manager.addComponent(e, std::move(ptrDerived)); } manager.forMatchingSignature >(getResultFunction); EXPECT_EQ(1, result); } } TEST(EC, DeletedEntities) { EC::Manager manager; for(unsigned int i = 0; i < 4; ++i) { auto eid = manager.addEntity(); manager.addComponent(eid); if(i >= 2) { manager.deleteEntity(eid); } } manager.cleanup(); for(unsigned int i = 0; i < 4; ++i) { if(i < 2) { EXPECT_TRUE(manager.hasComponent(i)); } else { EXPECT_FALSE(manager.hasComponent(i)); } } for(unsigned int i = 0; i < 2; ++i) { auto eid = manager.addEntity(); EXPECT_FALSE(manager.hasComponent(eid)); } } TEST(EC, FunctionStorage) { EC::Manager manager; auto eid = manager.addEntity(); manager.addComponent(eid, 0, 1); manager.addComponent(eid); manager.addComponent(eid); manager.addComponent(eid); auto f0index = manager.addForMatchingFunction>( [] (std::size_t eid, C0& c0) { ++c0.x; ++c0.y; }); auto f1index = manager.addForMatchingFunction>( [] (std::size_t eid, C0& c0, C1& c1) { c1.vx = c0.x + 10; c1.vy = c1.vy + c1.vx + c0.y + 10; }); manager.addForMatchingFunction>( [] (std::size_t eid) { //derp 0 }); auto lastIndex = manager.addForMatchingFunction>( [] (std::size_t eid) { //derp 1 }); manager.callForMatchingFunctions(); { auto c0 = manager.getEntityData(eid); EXPECT_EQ(1, c0.x); EXPECT_EQ(2, c0.y); auto c1 = manager.getEntityData(eid); EXPECT_EQ(11, c1.vx); EXPECT_EQ(23, c1.vy); } EXPECT_TRUE(manager.callForMatchingFunction(f0index)); EXPECT_FALSE(manager.callForMatchingFunction(lastIndex + 1)); { auto& c0 = manager.getEntityData(eid); EXPECT_EQ(2, c0.x); EXPECT_EQ(3, c0.y); c0.x = 1; c0.y = 2; auto c1 = manager.getEntityData(eid); EXPECT_EQ(11, c1.vx); EXPECT_EQ(23, c1.vy); } manager.clearSomeMatchingFunctions({f1index}); { std::vector indices{f1index}; manager.clearSomeMatchingFunctions(indices); } { std::set indices{f1index}; manager.clearSomeMatchingFunctions(indices); } { std::unordered_set indices{f1index}; manager.clearSomeMatchingFunctions(indices); } manager.callForMatchingFunctions(); { auto c0 = manager.getEntityData(eid); EXPECT_EQ(1, c0.x); EXPECT_EQ(2, c0.y); auto c1 = manager.getEntityData(eid); EXPECT_EQ(11, c1.vx); EXPECT_EQ(46, c1.vy); } EXPECT_TRUE(manager.removeForMatchingFunction(f1index)); EXPECT_FALSE(manager.removeForMatchingFunction(f1index)); manager.callForMatchingFunctions(); { auto c0 = manager.getEntityData(eid); EXPECT_EQ(1, c0.x); EXPECT_EQ(2, c0.y); auto c1 = manager.getEntityData(eid); EXPECT_EQ(11, c1.vx); EXPECT_EQ(46, c1.vy); } manager.clearForMatchingFunctions(); manager.callForMatchingFunctions(); { auto c0 = manager.getEntityData(eid); EXPECT_EQ(1, c0.x); EXPECT_EQ(2, c0.y); auto c1 = manager.getEntityData(eid); EXPECT_EQ(11, c1.vx); EXPECT_EQ(46, c1.vy); } }