]> git.seodisparate.com - EntityComponentMetaSystem/commitdiff
Added capability to store functions
authorStephen Seo <seo.disparate@gmail.com>
Tue, 20 Sep 2016 11:07:28 +0000 (20:07 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Tue, 20 Sep 2016 11:07:28 +0000 (20:07 +0900)
EC::Manager can now store functions similar to functions
given to EC::Manager::forMatchingSignature.

src/EC/Manager.hpp
src/test/ECTest.cpp

index aa44a797f6641386efa7a8f4924fb8669f88f3f5..2338c8dacebd1a427d72fd275263ff81c594607a 100644 (file)
@@ -13,6 +13,7 @@
 #include <vector>
 #include <tuple>
 #include <utility>
+#include <functional>
 
 #include "Meta/Combine.hpp"
 #include "Meta/Matching.hpp"
@@ -226,6 +227,12 @@ namespace EC
                     ctype.template getEntityData<Types>(entityID)...
                 );
             }
+
+            template <typename CType, typename Function>
+            void callInstance(std::size_t entityID, CType& ctype, Function&& function) const
+            {
+                ForMatchingSignatureHelper<Types...>::call(entityID, ctype, std::forward<Function>(function));
+            }
         };
 
     public:
@@ -250,6 +257,47 @@ namespace EC
             }
         }
 
+    private:
+        std::vector<std::function<void()> > forMatchingFunctions;
+
+    public:
+        template <typename Signature, typename Function>
+        void addForMatchingFunction(Function&& function)
+        {
+            using SignatureComponents = typename EC::Meta::Matching<Signature, ComponentsList>::type;
+            using Helper = EC::Meta::Morph<SignatureComponents, ForMatchingSignatureHelper<> >;
+
+            Helper helper;
+            BitsetType signatureBitset = BitsetType::template generateBitset<Signature>();
+
+            forMatchingFunctions.emplace_back( [function, signatureBitset, helper, this] () {
+                for(std::size_t i = 0; i < this->currentSize; ++i)
+                {
+                    if(!std::get<bool>(this->entities[i]))
+                    {
+                        continue;
+                    }
+                    if((signatureBitset & std::get<BitsetType>(this->entities[i])) == signatureBitset)
+                    {
+                        helper.callInstance(i, *this, function);
+                    }
+                }
+            });
+        }
+
+        void callForMatchingFunctions()
+        {
+            for(auto functionIter = forMatchingFunctions.begin(); functionIter != forMatchingFunctions.end(); ++functionIter)
+            {
+                (*functionIter)();
+            }
+        }
+
+        void clearForMatchingFunctions()
+        {
+            forMatchingFunctions.clear();
+        }
+
     };
 }
 
index ee72cd2640982957fe0ded9de2ef67e07b3c40cd..e93d929d9af2e4444ab6419d38ea7d996117fb6f 100644 (file)
@@ -242,3 +242,35 @@ TEST(EC, DeletedEntities)
     }
 }
 
+TEST(EC, FunctionStorage)
+{
+    EC::Manager<ListComponentsAll, ListTagsAll> manager;
+    auto eid = manager.addEntity();
+    manager.addComponent<C0>(eid);
+
+    manager.addForMatchingFunction<EC::Meta::TypeList<C0> >( [] (std::size_t eid, C0& c0) {
+        c0.x = 1;
+        c0.y = 2;
+    });
+
+    manager.callForMatchingFunctions();
+
+    {
+        auto c0 = manager.getEntityData<C0>(eid);
+
+        EXPECT_EQ(c0.x, 1);
+        EXPECT_EQ(c0.y, 2);
+    }
+
+    manager.clearForMatchingFunctions();
+
+    manager.callForMatchingFunctions();
+
+    {
+        auto c0 = manager.getEntityData<C0>(eid);
+
+        EXPECT_EQ(c0.x, 1);
+        EXPECT_EQ(c0.y, 2);
+    }
+}
+