Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
query_cache.cpp
Go to the documentation of this file.
2
6
7#include <algorithm>
8#include <atomic>
9#include <cstddef>
10#include <span>
11#include <utility>
12#include <vector>
13
14namespace helios::ecs::details {
15
16size_t QueryCacheManager::ComputeQueryHash(std::span<const ComponentTypeId> with_components,
17 std::span<const ComponentTypeId> without_components) {
18 // Components should already be sorted by caller
19 size_t hash = 0;
20
21 // Hash "with" components
22 for (const auto& id : with_components) {
23 hash ^= std::hash<ComponentTypeId>{}(id) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
24 }
25
26 // Hash "without" components with different mixing to distinguish from "with"
27 for (const auto& id : without_components) {
28 hash ^= std::hash<ComponentTypeId>{}(id) + 0x517cc1b7 + (hash << 7) + (hash >> 3);
29 }
30
31 return hash;
32}
33
34bool QueryCacheManager::QueryInvolvesAnyComponents(const QueryState& state,
35 std::span<const ComponentTypeId> component_ids) {
36 // Check if any of the component_ids appear in the query's with or without lists
37 return std::ranges::any_of(component_ids, [&state](const ComponentTypeId id) {
38 return std::ranges::binary_search(state.with_component_types, id) ||
39 std::ranges::binary_search(state.without_component_types, id);
40 });
41}
42
43void QueryCacheManager::StoreCache(std::span<const ComponentTypeId> with_components,
44 std::span<const ComponentTypeId> without_components,
45 std::vector<std::reference_wrapper<const Archetype>> matching_archetypes,
46 size_t current_generation) {
47 const size_t hash = ComputeQueryHash(with_components, without_components);
48
50 state.matching_archetypes = std::move(matching_archetypes);
51 state.archetype_generations.reserve(state.matching_archetypes.size());
52
53 // Store each archetype's current generation for validation
54 for (const auto& archetype_ref : state.matching_archetypes) {
55 state.archetype_generations.push_back(archetype_ref.get().GetGeneration());
56 }
57
58 state.with_component_types.assign(with_components.begin(), with_components.end());
59 state.without_component_types.assign(without_components.begin(), without_components.end());
60 state.query_generation = current_generation;
61 state.query_hash = hash;
62 state.last_access_time.store(access_counter_.fetch_add(1, std::memory_order_relaxed), std::memory_order_relaxed);
63
64 cache_.insert_or_assign(hash, std::move(state));
65}
66
68 // Quick check: world generation mismatch
69 if (state.query_generation != current_generation) {
70 return false;
71 }
72
73 // Validate each cached archetype's generation
74 HELIOS_ASSERT(state.matching_archetypes.size() == state.archetype_generations.size(),
75 "Archetype count mismatch in query state! Expected {}, got {}", state.matching_archetypes.size(),
76 state.archetype_generations.size());
77
78 for (size_t i = 0; i < state.matching_archetypes.size(); ++i) {
79 const Archetype& archetype = state.matching_archetypes[i].get();
80 const size_t cached_generation = state.archetype_generations[i];
81
82 // Check if archetype structure has changed
83 if (archetype.GetGeneration() != cached_generation) {
84 return false;
85 }
86 }
87
88 return true;
89}
90
91} // namespace helios::ecs::details
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:140
iterator begin() const
Gets iterator to first matching entity.
Definition query.hpp:2317
iterator end() const noexcept
Gets iterator past the last matching entity.
Definition query.hpp:1603
Represents a unique combination of component types.
Definition archetype.hpp:64
void StoreCache(std::span< const ComponentTypeId > with_components, std::span< const ComponentTypeId > without_components, std::vector< std::reference_wrapper< const Archetype > > matching_archetypes, size_t current_generation)
Stores or updates a query state in the cache.
static bool ValidateQueryState(const QueryState &state, size_t current_generation)
Validates a cached query state against current archetype generations.
size_t ComponentTypeId
Type ID for components.
BasicQuery< World, Allocator, Components... > Query
Type alias for query with mutable world access.
Definition query.hpp:2481
Query state that caches archetype matching results.