Skip to main content

TypedCommandBuffer.ixx File

Compile-time typed command buffer with handler routing. More...

Included Headers

Namespaces Index

namespacehelios
namespaceengine
namespaceruntime
namespacemessaging
namespacecommand

Classes Index

classTypedCommandBuffer<CommandTypes>

Compile-time typed command buffer with per-type queues and handler routing. More...

Description

Compile-time typed command buffer with handler routing.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
8#include <cassert>
9#include <iostream>
10#include <ostream>
11#include <tuple>
12#include <utility>
13#include <vector>
14
15export module helios.engine.runtime.messaging.command.TypedCommandBuffer;
16
17import helios.engine.state.components;
18
19import helios.engine.runtime.world.UpdateContext;
20import helios.engine.runtime.messaging.command.CommandHandlerRegistry;
21
22import helios.engine.state.commands.DelayedStateCommand;
23
24import helios.engine.runtime.timing.TimerManager;
25import helios.engine.runtime.timing.types;
26
27import helios.engine.runtime.messaging.command.tags.CommandBufferRole;
28
33
35
45 template<typename Cmd>
46 concept ExecutableCommand = requires(Cmd const& c, UpdateContext& updateContext) {
47 {c.execute(updateContext) } noexcept;
48 };
49
60 template<typename Cmd>
61 concept DelayedCommandLike = requires(Cmd const& c) {
62 {c.timerId() } noexcept;
63 };
64
93 template <typename... CommandTypes>
95
96 TimerManager* timerManager_;
97
98 CommandHandlerRegistry* commandHandlerRegistry_;
99
103 std::tuple<std::vector<CommandTypes>...> commandQueues_;
104
112 std::tuple<std::vector<CommandTypes>...> delayedQueues_;
113
121 template<typename CommandType>
122 std::vector<CommandType>& commandQueue() noexcept {
123 return std::get<std::vector<CommandType>>(commandQueues_);
124 }
125
133 template<typename CommandType>
134 std::vector<CommandType>& delayedQueue() noexcept {
135 return std::get<std::vector<CommandType>>(delayedQueues_);
136 }
137
148 [[nodiscard]] bool shouldDelayCommand(const TimerState state) const noexcept {
149 return state == TimerState::Running;
150 }
151
161 [[nodiscard]] bool shouldDiscardCommand(const TimerState state) const noexcept {
162 return state != TimerState::Running && state != TimerState::Finished;;
163 }
164
172 [[nodiscard]] bool isDelayedCommandReady(const TimerState state) const noexcept {
173 return state == TimerState::Finished;
174 }
175
213 template<typename CommandType>
214 void flushCommandQueue(UpdateContext& updateContext) noexcept {
215
216 //auto& timerManager = gameWorld.manager<TimerManager>();
217
218 auto& queue = commandQueue<CommandType>();
220 delayed.clear();
221
222 if (queue.empty()) {
223 return;
224 }
225
226 if (commandHandlerRegistry_->has<CommandType>()) {
227
228 for (auto& cmd : queue) {
229 if constexpr (DelayedCommandLike<CommandType>) {
230 auto* timer = timerManager_->getTimer(cmd.timerId());
231 if (!timer) {
232 assert(timer && "Unexpected null game timer");
233 commandHandlerRegistry_->submit<CommandType>(cmd);
234 continue;
235 }
236
237 if (shouldDelayCommand(timer->state())) {
238 delayed.push_back(std::move(cmd));
239 } else if (isDelayedCommandReady(timer->state())) {
240 commandHandlerRegistry_->submit<CommandType>(cmd);
241 } else if (shouldDiscardCommand(timer->state())) {
242 // cancelled? Discard! intentionally noop
243 }
244 } else {
245 commandHandlerRegistry_->submit<CommandType>(cmd);
246 }
247 }
248
249
250 } else {
251 if constexpr (ExecutableCommand<CommandType>) {
252
253 for (auto& cmd : queue) {
254 if constexpr (DelayedCommandLike<CommandType>) {
255 auto* timer = timerManager_->getTimer(cmd.timerId());
256 if (!timer) {
257 assert(timer && "Unexpected null game timer");
258 cmd.execute(updateContext);
259 continue;
260 }
261
262 if (shouldDelayCommand(timer->state())) {
263 delayed.push_back(std::move(cmd));
264 } else if (isDelayedCommandReady(timer->state())) {
265 cmd.execute(updateContext);
266 } else if (shouldDiscardCommand(timer->state())) {
267 // cancelled? Discard! intentionally noop
268 }
269 } else {
270 cmd.execute(updateContext);
271 }
272
273 }
274
275 } else {
276 std::cerr << "Command type is not executable" << HELIOS_FUNCTION_SIGNATURE << std::endl;
277 assert(false && "Command type is not executable");
278 }
279
280 }
281
282 queue.clear();
283 queue.swap(delayed);
284 delayed.clear();
285 }
286
287 public:
288
290
299 template<typename T, typename... Args>
300 void add(Args&&... args) {
301 auto& queue = std::get<std::vector<T>>(commandQueues_);
302 queue.emplace_back(std::forward<Args>(args)...);
303 }
304
305 void init(CommandHandlerRegistry& commandHandlerRegistry, TimerManager& timerManager) noexcept {
306 commandHandlerRegistry_ = &commandHandlerRegistry;
307 timerManager_ = &timerManager;
308 }
309
313 void clear() noexcept {
314 std::apply([](auto&... queue) { (queue.clear(), ...); }, commandQueues_);
315 }
316
328 }
329
330
331 };
332
333
334}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.