Fix bug with duplicate signatures
Fixed bug where if forMatchingSignatures and forMatchingSignaturesPtr was called with some signatures in the TypeList being duplicates, then only the first duplicate and function pair would be called, and all other functions paired with other duplicate signatures would not be called.
This commit is contained in:
parent
6b0e950c84
commit
506b027655
5 changed files with 290 additions and 141 deletions
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
#include "Meta/Combine.hpp"
|
#include "Meta/Combine.hpp"
|
||||||
#include "Meta/Matching.hpp"
|
#include "Meta/Matching.hpp"
|
||||||
|
#include "Meta/ForEachWithIndex.hpp"
|
||||||
|
#include "Meta/ForEachDoubleTuple.hpp"
|
||||||
#include "Bitset.hpp"
|
#include "Bitset.hpp"
|
||||||
|
|
||||||
namespace EC
|
namespace EC
|
||||||
|
@ -1216,20 +1218,20 @@ namespace EC
|
||||||
the order of entities called is not guaranteed. Otherwise entities
|
the order of entities called is not guaranteed. Otherwise entities
|
||||||
will be called in consecutive order by their ID.
|
will be called in consecutive order by their ID.
|
||||||
*/
|
*/
|
||||||
template <typename SigList, typename FuncTuple>
|
template <typename SigList, typename FTuple>
|
||||||
void forMatchingSignatures(FuncTuple funcTuple,
|
void forMatchingSignatures(
|
||||||
std::size_t threadCount = 1)
|
FTuple fTuple, const std::size_t threadCount = 1)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<std::size_t> > multiMatchingEntities(
|
std::vector<std::vector<std::size_t> > multiMatchingEntities(
|
||||||
SigList::size);
|
SigList::size);
|
||||||
BitsetType signatureBitsets[SigList::size];
|
BitsetType signatureBitsets[SigList::size];
|
||||||
|
|
||||||
// generate bitsets for each signature
|
// generate bitsets for each signature
|
||||||
EC::Meta::forEach<SigList>(
|
EC::Meta::forEachWithIndex<SigList>(
|
||||||
[this, &signatureBitsets] (auto signature) {
|
[this, &signatureBitsets] (auto signature, const auto index) {
|
||||||
signatureBitsets[
|
signatureBitsets[index] =
|
||||||
EC::Meta::IndexOf<decltype(signature), SigList>{} ] =
|
BitsetType::template generateBitset
|
||||||
BitsetType::template generateBitset<decltype(signature)>();
|
<decltype(signature)>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// find and store entities matching signatures
|
// find and store entities matching signatures
|
||||||
|
@ -1255,8 +1257,8 @@ namespace EC
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<std::thread> threads(threadCount);
|
std::vector<std::thread> threads(threadCount);
|
||||||
|
std::mutex mutexes[SigList::size];
|
||||||
std::size_t s = currentSize / threadCount;
|
std::size_t s = currentSize / threadCount;
|
||||||
std::mutex sigsMutexes[SigList::size];
|
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
{
|
{
|
||||||
std::size_t begin = s * i;
|
std::size_t begin = s * i;
|
||||||
|
@ -1270,30 +1272,28 @@ namespace EC
|
||||||
end = s * (i + 1);
|
end = s * (i + 1);
|
||||||
}
|
}
|
||||||
threads[i] = std::thread(
|
threads[i] = std::thread(
|
||||||
[this, &signatureBitsets, &multiMatchingEntities,
|
[this, &mutexes, &multiMatchingEntities, &signatureBitsets]
|
||||||
&sigsMutexes]
|
(std::size_t begin, std::size_t end)
|
||||||
(std::size_t begin, std::size_t end) {
|
{
|
||||||
for(std::size_t eid = begin; eid < end; ++eid)
|
for(std::size_t j = begin; j < end; ++j)
|
||||||
{
|
{
|
||||||
if(!isAlive(eid))
|
if(!isAlive(j))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(std::size_t i = 0; i < SigList::size; ++i)
|
for(std::size_t k = 0; k < SigList::size; ++k)
|
||||||
{
|
{
|
||||||
if((signatureBitsets[i]
|
if((signatureBitsets[k]
|
||||||
& std::get<BitsetType>(entities[eid]))
|
& std::get<BitsetType>(entities[j]))
|
||||||
== signatureBitsets[i])
|
== signatureBitsets[k])
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(
|
std::lock_guard<std::mutex> guard(
|
||||||
sigsMutexes[i]);
|
mutexes[k]);
|
||||||
multiMatchingEntities[i].push_back(eid);
|
multiMatchingEntities[k].push_back(j);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, begin, end);
|
||||||
begin, end);
|
|
||||||
}
|
}
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
{
|
{
|
||||||
|
@ -1302,62 +1302,64 @@ namespace EC
|
||||||
}
|
}
|
||||||
|
|
||||||
// call functions on matching entities
|
// call functions on matching entities
|
||||||
EC::Meta::forEach<SigList>(
|
EC::Meta::forEachDoubleTuple(
|
||||||
[this, &multiMatchingEntities, &funcTuple, &threadCount]
|
EC::Meta::Morph<SigList, std::tuple<> >{},
|
||||||
(auto signature) {
|
fTuple,
|
||||||
using SignatureComponents =
|
[this, &multiMatchingEntities, &threadCount]
|
||||||
typename EC::Meta::Matching<
|
(auto sig, auto func, auto index)
|
||||||
decltype(signature), ComponentsList>::type;
|
|
||||||
using Helper =
|
|
||||||
EC::Meta::Morph<
|
|
||||||
SignatureComponents,
|
|
||||||
ForMatchingSignatureHelper<> >;
|
|
||||||
using Index = EC::Meta::IndexOf<decltype(signature),
|
|
||||||
SigList>;
|
|
||||||
constexpr std::size_t index = Index{};
|
|
||||||
if(threadCount <= 1)
|
|
||||||
{
|
{
|
||||||
for(auto iter = multiMatchingEntities[index].begin();
|
using SignatureComponents =
|
||||||
iter != multiMatchingEntities[index].end(); ++iter)
|
typename EC::Meta::Matching<
|
||||||
|
decltype(sig), ComponentsList>::type;
|
||||||
|
using Helper =
|
||||||
|
EC::Meta::Morph<
|
||||||
|
SignatureComponents,
|
||||||
|
ForMatchingSignatureHelper<> >;
|
||||||
|
if(threadCount <= 1)
|
||||||
{
|
{
|
||||||
Helper::call(*iter, *this,
|
for(const auto& id : multiMatchingEntities[index])
|
||||||
std::get<index>(funcTuple));
|
{
|
||||||
|
Helper::call(id, *this, func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
std::vector<std::thread> threads(threadCount);
|
|
||||||
std::size_t s = multiMatchingEntities[index].size()
|
|
||||||
/ threadCount;
|
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
|
||||||
{
|
{
|
||||||
std::size_t begin = s * i;
|
std::vector<std::thread> threads(threadCount);
|
||||||
std::size_t end;
|
std::size_t s = multiMatchingEntities[index].size()
|
||||||
if(i == threadCount - 1)
|
/ threadCount;
|
||||||
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
{
|
{
|
||||||
end = multiMatchingEntities[index].size();
|
std::size_t begin = s * i;
|
||||||
}
|
std::size_t end;
|
||||||
else
|
if(i == threadCount - 1)
|
||||||
{
|
|
||||||
end = s * (i + 1);
|
|
||||||
}
|
|
||||||
threads[i] = std::thread(
|
|
||||||
[this, &multiMatchingEntities, &funcTuple]
|
|
||||||
(std::size_t begin, std::size_t end)
|
|
||||||
{
|
|
||||||
for(std::size_t j = begin; j < end; ++j)
|
|
||||||
{
|
{
|
||||||
Helper::call(multiMatchingEntities[index][j],
|
end = multiMatchingEntities[index].size();
|
||||||
*this, std::get<index>(funcTuple));
|
|
||||||
}
|
}
|
||||||
}, begin, end);
|
else
|
||||||
}
|
{
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
end = s * (i + 1);
|
||||||
{
|
}
|
||||||
threads[i].join();
|
threads[i] = std::thread(
|
||||||
|
[this, &multiMatchingEntities, &index, &func]
|
||||||
|
(std::size_t begin, std::size_t end)
|
||||||
|
{
|
||||||
|
for(std::size_t j = begin; j < end;
|
||||||
|
++j)
|
||||||
|
{
|
||||||
|
Helper::call(
|
||||||
|
multiMatchingEntities[index][j],
|
||||||
|
*this,
|
||||||
|
func);
|
||||||
|
}
|
||||||
|
}, begin, end);
|
||||||
|
}
|
||||||
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
|
{
|
||||||
|
threads[i].join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -1400,8 +1402,8 @@ namespace EC
|
||||||
the order of entities called is not guaranteed. Otherwise entities
|
the order of entities called is not guaranteed. Otherwise entities
|
||||||
will be called in consecutive order by their ID.
|
will be called in consecutive order by their ID.
|
||||||
*/
|
*/
|
||||||
template <typename SigList, typename FuncTuple>
|
template <typename SigList, typename FTuple>
|
||||||
void forMatchingSignaturesPtr(FuncTuple funcTuple,
|
void forMatchingSignaturesPtr(FTuple fTuple,
|
||||||
std::size_t threadCount = 1)
|
std::size_t threadCount = 1)
|
||||||
{
|
{
|
||||||
std::vector<std::vector<std::size_t> > multiMatchingEntities(
|
std::vector<std::vector<std::size_t> > multiMatchingEntities(
|
||||||
|
@ -1409,11 +1411,11 @@ namespace EC
|
||||||
BitsetType signatureBitsets[SigList::size];
|
BitsetType signatureBitsets[SigList::size];
|
||||||
|
|
||||||
// generate bitsets for each signature
|
// generate bitsets for each signature
|
||||||
EC::Meta::forEach<SigList>(
|
EC::Meta::forEachWithIndex<SigList>(
|
||||||
[this, &signatureBitsets] (auto signature) {
|
[this, &signatureBitsets] (auto signature, const auto index) {
|
||||||
signatureBitsets[
|
signatureBitsets[index] =
|
||||||
EC::Meta::IndexOf<decltype(signature), SigList>{} ] =
|
BitsetType::template generateBitset
|
||||||
BitsetType::template generateBitset<decltype(signature)>();
|
<decltype(signature)>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// find and store entities matching signatures
|
// find and store entities matching signatures
|
||||||
|
@ -1439,8 +1441,8 @@ namespace EC
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<std::thread> threads(threadCount);
|
std::vector<std::thread> threads(threadCount);
|
||||||
|
std::mutex mutexes[SigList::size];
|
||||||
std::size_t s = currentSize / threadCount;
|
std::size_t s = currentSize / threadCount;
|
||||||
std::mutex sigsMutexes[SigList::size];
|
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
{
|
{
|
||||||
std::size_t begin = s * i;
|
std::size_t begin = s * i;
|
||||||
|
@ -1454,30 +1456,28 @@ namespace EC
|
||||||
end = s * (i + 1);
|
end = s * (i + 1);
|
||||||
}
|
}
|
||||||
threads[i] = std::thread(
|
threads[i] = std::thread(
|
||||||
[this, &signatureBitsets, &multiMatchingEntities,
|
[this, &mutexes, &multiMatchingEntities, &signatureBitsets]
|
||||||
&sigsMutexes]
|
(std::size_t begin, std::size_t end)
|
||||||
(std::size_t begin, std::size_t end) {
|
{
|
||||||
for(std::size_t eid = begin; eid < end; ++eid)
|
for(std::size_t j = begin; j < end; ++j)
|
||||||
{
|
{
|
||||||
if(!isAlive(eid))
|
if(!isAlive(j))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(std::size_t i = 0; i < SigList::size; ++i)
|
for(std::size_t k = 0; k < SigList::size; ++k)
|
||||||
{
|
{
|
||||||
if((signatureBitsets[i]
|
if((signatureBitsets[k]
|
||||||
& std::get<BitsetType>(entities[eid]))
|
& std::get<BitsetType>(entities[j]))
|
||||||
== signatureBitsets[i])
|
== signatureBitsets[k])
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(
|
std::lock_guard<std::mutex> guard(
|
||||||
sigsMutexes[i]);
|
mutexes[k]);
|
||||||
multiMatchingEntities[i].push_back(eid);
|
multiMatchingEntities[k].push_back(j);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}, begin, end);
|
||||||
begin, end);
|
|
||||||
}
|
}
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
{
|
{
|
||||||
|
@ -1486,62 +1486,64 @@ namespace EC
|
||||||
}
|
}
|
||||||
|
|
||||||
// call functions on matching entities
|
// call functions on matching entities
|
||||||
EC::Meta::forEach<SigList>(
|
EC::Meta::forEachDoubleTuple(
|
||||||
[this, &multiMatchingEntities, &funcTuple, &threadCount]
|
EC::Meta::Morph<SigList, std::tuple<> >{},
|
||||||
(auto signature) {
|
fTuple,
|
||||||
using SignatureComponents =
|
[this, &multiMatchingEntities, &threadCount]
|
||||||
typename EC::Meta::Matching<
|
(auto sig, auto func, auto index)
|
||||||
decltype(signature), ComponentsList>::type;
|
|
||||||
using Helper =
|
|
||||||
EC::Meta::Morph<
|
|
||||||
SignatureComponents,
|
|
||||||
ForMatchingSignatureHelper<> >;
|
|
||||||
using Index = EC::Meta::IndexOf<decltype(signature),
|
|
||||||
SigList>;
|
|
||||||
constexpr std::size_t index = Index{};
|
|
||||||
if(threadCount <= 1)
|
|
||||||
{
|
{
|
||||||
for(auto iter = multiMatchingEntities[index].begin();
|
using SignatureComponents =
|
||||||
iter != multiMatchingEntities[index].end(); ++iter)
|
typename EC::Meta::Matching<
|
||||||
|
decltype(sig), ComponentsList>::type;
|
||||||
|
using Helper =
|
||||||
|
EC::Meta::Morph<
|
||||||
|
SignatureComponents,
|
||||||
|
ForMatchingSignatureHelper<> >;
|
||||||
|
if(threadCount <= 1)
|
||||||
{
|
{
|
||||||
Helper::callPtr(*iter, *this,
|
for(const auto& id : multiMatchingEntities[index])
|
||||||
std::get<index>(funcTuple));
|
{
|
||||||
|
Helper::callPtr(id, *this, func);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
std::vector<std::thread> threads(threadCount);
|
|
||||||
std::size_t s = multiMatchingEntities[index].size()
|
|
||||||
/ threadCount;
|
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
|
||||||
{
|
{
|
||||||
std::size_t begin = s * i;
|
std::vector<std::thread> threads(threadCount);
|
||||||
std::size_t end;
|
std::size_t s = multiMatchingEntities[index].size()
|
||||||
if(i == threadCount - 1)
|
/ threadCount;
|
||||||
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
{
|
{
|
||||||
end = multiMatchingEntities[index].size();
|
std::size_t begin = s * i;
|
||||||
}
|
std::size_t end;
|
||||||
else
|
if(i == threadCount - 1)
|
||||||
{
|
|
||||||
end = s * (i + 1);
|
|
||||||
}
|
|
||||||
threads[i] = std::thread(
|
|
||||||
[this, &multiMatchingEntities, &funcTuple]
|
|
||||||
(std::size_t begin, std::size_t end)
|
|
||||||
{
|
|
||||||
for(std::size_t j = begin; j < end; ++j)
|
|
||||||
{
|
{
|
||||||
Helper::callPtr(multiMatchingEntities[index][j],
|
end = multiMatchingEntities[index].size();
|
||||||
*this, std::get<index>(funcTuple));
|
|
||||||
}
|
}
|
||||||
}, begin, end);
|
else
|
||||||
}
|
{
|
||||||
for(std::size_t i = 0; i < threadCount; ++i)
|
end = s * (i + 1);
|
||||||
{
|
}
|
||||||
threads[i].join();
|
threads[i] = std::thread(
|
||||||
|
[this, &multiMatchingEntities, &index, &func]
|
||||||
|
(std::size_t begin, std::size_t end)
|
||||||
|
{
|
||||||
|
for(std::size_t j = begin; j < end;
|
||||||
|
++j)
|
||||||
|
{
|
||||||
|
Helper::callPtr(
|
||||||
|
multiMatchingEntities[index][j],
|
||||||
|
*this,
|
||||||
|
func);
|
||||||
|
}
|
||||||
|
}, begin, end);
|
||||||
|
}
|
||||||
|
for(std::size_t i = 0; i < threadCount; ++i)
|
||||||
|
{
|
||||||
|
threads[i].join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
45
src/EC/Meta/ForEachDoubleTuple.hpp
Normal file
45
src/EC/Meta/ForEachDoubleTuple.hpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
// This work derives from Vittorio Romeo's code used for cppcon 2015 licensed
|
||||||
|
// under the Academic Free License.
|
||||||
|
// His code is available here: https://github.com/SuperV1234/cppcon2015
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef EC_META_FOR_EACH_DOUBLE_TUPLE_HPP
|
||||||
|
#define EC_META_FOR_EACH_DOUBLE_TUPLE_HPP
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include "Morph.hpp"
|
||||||
|
|
||||||
|
namespace EC
|
||||||
|
{
|
||||||
|
namespace Meta
|
||||||
|
{
|
||||||
|
template <typename Function, typename TupleFirst,
|
||||||
|
typename TupleSecond, std::size_t... Indices>
|
||||||
|
constexpr void forEachDoubleTupleHelper(
|
||||||
|
Function&& function, TupleFirst t0, TupleSecond t1,
|
||||||
|
std::index_sequence<Indices...>)
|
||||||
|
{
|
||||||
|
return (void)std::initializer_list<int>{(function(
|
||||||
|
std::get<Indices>(t0), std::get<Indices>(t1), Indices), 0)...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TupleFirst, typename TupleSecond, typename Function>
|
||||||
|
constexpr void forEachDoubleTuple(
|
||||||
|
TupleFirst&& t0, TupleSecond&& t1, Function&& function)
|
||||||
|
{
|
||||||
|
using TTupleSize = std::tuple_size<TupleFirst>;
|
||||||
|
using IndexSeq = std::make_index_sequence<TTupleSize::value>;
|
||||||
|
|
||||||
|
return forEachDoubleTupleHelper(
|
||||||
|
std::forward<Function>(function),
|
||||||
|
std::forward<TupleFirst>(t0),
|
||||||
|
std::forward<TupleSecond>(t1),
|
||||||
|
IndexSeq{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
40
src/EC/Meta/ForEachWithIndex.hpp
Normal file
40
src/EC/Meta/ForEachWithIndex.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
// This work derives from Vittorio Romeo's code used for cppcon 2015 licensed
|
||||||
|
// under the Academic Free License.
|
||||||
|
// His code is available here: https://github.com/SuperV1234/cppcon2015
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef EC_META_FOR_EACH_WITH_INDEX_HPP
|
||||||
|
#define EC_META_FOR_EACH_WITH_INDEX_HPP
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <utility>
|
||||||
|
#include "Morph.hpp"
|
||||||
|
|
||||||
|
namespace EC
|
||||||
|
{
|
||||||
|
namespace Meta
|
||||||
|
{
|
||||||
|
template <typename Function, typename TTuple, std::size_t... Indices>
|
||||||
|
constexpr void forEachWithIndexHelper(
|
||||||
|
Function&& function, TTuple tuple, std::index_sequence<Indices...>)
|
||||||
|
{
|
||||||
|
return (void)std::initializer_list<int>{(function(std::move(
|
||||||
|
std::get<Indices>(tuple)), Indices), 0)...};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TTypeList, typename Function>
|
||||||
|
constexpr void forEachWithIndex(Function&& function)
|
||||||
|
{
|
||||||
|
using TTuple = EC::Meta::Morph<TTypeList, std::tuple<> >;
|
||||||
|
using TTupleSize = std::tuple_size<TTuple>;
|
||||||
|
using IndexSeq = std::make_index_sequence<TTupleSize::value>;
|
||||||
|
|
||||||
|
return forEachWithIndexHelper(
|
||||||
|
std::forward<Function>(function), TTuple{}, IndexSeq{});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -12,5 +12,7 @@
|
||||||
#include "IndexOf.hpp"
|
#include "IndexOf.hpp"
|
||||||
#include "Morph.hpp"
|
#include "Morph.hpp"
|
||||||
#include "ForEach.hpp"
|
#include "ForEach.hpp"
|
||||||
|
#include "ForEachWithIndex.hpp"
|
||||||
|
#include "ForEachDoubleTuple.hpp"
|
||||||
#include "Matching.hpp"
|
#include "Matching.hpp"
|
||||||
|
|
||||||
|
|
|
@ -789,6 +789,35 @@ TEST(EC, ForMatchingSignatures)
|
||||||
EXPECT_EQ(13, manager.getEntityData<C0>(eid).y);
|
EXPECT_EQ(13, manager.getEntityData<C0>(eid).y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test duplicate signatures
|
||||||
|
manager.forMatchingSignatures<TypeList<
|
||||||
|
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 = 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);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EC, forMatchingPtrs)
|
TEST(EC, forMatchingPtrs)
|
||||||
|
@ -899,5 +928,36 @@ TEST(EC, forMatchingPtrs)
|
||||||
c.y = 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 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>,
|
||||||
|
TypeList<C0, C1> > >(
|
||||||
|
std::make_tuple(
|
||||||
|
&setTo9999,
|
||||||
|
&setTo10000
|
||||||
|
));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue