Skip to main content

Manager.ixx File

Type-erased manager wrapper using the Concept/Model pattern. More...

Included Headers

#include <cassert> #include <memory> #include <helios.engine.common.concepts.IsManagerLike>

Namespaces Index

namespacehelios
namespaceengine

Main engine module aggregating core infrastructure and game systems. More...

namespaceruntime

Runtime infrastructure for game execution and lifecycle orchestration. More...

namespaceworld

World state management, resource registry, and per-frame update context. More...

Classes Index

classManager

Type-erased wrapper for game world managers. More...

classConcept

Internal virtual interface for type erasure. More...

classModel<T>

Typed wrapper that adapts a concrete manager to the Concept interface. More...

Description

Type-erased manager wrapper using the Concept/Model pattern.

File Listing

The file content with the documentation metadata removed is:

1/**
2 * @file Manager.ixx
3 * @brief Type-erased manager wrapper using the Concept/Model pattern.
4 */
5module;
6
7#include <cassert>
8#include <memory>
9
10export module helios.engine.runtime.world.Manager;
11
12import helios.engine.common.concepts.IsManagerLike;
13
15
16export namespace helios::engine::runtime::world {
17
18 class UpdateContext;
19 class GameWorld;
20
21 /**
22 * @brief Concept detecting an optional `init(GameWorld&)` method on a manager.
23 *
24 * @tparam T The manager type to inspect.
25 */
26 template<typename T>
27 concept HasInit = requires(T& t, GameWorld& gameWorld) {
28 {t.init(gameWorld) } -> std::same_as<void>;
29 };
30
31 /**
32 * @brief Concept detecting an optional `reset()` method on a manager.
33 *
34 * @tparam T The manager type to inspect.
35 */
36 template<typename T>
37 concept HasReset = requires(T& t) {
38 {t.reset() } -> std::same_as<void>;
39 };
40
41
42
43 /**
44 * @brief Type-erased wrapper for game world managers.
45 *
46 * @details Manager uses the Concept/Model pattern to erase the concrete
47 * manager type. Concrete managers are plain classes that satisfy
48 * `IsManagerLike<T>` (i.e. provide `flush(UpdateContext&)` and declare
49 * `using EngineRoleTag = ManagerRole;`).
50 *
51 * The internal `Concept` base defines the virtual interface, and
52 * `Model<T>` adapts the concrete type T, owning it by value.
53 * `init()` and `reset()` are conditionally forwarded if the concrete
54 * type satisfies `HasInit<T>` or `HasReset<T>` respectively.
55 *
56 * Manager is move-only (non-copyable).
57 *
58 * @see IsManagerLike
59 * @see ManagerRole
60 * @see ManagerRegistry
61 * @see ConceptModelRegistry
62 */
63 class Manager {
64
65 private:
66 /**
67 * @brief Internal virtual interface for type erasure.
68 */
69 class Concept {
70 public:
71 virtual ~Concept() = default;
72 virtual void flush(UpdateContext& updateContext) noexcept = 0;
73 virtual void init(GameWorld& gameWorld) noexcept = 0;
74 virtual void reset() noexcept = 0;
75
76 [[nodiscard]] virtual void* underlying() noexcept = 0;
77 [[nodiscard]] virtual const void* underlying() const noexcept = 0;
78 };
79
80 /**
81 * @brief Typed wrapper that adapts a concrete manager to the Concept interface.
82 *
83 * @tparam T The concrete manager type, must satisfy `IsManagerLike<T>`.
84 */
85 template<typename T>
86 class Model final : public Concept {
87 T manager_;
88
89 public:
90
91 explicit Model(T sys) : manager_(std::move(sys)) {}
92
93 void flush(UpdateContext& updateContext) noexcept override {
94 manager_.flush(updateContext);
95 }
96 void init(GameWorld& gameWorld) noexcept override {
97 if constexpr (HasInit<T>) {
98 manager_.init(gameWorld);
99 }
100 }
101 void reset() noexcept override {
102 if constexpr (HasReset<T>) {
103 manager_.reset();
104 }
105 }
106
107 void* underlying() noexcept override {
108 return &manager_;
109 }
110
111 const void* underlying() const noexcept override {
112 return &manager_;
113 }
114 };
115
116 std::unique_ptr<Concept> pimpl_;
117
118 public:
119
120 /**
121 * @brief Default constructor creating an empty Manager.
122 */
123 Manager() = default;
124
125 /**
126 * @brief Wraps a concrete manager in a type-erased Manager.
127 *
128 * @tparam T The concrete manager type, must satisfy `IsManagerLike<T>`.
129 *
130 * @param manager The concrete manager instance to wrap (moved into internal storage).
131 */
132 template<typename T>
133 requires IsManagerLike<T>
134 explicit Manager(T manager) : pimpl_(std::make_unique<Model<T>>(std::move(manager))) {}
135
136 Manager(const Manager&) = delete;
137 Manager& operator=(const Manager&) = delete;
138
139 Manager& operator=(Manager&&) = default;
140 Manager(Manager&&) noexcept = default;
141
142
143 /**
144 * @brief Delegates to the wrapped manager's `flush()` method.
145 *
146 * @details Called by the GameLoop at each commit point after
147 * CommandBuffers have been flushed. Managers process their
148 * accumulated requests in batch.
149 *
150 * @param updateContext The current frame's update context.
151 *
152 * @pre Manager must be initialized (pimpl_ != nullptr).
153 */
154 void flush(UpdateContext& updateContext) noexcept {
155 assert(pimpl_ && "Manager not initialized");
156 pimpl_->flush(updateContext);
157 }
158
159
160 /**
161 * @brief Delegates to the wrapped manager's `init()` method, if present.
162 *
163 * @details If the concrete type satisfies `HasInit<T>`, its `init()` is
164 * called. Otherwise this is a no-op. Typically used by managers to
165 * register their TypedCommandHandlers with the GameWorld.
166 *
167 * @param gameWorld The GameWorld for one-time initialization.
168 *
169 * @pre Manager must be initialized (pimpl_ != nullptr).
170 */
171 void init(GameWorld& gameWorld) noexcept {
172 assert(pimpl_ && "Manager not initialized");
173 pimpl_->init(gameWorld);
174 }
175
176 /**
177 * @brief Delegates to the wrapped manager's `reset()` method, if present.
178 *
179 * @details If the concrete type satisfies `HasReset<T>`, its `reset()` is
180 * called. Otherwise this is a no-op. Used during level transitions or
181 * game restarts to clear accumulated state.
182 *
183 * @pre Manager must be initialized (pimpl_ != nullptr).
184 */
185 void reset() noexcept {
186 assert(pimpl_ && "Manager not initialized");
187 pimpl_->reset();
188 }
189
190 /**
191 * @brief Returns a type-erased pointer to the wrapped manager instance.
192 *
193 * @return Pointer to the underlying concrete manager.
194 *
195 * @pre Manager must be initialized (pimpl_ != nullptr).
196 */
197 [[nodiscard]] void* underlying() noexcept {
198 assert(pimpl_ && "Manager not initialized");
199 return pimpl_->underlying();
200 }
201
202 /**
203 * @copydoc underlying()
204 */
205 [[nodiscard]] const void* underlying() const noexcept {
206 assert(pimpl_ && "Manager not initialized");
207 return pimpl_->underlying();
208 }
209
210 };
211
212
213}
214

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.