Added capability to store functions

EC::Manager can now store functions similar to functions
given to EC::Manager::forMatchingSignature.
This commit is contained in:
Stephen Seo 2016-09-20 20:07:28 +09:00
parent ab2209b698
commit 7c49ab4f04
2 changed files with 80 additions and 0 deletions

View 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();
}
};
}

View 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);
}
}