Skip to content

Commit

Permalink
Fixed: Duplicates archetype matches in cache after a new archetype ha…
Browse files Browse the repository at this point in the history
…s been added in between queries
  • Loading branch information
richardbiely committed Feb 3, 2024
1 parent babe6ad commit 92198c5
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 35 deletions.
28 changes: 16 additions & 12 deletions include/gaia/ecs/query_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_All.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_All.end())
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
if (idsToMatch.size() == 1) {
Expand Down Expand Up @@ -402,10 +403,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_All.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_All.end())
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
// if (idsToMatch.size() == 1) {
Expand Down Expand Up @@ -447,10 +449,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_Any.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_Any.end())
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
if (idsToMatch.size() == 1) {
Expand Down Expand Up @@ -501,10 +504,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_Any.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_Any.end())
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
// if (idsToMatch.size() == 1) {
Expand Down
28 changes: 16 additions & 12 deletions single_include/gaia.h
Original file line number Diff line number Diff line change
Expand Up @@ -19188,10 +19188,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_All.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_All.end())
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
if (idsToMatch.size() == 1) {
Expand Down Expand Up @@ -19238,10 +19239,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_All.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_All.end())
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_All.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
// if (idsToMatch.size() == 1) {
Expand Down Expand Up @@ -19283,10 +19285,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_Any.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_Any.end())
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
if (idsToMatch.size() == 1) {
Expand Down Expand Up @@ -19337,10 +19340,11 @@ namespace gaia {
const auto cache_it = data.lastMatchedArchetypeIdx_Any.find(EntityLookupKey(ent));
uint32_t lastMatchedIdx = 0;
if (cache_it == data.lastMatchedArchetypeIdx_Any.end())
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), 0U);
else
data.lastMatchedArchetypeIdx_Any.emplace(EntityLookupKey(ent), archetypes.size());
else {
lastMatchedIdx = cache_it->second;
cache_it->second = archetypes.size();
cache_it->second = archetypes.size();
}

// For simple cases it is enough to add archetypes to cache right away
// if (idsToMatch.size() == 1) {
Expand Down
61 changes: 50 additions & 11 deletions src/test/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,17 @@ TEST_CASE("Entity - EntityBad") {
REQUIRE(e.entity());
}

TEST_CASE("Entity copy") {
TestWorld twld;

auto e1 = wld.add();
auto e2 = wld.add();
wld.add(e1, e2);
auto e3 = wld.copy(e1);

REQUIRE(wld.has(e3, e2));
}

TEST_CASE("Add - no components") {
const uint32_t N = 1'500;

Expand Down Expand Up @@ -2302,6 +2313,45 @@ TEST_CASE("Query - QueryResult") {
SECTION("Non-cached query") {
Test_Query_QueryResult<ecs::QueryUncached>();
}
SECTION("Caching") {
struct Player {};
struct Health {
uint32_t value;
};

TestWorld twld;

const auto player = wld.add();
wld.bulk(player).add<Player>().add<Health>();

uint32_t matches = 0;
auto qp = wld.query().all<Health, Player>();
qp.each([&matches]() {
++matches;
});
REQUIRE(matches == 1);

// Add new entity with some new component. Creates a new archetype.
const auto something = wld.add();
wld.add<Something>(something);

// We still need to match the player entity once
matches = 0;
qp.each([&matches]() {
++matches;
});
REQUIRE(matches == 1);

// New the new item also has the health component
wld.add<Health>(something);

// We still need to match the player entity once
matches = 0;
qp.each([&matches]() {
++matches;
});
REQUIRE(matches == 1);
}
}

template <typename TQuery>
Expand Down Expand Up @@ -3825,17 +3875,6 @@ TEST_CASE("Usage 1 - simple query, 0 component") {
}
}

TEST_CASE("Entity copy") {
TestWorld twld;

auto e1 = wld.add();
auto e2 = wld.add();
wld.add(e1, e2);
auto e3 = wld.copy(e1);

REQUIRE(wld.has(e3, e2));
}

TEST_CASE("Usage 1 - simple query, 1 component") {
TestWorld twld;

Expand Down

0 comments on commit 92198c5

Please sign in to comment.