Skip to main content

EntityMutationManager.ixx File

Applies deferred entity-mutation commands to the ECS world. More...

Included Headers​

#include <vector> #include <format> #include "helios-engine-config.h" #include <optional> #include <algorithm> #include <iterator> #include <cassert> #include <helios.engine.util.log> #include <helios.ecs.concepts.Traits> #include <helios.engine.runtime.world.UpdateContext> #include <helios.ecs.commands> #include <helios.engine.runtime.messaging.command.types.CommandBufferTypeId> #include <helios.ecs.types.ComponentTypeId> #include <helios.engine.core.thread.JobSystem> #include <helios.engine.runtime.messaging.command.tags.CommandBufferRole> #include <helios.engine.runtime.world.tags.ManagerRole> #include <helios.engine.runtime.messaging.command.CommandBuffer> #include <helios.ecs.types> #include <helios.engine.runtime.world.ManagerRegistry> #include <helios.engine.runtime.messaging.command.CommandBufferRegistry> #include <helios.engine.runtime.messaging.command.CommandHandlerRegistry> #include <helios.ecs.components>

Namespaces Index​

namespacehelios
namespaceengine
namespaceruntime
namespaceworld
namespacecommands

Classes Index​

classEntityMutationManager<TEntityManager>

Receives submitted ECS mutation commands and applies them during flush. More...

classInternalBuffer<TCommandType>

Per-command-type buffer that applies mutations on flush. More...

Macro Definitions Index​

#defineHELIOS_LOG_SCOPE   "helios::engine::runtime::world::EntityMutationManager"

Description​

Applies deferred entity-mutation commands to the ECS world.

Macro Definitions​

HELIOS_LOG_SCOPE​

#define HELIOS_LOG_SCOPE   "helios::engine::runtime::world::EntityMutationManager"

Definition at line 53 of file EntityMutationManager.ixx.

53#define HELIOS_LOG_SCOPE "helios::engine::runtime::world::EntityMutationManager"

File Listing​

The file content with the documentation metadata removed is:

1
5module;
6
7#include <vector>
8#include <format>
10#include <optional>
11#include <algorithm>
12#include <iterator>
13#include <cassert>
14
15export module helios.engine.runtime.world.EntityMutationManager;
16
17import helios.ecs.commands;
18import helios.ecs.types.ComponentTypeId;
19
20import helios.engine.core.thread.JobSystem;
21
22import helios.engine.runtime.world.tags.ManagerRole;
23import helios.engine.runtime.messaging.command.CommandBuffer;
24import helios.engine.runtime.messaging.command.types.CommandBufferTypeId;
25import helios.engine.runtime.messaging.command.CommandBufferRegistry;
26import helios.engine.runtime.messaging.command.tags.CommandBufferRole;
27
28import helios.engine.runtime.messaging.command.CommandHandlerRegistry;
29import helios.engine.runtime.world.ManagerRegistry;
30
31import helios.ecs.types;
32import helios.ecs.components;
33
34
35import helios.engine.util.log;
36import helios.engine.runtime.world.UpdateContext;
37
38import helios.ecs.concepts.Traits;
39import helios.engine.util.log;
40
41using namespace helios::ecs::components;
42using namespace helios::engine::core::thread;
47using namespace helios::ecs::types;
48using namespace helios::ecs::concepts::traits;
49using namespace helios::ecs::commands;
50using namespace helios::engine::util::log;
52
53#define HELIOS_LOG_SCOPE "helios::engine::runtime::world::EntityMutationManager"
54export namespace helios::engine::runtime::world {
55
56
67 template<typename TEntityManager>
69
71 using THandle = typename TEntityManager::Handle_type;
72
74 TEntityManager& entityManager_;
75
77 CommandBufferRegistry commandBufferRegistry_{};
78
80 CommandHandlerRegistry* commandHandlerRegistry_{nullptr};
81
83 JobSystem& jobSystem_;
84
91 std::vector<std::vector<CommandBufferTypeId>> componentToBufferGroups_{};
92
94 std::vector<std::size_t> bufferGroupIndices_;
95
98
107 template<typename TCommandType>
108 class InternalBuffer {
109
110 CommandHandlerRegistry* commandHandlerRegistry_{nullptr};
111
112 std::vector<TCommandType> commands_;
113
114 TEntityManager& entityManager_;
115
116 public:
119
121 using Command_type = TCommandType;
122
124 using Component_type = typename TCommandType::Component_type;
125
127 InternalBuffer(TEntityManager& entityManager) : entityManager_(entityManager) {
129 }
130
138 void flush(UpdateContext& updateContext)
140
141 using Component_type = typename TCommandType::Component_type;
142
143 logger_.info("Processing {0} commands", commands_.size());
144
145 for (auto& command : commands_) {
146 if (!entityManager_.isValid(command.handle)) {
147 continue;
148 }
150 entityManager_.template emplace<Component_type>(command.handle, std::move(command.component));
151 } else {
152 entityManager_.template remove<Component_type>(command.handle);
153 }
154 }
155
156 clear();
157 }
158
159
161 void clear() {
162 commands_.clear();
163 }
164
166 void init(CommandHandlerRegistry& commandHandlerRegistry, ManagerRegistry& managerRegistry) {/* noop*/ }
167
173 void add(TCommandType commandType) {
174 commands_.emplace_back(std::forward<TCommandType>(commandType));
175 }
176
177 };
178
185 template<typename TCommand>
186 auto* modelFor() {
187
188 auto* model = commandBufferRegistry_.item<InternalBuffer<TCommand>>();
189
190 if (!model) {
191 auto& created =
192 commandBufferRegistry_.add<InternalBuffer<TCommand>>(
194 );
195
196 using Component_type = typename TCommand::Component_type;
197 const auto cv = ComponentTypeId<THandle>::template id<Component_type>().value();
198
199 if (componentToBufferGroups_.size() <= cv) {
200 componentToBufferGroups_.resize(cv + 1);
201 }
202
203 if (componentToBufferGroups_[cv].empty()) {
204 bufferGroupIndices_.push_back(cv);
205 }
206 componentToBufferGroups_[cv].push_back(CommandBufferTypeId::template id<InternalBuffer<TCommand>>());
207
210 }
211 std::ignore = entityManager_.template ensureSparseSet<Component_type>();
212
213 return &created;
214 }
215
216 return model;
217 }
218
219 public:
220
222 using Handle_type = THandle;
223
226
234 : entityManager_(entity_manager), jobSystem_(jobSystem) {}
235
245 template<typename TCommand>
246 requires std::is_same_v<typename TCommand::Handle_type, THandle>
247 bool submit(TCommand&& command) {
248
249 using Command_type = std::remove_cvref_t<TCommand>;
250
262
263
268
269 modelAddAct->add(AddActive_type(command.handle));
270 modelAddActiveDirty->add(AddActiveDirty_type(command.handle));
271 modelRemoveInact->add(RemoveInactive_type(command.handle));
272
273 } else {
274
278
279 modelRemoveAct->add(RemoveActive_type(command.handle));
280 modelAddInactiveDirty->add(AddInactiveDirty_type(command.handle));
281 modelAddInact->add(AddInactive_type(command.handle));
282 }
283
284 } else {
285 auto* model = modelFor<Command_type>();
286 model->add(std::forward<TCommand>(command));
287 }
288
289
290
291 return true;
292 }
293
299 void init(CommandHandlerRegistry& commandHandlerRegistry) {}
300
307 for (auto* buffer : commandBufferRegistry_.items()) {
308 buffer->flush(updateContext);
309 }
310
311 }
312
322
323 std::vector<std::size_t> activeIndices;
324 for (const auto idx : bufferGroupIndices_) {
325 if (!componentToBufferGroups_[idx].empty()) {
326 activeIndices.push_back(idx);
327 }
328 }
329 jobSystem_.runAndWait(activeIndices.size(), [&](const std::size_t groupIndex) {
330 for (const auto bufferTypeId : componentToBufferGroups_[activeIndices[groupIndex]]) {
331 logger_.info("Processing MutationCommandBuffer {0}", bufferTypeId.value());
332 auto* buffer = commandBufferRegistry_.item(bufferTypeId);
333 buffer->flush(updateContext);
334 }
335 });
336 }
337
338
339 };
340
341
342}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.