]> git.seodisparate.com - EntityComponentMetaSystem/commitdiff
Add ability to handle unknown types
authorStephen Seo <seo.disparate@gmail.com>
Thu, 17 May 2018 08:05:49 +0000 (17:05 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 17 May 2018 08:05:49 +0000 (17:05 +0900)
EC/Manager and EC/Bitset can now handle types that are not known
(Components or Tags not in the given Components or Tags when created).

Manager::getEntityData now returns a pointer instead of a reference.
Functions passed to Manager::forMatchingFunction (and other similar fns)
should now accept Component fields as pointer types, not reference
types.

src/EC/Bitset.hpp
src/EC/Manager.hpp
src/EC/Meta/IndexOf.hpp
src/test/ECTest.cpp
src/test/MetaTest.cpp

index e3dc07b853454e80897ef3830d35370c19d6be75..b814e0773b7c267790776ea23edb9d165ff61e08 100644 (file)
 
 namespace EC
 {
+    // Note bitset size is sizes of components and tags + 1
+    // This is to use the last extra bit as the result of a query
+    // with a Component or Tag not known to the Bitset.
+    // Those queries will return a false bit every time.
     template <typename ComponentsList, typename TagsList>
     struct Bitset :
-        public std::bitset<ComponentsList::size + TagsList::size>
+        public std::bitset<ComponentsList::size + TagsList::size + 1>
     {
         using Combined = EC::Meta::Combine<ComponentsList, TagsList>;
 
+        Bitset()
+        {
+            (*this)[Combined::size] = false;
+        }
+
+        // TODO find a better way to handle non-member type in const
         template <typename Component>
         constexpr auto getComponentBit() const
         {
-            return (*this)[EC::Meta::IndexOf<Component, Combined>::value];
+            auto index = EC::Meta::IndexOf<Component, Combined>::value;
+            return (*this)[index];
         }
 
         template <typename Component>
         constexpr auto getComponentBit()
         {
-            return (*this)[EC::Meta::IndexOf<Component, Combined>::value];
+            auto index = EC::Meta::IndexOf<Component, Combined>::value;
+            (*this)[Combined::size] = false;
+            return (*this)[index];
         }
 
         template <typename Tag>
         constexpr auto getTagBit() const
         {
-            return (*this)[EC::Meta::IndexOf<Tag, Combined>::value];
+            auto index = EC::Meta::IndexOf<Tag, Combined>::value;
+            return (*this)[index];
         }
 
         template <typename Tag>
         constexpr auto getTagBit()
         {
-            return (*this)[EC::Meta::IndexOf<Tag, Combined>::value];
+            auto index = EC::Meta::IndexOf<Tag, Combined>::value;
+            (*this)[Combined::size] = false;
+            return (*this)[index];
         }
 
         template <typename Contents>
index 0e958fdbbc86145b43771a004a1f262f89edc168..b3dd90f779fdd79c1597984d5cda1cabdd6ea4e2 100644 (file)
@@ -31,6 +31,7 @@
 #include "Meta/Matching.hpp"
 #include "Meta/ForEachWithIndex.hpp"
 #include "Meta/ForEachDoubleTuple.hpp"
+#include "Meta/IndexOf.hpp"
 #include "Bitset.hpp"
 
 namespace EC
@@ -61,7 +62,7 @@ namespace EC
         template <typename... Types>
         struct Storage
         {
-            using type = std::tuple<std::vector<Types>... >;
+            using type = std::tuple<std::vector<Types>..., std::vector<char> >;
         };
         using ComponentsStorage =
             typename EC::Meta::Morph<ComponentsList, Storage<> >::type;
@@ -230,10 +231,22 @@ namespace EC
             the Entity actually owns that Component.
         */
         template <typename Component>
-        Component& getEntityData(const std::size_t& index)
+        Component* getEntityData(const std::size_t& index)
         {
-            return std::get<std::vector<Component> >(componentsStorage).at(
-                index);
+            constexpr auto componentIndex = EC::Meta::IndexOf<
+                Component, Components>::value;
+            if(componentIndex < Components::size)
+            {
+                // Cast required due to compiler thinking that an invalid
+                // Component is needed even though the enclosing if statement
+                // prevents this from ever happening.
+                return (Component*) &std::get<componentIndex>(
+                    componentsStorage).at(index);
+            }
+            else
+            {
+                return nullptr;
+            }
         }
 
         /*!
@@ -249,7 +262,7 @@ namespace EC
             the Entity actually owns that Component.
         */
         template <typename Component>
-        Component& getEntityComponent(const std::size_t& index)
+        Component* getEntityComponent(const std::size_t& index)
         {
             return getEntityData<Component>(index);
         }
@@ -265,10 +278,22 @@ namespace EC
             to determine if the Entity actually owns that Component.
         */
         template <typename Component>
-        const Component& getEntityData(const std::size_t& index) const
+        const Component* getEntityData(const std::size_t& index) const
         {
-            return std::get<std::vector<Component> >(componentsStorage).at(
-                index);
+            constexpr auto componentIndex = EC::Meta::IndexOf<
+                Component, Components>::value;
+            if(componentIndex < Components::size)
+            {
+                // Cast required due to compiler thinking that an invalid
+                // Component is needed even though the enclosing if statement
+                // prevents this from ever happening.
+                return (Component*) &std::get<componentIndex>(
+                    componentsStorage).at(index);
+            }
+            else
+            {
+                return nullptr;
+            }
         }
 
         /*!
@@ -284,7 +309,7 @@ namespace EC
             to determine if the Entity actually owns that Component.
         */
         template <typename Component>
-        const Component& getEntityComponent(const std::size_t& index) const
+        const Component* getEntityComponent(const std::size_t& index) const
         {
             return getEntityData<Component>(index);
         }
@@ -349,7 +374,8 @@ namespace EC
         template <typename Component, typename... Args>
         void addComponent(const std::size_t& entityID, Args&&... args)
         {
-            if(!isAlive(entityID))
+            if(!isAlive(entityID)
+                || !EC::Meta::Contains<Component, Components>::value)
             {
                 return;
             }
@@ -360,9 +386,15 @@ namespace EC
                 entities[entityID]
             ).template getComponentBit<Component>() = true;
 
-            std::get<std::vector<Component> >(
+            constexpr auto index =
+                EC::Meta::IndexOf<Component, Components>::value;
+
+            // Cast required due to compiler thinking that vector<char> at
+            // index = Components::size is being used, even if the previous
+            // if statement will prevent this from ever happening.
+            (*((std::vector<Component>*)(&std::get<index>(
                 componentsStorage
-            )[entityID] = std::move(component);
+            ))))[entityID] = std::move(component);
         }
 
         /*!
@@ -400,7 +432,8 @@ namespace EC
         template <typename Tag>
         void addTag(const std::size_t& entityID)
         {
-            if(!isAlive(entityID))
+            if(!isAlive(entityID)
+                || !EC::Meta::Contains<Tag, Tags>::value)
             {
                 return;
             }
index db155d843817a172e3accae4ba94f4ab5ec0bcb8..851d9fb0b6b6542db3a53e3f7b3764b6a371bddd 100644 (file)
@@ -4,6 +4,12 @@
 // His code is available here: https://github.com/SuperV1234/cppcon2015
 
 
+/*
+    Returns the index of a type in a type list.
+    If the type does not exist in the type list,
+    returns the size of the type list.
+*/
+
 #ifndef EC_META_INDEX_OF_HPP
 #define EC_META_INDEX_OF_HPP
 
@@ -14,7 +20,7 @@ namespace EC
     namespace Meta
     {
         template <typename T, typename... Types>
-        struct IndexOf
+        struct IndexOf : std::integral_constant<std::size_t, 0>
         {
         };
 
index fc5e59a596ffb15cedab94f8b7bdf718407fbee3..3167a525f35f3fdbc3fd7666f76aa85ea02613e5 100644 (file)
@@ -96,18 +96,18 @@ TEST(EC, Manager)
     manager.addTag<T0>(e1);
 
     {
-        auto& vel = manager.getEntityData<C1>(e0);
-        vel.vx = 1;
-        vel.vy = 1;
+        auto* vel = manager.getEntityData<C1>(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 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;
+    auto updateTag = [] (std::size_t id, C0* pos, C1* vel) {
+        pos->x = pos->y = vel->vx = vel->vy = 0;
     };
 
     manager.forMatchingSignature<EC::Meta::TypeList<C0, C1> >(posUpdate);
@@ -116,9 +116,9 @@ TEST(EC, Manager)
     manager.forMatchingSignature<EC::Meta::TypeList<C0, C1, T0> >(updateTag);
 
     {
-        auto& pos = manager.getEntityData<C0>(e0);
-        EXPECT_EQ(pos.x, 7);
-        EXPECT_EQ(pos.y, 7);
+        auto* pos = manager.getEntityData<C0>(e0);
+        EXPECT_EQ(pos->x, 7);
+        EXPECT_EQ(pos->y, 7);
     }
 
     {
@@ -166,9 +166,10 @@ TEST(EC, MoveComponentWithUniquePtr)
 
         int x = 0;
         int y = 0;
-        manager.forMatchingSignature<EC::Meta::TypeList<C0Ptr> >([&x, &y] (std::size_t eID, C0Ptr& ptr) {
-            x = ptr->x;
-            y = ptr->y;
+        manager.forMatchingSignature<EC::Meta::TypeList<C0Ptr> >([&x, &y]
+                (std::size_t eID, C0Ptr* ptr) {
+            x = (*ptr)->x;
+            y = (*ptr)->y;
         });
         EXPECT_EQ(5, x);
         EXPECT_EQ(10, y);
@@ -185,8 +186,8 @@ TEST(EC, MoveComponentWithUniquePtr)
 
         int result = 0;
 
-        auto getResultFunction = [&result] (std::size_t eID, TestPtr& ptr) {
-            result = ptr->getInt();
+        auto getResultFunction = [&result] (std::size_t eID, TestPtr* ptr) {
+            result = (*ptr)->getInt();
         };
 
         manager.forMatchingSignature<EC::Meta::TypeList<TestPtr> >(getResultFunction);
@@ -244,32 +245,34 @@ TEST(EC, FunctionStorage)
     manager.addComponent<C2>(eid);
     manager.addComponent<C3>(eid);
 
-    auto f0index = manager.addForMatchingFunction<EC::Meta::TypeList<C0>>( [] (std::size_t eid, C0& c0) {
-        ++c0.x;
-        ++c0.y;
+    auto f0index = manager.addForMatchingFunction<EC::Meta::TypeList<C0>>(
+            [] (std::size_t eid, C0* c0) {
+        ++c0->x;
+        ++c0->y;
     });
 
-    auto f1index = manager.addForMatchingFunction<EC::Meta::TypeList<C0, C1>>( [] (std::size_t eid, C0& c0, C1& c1) {
-        c1.vx = c0.x + 10;
-        c1.vy = c1.vy + c1.vx + c0.y + 10;
+    auto f1index = manager.addForMatchingFunction<EC::Meta::TypeList<C0, C1>>(
+            [] (std::size_t eid, C0* c0, C1* c1) {
+        c1->vx = c0->x + 10;
+        c1->vy = c1->vy + c1->vx + c0->y + 10;
     });
 
     auto f2index = manager.addForMatchingFunction<EC::Meta::TypeList<C0>>(
-            [] (std::size_t eid, C0& c0) {
-        c0.x = c0.y = 9999;
+            [] (std::size_t eid, C0* c0) {
+        c0->x = c0->y = 9999;
     });
 
     auto f3index = manager.addForMatchingFunction<EC::Meta::TypeList<C1>>(
-            [] (std::size_t eid, C1& c1) {
-        c1.vx = c1.vy = 10000;
+            [] (std::size_t eid, C1* c1) {
+        c1->vx = c1->vy = 10000;
     });
 
     EXPECT_EQ(2, manager.removeSomeMatchingFunctions({f2index, f3index}));
 
     auto f4index = manager.addForMatchingFunction<EC::Meta::TypeList<C0>>(
-            [] (std::size_t eid, C0& c0) {
-        c0.x = 999;
-        c0.y = 888;
+            [] (std::size_t eid, C0* c0) {
+        c0->x = 999;
+        c0->y = 888;
     });
 
     {
@@ -278,9 +281,9 @@ TEST(EC, FunctionStorage)
     }
 
     auto f5index = manager.addForMatchingFunction<EC::Meta::TypeList<C0>>(
-            [] (std::size_t eid, C0& c0) {
-        c0.x = 777;
-        c0.y = 666;
+            [] (std::size_t eid, C0* c0) {
+        c0->x = 777;
+        c0->y = 666;
     });
 
     auto lastIndex = f5index;
@@ -293,33 +296,33 @@ TEST(EC, FunctionStorage)
     manager.callForMatchingFunctions();
 
     {
-        auto c0 = manager.getEntityData<C0>(eid);
+        auto* c0 = manager.getEntityData<C0>(eid);
 
-        EXPECT_EQ(1, c0.x);
-        EXPECT_EQ(2, c0.y);
+        EXPECT_EQ(1, c0->x);
+        EXPECT_EQ(2, c0->y);
 
-        auto c1 = manager.getEntityData<C1>(eid);
+        auto* c1 = manager.getEntityData<C1>(eid);
 
-        EXPECT_EQ(11, c1.vx);
-        EXPECT_EQ(23, c1.vy);
+        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<C0>(eid);
+        auto* c0 = manager.getEntityData<C0>(eid);
 
-        EXPECT_EQ(2, c0.x);
-        EXPECT_EQ(3, c0.y);
+        EXPECT_EQ(2, c0->x);
+        EXPECT_EQ(3, c0->y);
 
-        c0.x = 1;
-        c0.y = 2;
+        c0->x = 1;
+        c0->y = 2;
 
-        auto c1 = manager.getEntityData<C1>(eid);
+        auto* c1 = manager.getEntityData<C1>(eid);
 
-        EXPECT_EQ(11, c1.vx);
-        EXPECT_EQ(23, c1.vy);
+        EXPECT_EQ(11, c1->vx);
+        EXPECT_EQ(23, c1->vy);
     }
 
     EXPECT_EQ(1, manager.keepSomeMatchingFunctions({f1index}));
@@ -340,15 +343,15 @@ TEST(EC, FunctionStorage)
     manager.callForMatchingFunctions();
 
     {
-        auto c0 = manager.getEntityData<C0>(eid);
+        auto* c0 = manager.getEntityData<C0>(eid);
 
-        EXPECT_EQ(1, c0.x);
-        EXPECT_EQ(2, c0.y);
+        EXPECT_EQ(1, c0->x);
+        EXPECT_EQ(2, c0->y);
 
-        auto c1 = manager.getEntityData<C1>(eid);
+        auto* c1 = manager.getEntityData<C1>(eid);
 
-        EXPECT_EQ(11, c1.vx);
-        EXPECT_EQ(46, c1.vy);
+        EXPECT_EQ(11, c1->vx);
+        EXPECT_EQ(46, c1->vy);
     }
 
     EXPECT_TRUE(manager.removeForMatchingFunction(f1index));
@@ -357,30 +360,30 @@ TEST(EC, FunctionStorage)
     manager.callForMatchingFunctions();
 
     {
-        auto c0 = manager.getEntityData<C0>(eid);
+        auto* c0 = manager.getEntityData<C0>(eid);
 
-        EXPECT_EQ(1, c0.x);
-        EXPECT_EQ(2, c0.y);
+        EXPECT_EQ(1, c0->x);
+        EXPECT_EQ(2, c0->y);
 
-        auto c1 = manager.getEntityData<C1>(eid);
+        auto* c1 = manager.getEntityData<C1>(eid);
 
-        EXPECT_EQ(11, c1.vx);
-        EXPECT_EQ(46, c1.vy);
+        EXPECT_EQ(11, c1->vx);
+        EXPECT_EQ(46, c1->vy);
     }
 
     manager.clearForMatchingFunctions();
     manager.callForMatchingFunctions();
 
     {
-        auto c0 = manager.getEntityData<C0>(eid);
+        auto* c0 = manager.getEntityData<C0>(eid);
 
-        EXPECT_EQ(1, c0.x);
-        EXPECT_EQ(2, c0.y);
+        EXPECT_EQ(1, c0->x);
+        EXPECT_EQ(2, c0->y);
 
-        auto c1 = manager.getEntityData<C1>(eid);
+        auto* c1 = manager.getEntityData<C1>(eid);
 
-        EXPECT_EQ(11, c1.vx);
-        EXPECT_EQ(46, c1.vy);
+        EXPECT_EQ(11, c1->vx);
+        EXPECT_EQ(46, c1->vy);
     }
 }
 
@@ -410,22 +413,22 @@ TEST(EC, MultiThreaded)
     {
         manager.addEntity();
         manager.addComponent<C0>(i, 0, 0);
-        EXPECT_EQ(0, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(0, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(0, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(0, manager.getEntityData<C0>(i)->y);
     }
 
     manager.forMatchingSignature<EC::Meta::TypeList<C0> >(
-        [] (const std::size_t& eid, C0& c) {
-            c.x = 1;
-            c.y = 2;
+        [] (const std::size_t& eid, C0* c) {
+            c->x = 1;
+            c->y = 2;
         },
         2
     );
 
     for(unsigned int i = 0; i < 17; ++i)
     {
-        EXPECT_EQ(1, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(2, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(1, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(2, manager.getEntityData<C0>(i)->y);
     }
 
     for(unsigned int i = 3; i < 17; ++i)
@@ -435,22 +438,22 @@ TEST(EC, MultiThreaded)
 
     for(unsigned int i = 0; i < 3; ++i)
     {
-        EXPECT_EQ(1, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(2, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(1, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(2, manager.getEntityData<C0>(i)->y);
     }
 
     manager.forMatchingSignature<EC::Meta::TypeList<C0> >(
-        [] (const std::size_t& eid, C0& c) {
-            c.x = 3;
-            c.y = 4;
+        [] (const std::size_t& eid, C0* c) {
+            c->x = 3;
+            c->y = 4;
         },
         8
     );
 
     for(unsigned int i = 0; i < 3; ++i)
     {
-        EXPECT_EQ(3, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(4, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(3, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(4, manager.getEntityData<C0>(i)->y);
     }
 
     manager.reset();
@@ -459,14 +462,14 @@ TEST(EC, MultiThreaded)
     {
         manager.addEntity();
         manager.addComponent<C0>(i, 0, 0);
-        EXPECT_EQ(0, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(0, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(0, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(0, manager.getEntityData<C0>(i)->y);
     }
 
     auto f0 = manager.addForMatchingFunction<EC::Meta::TypeList<C0> >(
-        [] (const std::size_t& eid, C0& c) {
-            c.x = 1;
-            c.y = 2;
+        [] (const std::size_t& eid, C0* c) {
+            c->x = 1;
+            c->y = 2;
         }
     );
 
@@ -474,14 +477,14 @@ TEST(EC, MultiThreaded)
 
     for(unsigned int i = 0; i < 17; ++i)
     {
-        EXPECT_EQ(1, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(2, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(1, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(2, manager.getEntityData<C0>(i)->y);
     }
 
     auto f1 = manager.addForMatchingFunction<EC::Meta::TypeList<C0> >(
-        [] (const std::size_t& eid, C0& c) {
-            c.x = 3;
-            c.y = 4;
+        [] (const std::size_t& eid, C0* c) {
+            c->x = 3;
+            c->y = 4;
         }
     );
 
@@ -489,8 +492,8 @@ TEST(EC, MultiThreaded)
 
     for(unsigned int i = 0; i < 17; ++i)
     {
-        EXPECT_EQ(3, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(4, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(3, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(4, manager.getEntityData<C0>(i)->y);
     }
 
     for(unsigned int i = 4; i < 17; ++i)
@@ -502,16 +505,16 @@ TEST(EC, MultiThreaded)
 
     for(unsigned int i = 0; i < 4; ++i)
     {
-        EXPECT_EQ(1, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(2, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(1, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(2, manager.getEntityData<C0>(i)->y);
     }
 
     manager.callForMatchingFunction(f1, 8);
 
     for(unsigned int i = 0; i < 4; ++i)
     {
-        EXPECT_EQ(3, manager.getEntityData<C0>(i).x);
-        EXPECT_EQ(4, manager.getEntityData<C0>(i).y);
+        EXPECT_EQ(3, manager.getEntityData<C0>(i)->x);
+        EXPECT_EQ(4, manager.getEntityData<C0>(i)->y);
     }
 }
 
@@ -540,9 +543,9 @@ TEST(EC, ForMatchingSignatures)
             manager.addComponent<C1>(id);
             manager.addTag<T0>(id);
 
-            auto& c1 = manager.getEntityData<C1>(id);
-            c1.vx = 0;
-            c1.vy = 0;
+            auto* c1 = manager.getEntityData<C1>(id);
+            c1->vx = 0;
+            c1->vy = 0;
         }
         else
         {
@@ -556,21 +559,21 @@ TEST(EC, ForMatchingSignatures)
         TypeList<TypeList<C0>, TypeList<C0, C1> >
     >(
         std::make_tuple(
-        [] (std::size_t eid, C0& c) {
-            EXPECT_EQ(c.x, 0);
-            EXPECT_EQ(c.y, 0);
-            c.x = 1;
-            c.y = 1;
+        [] (std::size_t eid, C0* c) {
+            EXPECT_EQ(c->x, 0);
+            EXPECT_EQ(c->y, 0);
+            c->x = 1;
+            c->y = 1;
         },
-        [] (std::size_t eid, C0& c0, C1& c1) {
-            EXPECT_EQ(c0.x, 1);
-            EXPECT_EQ(c0.y, 1);
-            EXPECT_EQ(c1.vx, 0);
-            EXPECT_EQ(c1.vy, 0);
-            c1.vx = c0.x;
-            c1.vy = c0.y;
-            c0.x = 2;
-            c0.y = 2;
+        [] (std::size_t eid, C0* c0, C1* c1) {
+            EXPECT_EQ(c0->x, 1);
+            EXPECT_EQ(c0->y, 1);
+            EXPECT_EQ(c1->vx, 0);
+            EXPECT_EQ(c1->vy, 0);
+            c1->vx = c0->x;
+            c1->vy = c0->y;
+            c0->x = 2;
+            c0->y = 2;
         })
     );
 
@@ -578,15 +581,15 @@ TEST(EC, ForMatchingSignatures)
     {
         if(id != first && id != last)
         {
-            EXPECT_EQ(2, manager.getEntityData<C0>(id).x);
-            EXPECT_EQ(2, manager.getEntityData<C0>(id).y);
-            EXPECT_EQ(1, manager.getEntityData<C1>(id).vx);
-            EXPECT_EQ(1, manager.getEntityData<C1>(id).vy);
+            EXPECT_EQ(2, manager.getEntityData<C0>(id)->x);
+            EXPECT_EQ(2, manager.getEntityData<C0>(id)->y);
+            EXPECT_EQ(1, manager.getEntityData<C1>(id)->vx);
+            EXPECT_EQ(1, manager.getEntityData<C1>(id)->vy);
         }
         else
         {
-            EXPECT_EQ(1, manager.getEntityData<C0>(id).x);
-            EXPECT_EQ(1, manager.getEntityData<C0>(id).y);
+            EXPECT_EQ(1, manager.getEntityData<C0>(id)->x);
+            EXPECT_EQ(1, manager.getEntityData<C0>(id)->y);
         }
     }
 
@@ -609,58 +612,58 @@ TEST(EC, ForMatchingSignatures)
     >
     (
         std::make_tuple(
-        [&first, &last, &cx, &cy, &cxM, &cyM] (std::size_t eid, C0& c) {
+        [&first, &last, &cx, &cy, &cxM, &cyM] (std::size_t eid, C0* c) {
             if(eid != first && eid != last)
             {
                 {
                     std::lock_guard<std::mutex> guard(cxM);
-                    cx.insert(std::make_pair(eid, c.x));
+                    cx.insert(std::make_pair(eid, c->x));
                 }
                 {
                     std::lock_guard<std::mutex> guard(cyM);
-                    cy.insert(std::make_pair(eid, c.y));
+                    cy.insert(std::make_pair(eid, c->y));
                 }
-                c.x = 5;
-                c.y = 7;
+                c->x = 5;
+                c->y = 7;
             }
             else
             {
                 {
                     std::lock_guard<std::mutex> guard(cxM);
-                    cx.insert(std::make_pair(eid, c.x));
+                    cx.insert(std::make_pair(eid, c->x));
                 }
                 {
                     std::lock_guard<std::mutex> guard(cyM);
-                    cy.insert(std::make_pair(eid, c.y));
+                    cy.insert(std::make_pair(eid, c->y));
                 }
-                c.x = 11;
-                c.y = 13;
+                c->x = 11;
+                c->y = 13;
             }
         },
         [&c0x, &c0y, &c1vx, &c1vy, &c0xM, &c0yM, &c1vxM, &c1vyM]
-        (std::size_t eid, C0& c0, C1& c1) {
+        (std::size_t eid, C0* c0, C1* c1) {
             {
                 std::lock_guard<std::mutex> guard(c0xM);
-                c0x.insert(std::make_pair(eid, c0.x));
+                c0x.insert(std::make_pair(eid, c0->x));
             }
             {
                 std::lock_guard<std::mutex> guard(c0yM);
-                c0y.insert(std::make_pair(eid, c0.y));
+                c0y.insert(std::make_pair(eid, c0->y));
             }
             {
                 std::lock_guard<std::mutex> guard(c1vxM);
-                c1vx.insert(std::make_pair(eid, c1.vx));
+                c1vx.insert(std::make_pair(eid, c1->vx));
             }
             {
                 std::lock_guard<std::mutex> guard(c1vyM);
-                c1vy.insert(std::make_pair(eid, c1.vy));
+                c1vy.insert(std::make_pair(eid, c1->vy));
             }
 
-            c1.vx += c0.x;
-            c1.vy += c0.y;
+            c1->vx += c0->x;
+            c1->vy += c0->y;
 
-            c0.x = 1;
-            c0.y = 2;
+            c0->x = 1;
+            c0->y = 2;
         }),
         3
     );
@@ -709,15 +712,15 @@ TEST(EC, ForMatchingSignatures)
     {
         if(eid != first && eid != last)
         {
-            EXPECT_EQ(1, manager.getEntityData<C0>(eid).x);
-            EXPECT_EQ(2, manager.getEntityData<C0>(eid).y);
-            EXPECT_EQ(6, manager.getEntityData<C1>(eid).vx);
-            EXPECT_EQ(8, manager.getEntityData<C1>(eid).vy);
+            EXPECT_EQ(1, manager.getEntityData<C0>(eid)->x);
+            EXPECT_EQ(2, manager.getEntityData<C0>(eid)->y);
+            EXPECT_EQ(6, manager.getEntityData<C1>(eid)->vx);
+            EXPECT_EQ(8, manager.getEntityData<C1>(eid)->vy);
         }
         else
         {
-            EXPECT_EQ(11, manager.getEntityData<C0>(eid).x);
-            EXPECT_EQ(13, manager.getEntityData<C0>(eid).y);
+            EXPECT_EQ(11, manager.getEntityData<C0>(eid)->x);
+            EXPECT_EQ(13, manager.getEntityData<C0>(eid)->y);
         }
     }
 
@@ -726,27 +729,27 @@ TEST(EC, ForMatchingSignatures)
         TypeList<C0, C1>,
         TypeList<C0, C1> > >(
         std::make_tuple(
-            [] (std::size_t eid, C0& c0, C1& c1) {
-                c0.x = 9999;
-                c0.y = 9999;
-                c1.vx = 9999;
-                c1.vy = 9999;
+            [] (std::size_t eid, C0* c0, C1* c1) {
+                c0->x = 9999;
+                c0->y = 9999;
+                c1->vx = 9999;
+                c1->vy = 9999;
             },
-            [] (std::size_t eid, C0& c0, C1& c1) {
-                c0.x = 10000;
-                c0.y = 10000;
-                c1.vx = 10000;
-                c1.vy = 10000;
+            [] (std::size_t eid, C0* c0, C1* c1) {
+                c0->x = 10000;
+                c0->y = 10000;
+                c1->vx = 10000;
+                c1->vy = 10000;
             }
     ));
     for(auto id : e)
     {
         if(id != first && id != last)
         {
-            EXPECT_EQ(10000, manager.getEntityData<C0>(id).x);
-            EXPECT_EQ(10000, manager.getEntityData<C0>(id).y);
-            EXPECT_EQ(10000, manager.getEntityData<C1>(id).vx);
-            EXPECT_EQ(10000, manager.getEntityData<C1>(id).vy);
+            EXPECT_EQ(10000, manager.getEntityData<C0>(id)->x);
+            EXPECT_EQ(10000, manager.getEntityData<C0>(id)->y);
+            EXPECT_EQ(10000, manager.getEntityData<C1>(id)->vx);
+            EXPECT_EQ(10000, manager.getEntityData<C1>(id)->vy);
         }
     };
 }
@@ -782,17 +785,17 @@ TEST(EC, forMatchingPtrs)
         }
     }
 
-    const auto func0 = [] (std::size_t eid, C0& c0, C1& c1)
+    const auto func0 = [] (std::size_t eid, C0* c0, C1* c1)
     {
-        c0.x = 1;
-        c0.y = 2;
-        c1.vx = 3;
-        c1.vy = 4;
+        c0->x = 1;
+        c0->y = 2;
+        c1->vx = 3;
+        c1->vy = 4;
     };
-    const auto func1 = [] (std::size_t eid, C0& c0)
+    const auto func1 = [] (std::size_t eid, C0* c0)
     {
-        c0.x = 11;
-        c0.y = 12;
+        c0->x = 11;
+        c0->y = 12;
     };
 
     using namespace EC::Meta;
@@ -808,24 +811,24 @@ TEST(EC, forMatchingPtrs)
     {
         if(eid != first && eid != last)
         {
-            C0& c0 = manager.getEntityData<C0>(eid);
-            EXPECT_EQ(1, c0.x);
-            EXPECT_EQ(2, c0.y);
-            c0.x = 0;
-            c0.y = 0;
-            C1& c1 = manager.getEntityData<C1>(eid);
-            EXPECT_EQ(3, c1.vx);
-            EXPECT_EQ(4, c1.vy);
-            c1.vx = 0;
-            c1.vy = 0;
+            C0* c0 = manager.getEntityData<C0>(eid);
+            EXPECT_EQ(1, c0->x);
+            EXPECT_EQ(2, c0->y);
+            c0->x = 0;
+            c0->y = 0;
+            C1* c1 = manager.getEntityData<C1>(eid);
+            EXPECT_EQ(3, c1->vx);
+            EXPECT_EQ(4, c1->vy);
+            c1->vx = 0;
+            c1->vy = 0;
         }
         else
         {
-            C0& c = manager.getEntityData<C0>(eid);
-            EXPECT_EQ(11, c.x);
-            EXPECT_EQ(12, c.y);
-            c.x = 0;
-            c.y = 0;
+            C0* c = manager.getEntityData<C0>(eid);
+            EXPECT_EQ(11, c->x);
+            EXPECT_EQ(12, c->y);
+            c->x = 0;
+            c->y = 0;
         }
     }
 
@@ -839,39 +842,39 @@ TEST(EC, forMatchingPtrs)
     {
         if(eid != first && eid != last)
         {
-            C0& c0 = manager.getEntityData<C0>(eid);
-            EXPECT_EQ(1, c0.x);
-            EXPECT_EQ(2, c0.y);
-            c0.x = 0;
-            c0.y = 0;
-            C1& c1 = manager.getEntityData<C1>(eid);
-            EXPECT_EQ(3, c1.vx);
-            EXPECT_EQ(4, c1.vy);
-            c1.vx = 0;
-            c1.vy = 0;
+            C0* c0 = manager.getEntityData<C0>(eid);
+            EXPECT_EQ(1, c0->x);
+            EXPECT_EQ(2, c0->y);
+            c0->x = 0;
+            c0->y = 0;
+            C1* c1 = manager.getEntityData<C1>(eid);
+            EXPECT_EQ(3, c1->vx);
+            EXPECT_EQ(4, c1->vy);
+            c1->vx = 0;
+            c1->vy = 0;
         }
         else
         {
-            C0& c = manager.getEntityData<C0>(eid);
-            EXPECT_EQ(11, c.x);
-            EXPECT_EQ(12, c.y);
-            c.x = 0;
-            c.y = 0;
+            C0* c = manager.getEntityData<C0>(eid);
+            EXPECT_EQ(11, c->x);
+            EXPECT_EQ(12, c->y);
+            c->x = 0;
+            c->y = 0;
         }
     }
 
     // test duplicate signatures
-    const auto setTo9999 = [] (std::size_t eid, C0& c0, C1& c1) {
-        c0.x = 9999;
-        c0.y = 9999;
-        c1.vx = 9999;
-        c1.vy = 9999;
+    const auto setTo9999 = [] (std::size_t eid, C0* c0, C1* c1) {
+        c0->x = 9999;
+        c0->y = 9999;
+        c1->vx = 9999;
+        c1->vy = 9999;
     };
-    const auto setTo10000 = [] (std::size_t eid, C0& c0, C1& c1) {
-        c0.x = 10000;
-        c0.y = 10000;
-        c1.vx = 10000;
-        c1.vy = 10000;
+    const auto setTo10000 = [] (std::size_t eid, C0* c0, C1* c1) {
+        c0->x = 10000;
+        c0->y = 10000;
+        c1->vx = 10000;
+        c1->vy = 10000;
     };
     manager.forMatchingSignaturesPtr<TypeList<
         TypeList<C0, C1>,
@@ -884,10 +887,10 @@ TEST(EC, forMatchingPtrs)
     {
         if(id != first && id != last)
         {
-            EXPECT_EQ(10000, manager.getEntityData<C0>(id).x);
-            EXPECT_EQ(10000, manager.getEntityData<C0>(id).y);
-            EXPECT_EQ(10000, manager.getEntityData<C1>(id).vx);
-            EXPECT_EQ(10000, manager.getEntityData<C1>(id).vy);
+            EXPECT_EQ(10000, manager.getEntityData<C0>(id)->x);
+            EXPECT_EQ(10000, manager.getEntityData<C0>(id)->y);
+            EXPECT_EQ(10000, manager.getEntityData<C1>(id)->vx);
+            EXPECT_EQ(10000, manager.getEntityData<C1>(id)->vy);
         }
     };
 }
index 6dcf850bf5ab920f4c2b0a457d945e2b8e3895ab..02f966c0b50b0e132319c7a12295ea95099e8340 100644 (file)
@@ -77,17 +77,21 @@ TEST(Meta, IndexOf)
     EXPECT_EQ(index, 2);
     index = EC::Meta::IndexOf<C3, ListComponentsAll>::value;
     EXPECT_EQ(index, 3);
+    index = EC::Meta::IndexOf<T0, ListComponentsAll>::value;
+    EXPECT_EQ(index, 4);
 
     index = EC::Meta::IndexOf<C1, ListComponentsSome>::value;
     EXPECT_EQ(index, 0);
     index = EC::Meta::IndexOf<C3, ListComponentsSome>::value;
     EXPECT_EQ(index, 1);
+    index = EC::Meta::IndexOf<C2, ListComponentsSome>::value;
+    EXPECT_EQ(index, 2);
 }
 
 TEST(Meta, Bitset)
 {
     EC::Bitset<ListComponentsAll, ListTagsAll> bitset;
-    EXPECT_EQ(bitset.size(), ListComponentsAll::size + ListTagsAll::size);
+    EXPECT_EQ(bitset.size(), ListComponentsAll::size + ListTagsAll::size + 1);
 
     bitset[EC::Meta::IndexOf<C1, ListComponentsAll>::value] = true;
     EXPECT_TRUE(bitset.getComponentBit<C1>());