FECS
Loading...
Searching...
No Matches
view_manager.h
Go to the documentation of this file.
1
5
6#pragma once
8#include "fecs/core/types.h"
11#include <array>
12#include <tuple>
13#include <utility>
14
15namespace FECS
16{
17 using namespace FECS::Manager;
18
27 template <typename... Components>
28 class View
29 {
30 static_assert(sizeof...(Components) >= 1, "View requires at least one component type");
31
32 public:
37 View(EntityManager* entityManagerPointer)
38 : m_Pools(&ComponentManager::GetPool<Components>(entityManagerPointer)...),
39 m_LastVersions{},
40 m_GlobalVersion(false),
41 m_CacheBuilt(false)
42 {
43 m_Cache = {};
44 m_Cache.clear();
45 }
46
51 {
52 }
53
63 template <typename Func>
64 void Each(Func&& fn)
65 {
66 // Check whether the component(s) has changed in version
67 bool dirty = !m_CacheBuilt;
68 std::size_t idx = 0;
69
70 // Iterate through the versions of the components to determine a change.
71 ((dirty |= (ComponentManager::GetVersion<Components>() != m_LastVersions[idx++])), ...);
72 ((dirty |= ComponentManager::GetVersion<GlobalComponent>() != m_GlobalVersion));
73
74 // Its dirty, rebuild the cache.
75 if (dirty)
76 {
77 // Clear the cache
78 m_Cache.clear();
79
80 // Find the smallest pool to use as driver
81 auto sizes = BuildSizes(std::make_index_sequence<N>{});
82 std::size_t driverIdx = 0;
83 std::size_t minSize = sizes[0];
84
85 for (std::size_t i = 1; i < N; i++)
86 {
87 if (sizes[i] < minSize)
88 {
89 minSize = sizes[i];
90 driverIdx = i;
91 }
92 }
93
94 // Use the smallest pool to drive iteration
95 DispatchDriver(driverIdx, std::forward<Func>(fn), std::make_index_sequence<N>{});
96
97 // Declare the cache as clean, and update the version record
98 idx = 0;
99 ((m_LastVersions[idx++] = ComponentManager::GetVersion<Components>()), ...);
101 m_CacheBuilt = true;
102 }
103
104 // Loop and apply function to cached entities.
105 for (Entity e : m_Cache)
106 {
107 Invoke(std::forward<Func>(fn), e, std::make_index_sequence<N>{});
108 }
109 }
110
116 View& Reserve(std::size_t size)
117 {
118 m_Cache.reserve(size);
119
120 return *this;
121 }
122
123 private:
125 template <std::size_t... I>
126 inline std::array<std::size_t, sizeof...(Components)> BuildSizes(std::index_sequence<I...>) const
127 {
128 return {{std::get<I>(m_Pools)->Size()...}};
129 }
130
132 template <typename Func, std::size_t... I>
133 void DispatchDriver(std::size_t driverIdx, Func&& func, std::index_sequence<I...>)
134 {
135 bool handled = ((driverIdx == I && (LoopDriver<I>(func), true)) || ...);
136 (void) handled;
137 }
138
140 template <std::size_t DriverIdx, typename Func>
141 void LoopDriver(Func&& func)
142 {
143 auto* driver = std::get<DriverIdx>(m_Pools);
144 for (std::size_t i = 0, n = driver->Size(); i < n; i++)
145 {
146 Entity e = driver->EntityAt(i);
147 if (!HasAll<DriverIdx>(e))
148 continue;
149
150 m_Cache.push_back(e);
151 }
152 }
153
155 template <std::size_t DriverIdx, std::size_t... I>
156 inline bool HasAllImpl(Entity e, std::index_sequence<I...>) const
157 {
158 return ((I == DriverIdx ? true : std::get<I>(m_Pools)->Has(e)) && ...);
159 }
160
162 template <std::size_t DriverIdx>
163 inline bool HasAll(Entity e) const
164 {
165 return HasAllImpl<DriverIdx>(e, std::make_index_sequence<sizeof...(Components)>{});
166 }
167
169 template <typename Func, std::size_t... I>
170 inline void Invoke(Func&& func, Entity e, std::index_sequence<I...>)
171 {
172 func(e, std::get<I>(m_Pools)->Get(e)...);
173 }
174
175 static constexpr std::size_t N = sizeof...(Components);
176
177 using PoolsTuple = std::tuple<Container::SparseSet<Components>*...>;
178 PoolsTuple m_Pools;
179 bool m_CacheBuilt = false;
180 std::array<size_t, N> m_LastVersions{};
181 std::size_t m_GlobalVersion = 0;
182 std::vector<Entity> m_Cache;
183 };
184}
Provides static access to component pools and handles entity cleanup.
Definition component_manager.h:22
static std::uint32_t & GetVersion()
Returns a per-type version reference for tracking changes.
Definition component_manager.h:66
Manages entity lifecycle, including creation, destruction, and version tracking.
Definition entity_manager.h:21
~View()
Destructor.
Definition view_manager.h:50
View & Reserve(std::size_t size)
Optionally reserves space in the internal cache for predicted number of entities.
Definition view_manager.h:116
void Each(Func &&fn)
Iterates over all entities in the view, Applying a function to each.
Definition view_manager.h:64
View(EntityManager *entityManagerPointer)
Constructs a View given a pointer to the Entity Manager.
Definition view_manager.h:37
Manages component pools and provides utility functions for component lifecycle operations.
Defines the EntityManager, which handles creation and destruction of entities.
Defines the SparseSet data structure for fast component storage and lookup.
Defines core types and constants for the FECS ECS system.
std::uint32_t Entity
Type alias for entity IDs (32-bit unsigned integer)
Definition types.h:28