Skip to main content

System.ixx File

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

Included Headers

#include <cassert> #include <memory> #include <helios.engine.common.concepts> #include <helios.engine.runtime.world.GameWorld> #include <helios.engine.runtime.world.UpdateContext>

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

classSystem

Type-erased wrapper for game logic processors. More...

classConcept

Internal virtual interface for type erasure. More...

classModel<T>

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

Description

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

File Listing

The file content with the documentation metadata removed is:

1/**
2 * @file System.ixx
3 * @brief Type-erased system wrapper using the Concept/Model pattern.
4 */
5module;
6
7#include <cassert>
8#include <memory>
9
10export module helios.engine.runtime.world.System;
11
12
13import helios.engine.runtime.world.UpdateContext;
14import helios.engine.runtime.world.GameWorld;
15
16import helios.engine.common.concepts;
17
20
21export namespace helios::engine::runtime::world {
22
23
24 /**
25 * @brief Type-erased wrapper for game logic processors.
26 *
27 * @details System uses the Concept/Model pattern to erase the concrete
28 * system type. Concrete systems are plain classes that satisfy
29 * `HasUpdate<T>` — they do not inherit from System.
30 *
31 * The internal `Concept` base defines the virtual interface, and
32 * `Model<T>` adapts the concrete type T, owning it by value.
33 * `init()` is conditionally forwarded if `HasInit<T>` is satisfied.
34 *
35 * System is move-only (non-copyable).
36 *
37 * @see HasUpdate
38 * @see HasInit
39 * @see SystemRegistry
40 *
41 * @see https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Type_Erasure
42 */
43 class System {
44
45 private:
46 /**
47 * @brief Internal virtual interface for type erasure.
48 */
49 class Concept {
50 public:
51
52 virtual ~Concept() = default;
53 virtual void update(UpdateContext& updateContext) noexcept = 0;
54 virtual void init(GameWorld& gameWorld) noexcept = 0;
55 virtual void* underlying() noexcept = 0;
56 virtual const void* underlying() const noexcept = 0;
57 };
58
59 /**
60 * @brief Typed wrapper that adapts a concrete system to the Concept interface.
61 *
62 * @tparam T The concrete system type, must satisfy `HasUpdate<T>`.
63 */
64 template<typename T>
65 class Model final : public Concept {
66 T system_;
67
68 public:
69
70
71 explicit Model(T sys) : system_(std::move(sys)) {}
72
73 void update(UpdateContext& updateContext) noexcept override {
74 system_.update(updateContext);
75 }
76 void init(GameWorld& gameWorld) noexcept override {
77 if constexpr (HasInit<T>) {
78 system_.init(gameWorld);
79 }
80 }
81
82 void* underlying() noexcept override {
83 return &system_;
84 }
85
86 const void* underlying() const noexcept override {
87 return &system_;
88 }
89 };
90
91 std::unique_ptr<Concept> pimpl_;
92
93 public:
94
95 /**
96 * @brief Default constructor creating an empty System.
97 */
98 System() = default;
99
100 /**
101 * @brief Wraps a concrete system in a type-erased System.
102 *
103 * @tparam T The concrete system type, must satisfy `HasUpdate<T>`.
104 *
105 * @param system The concrete system instance to wrap (moved into internal storage).
106 */
107 template<typename T>
108 requires HasUpdate<T>
109 explicit System(T system) : pimpl_(std::make_unique<Model<T>>(std::move(system))) {}
110
111 System(const System&) = delete;
112 System& operator=(const System&) = delete;
113
114 System& operator=(System&&) = default;
115 System(System&&) noexcept = default;
116
117
118 /**
119 * @brief Delegates to the wrapped system's `update()` method.
120 *
121 * @param updateContext The current frame's update context.
122 *
123 * @pre System must be initialized (pimpl_ != nullptr).
124 */
125 void update(UpdateContext& updateContext) noexcept {
126 assert(pimpl_ && "System not initialized");
127 pimpl_->update(updateContext);
128 }
129
130 /**
131 * @brief Delegates to the wrapped system's `init()` method, if present.
132 *
133 * @details If the concrete type satisfies `HasInit<T>`, its `init()` is
134 * called. Otherwise this is a no-op.
135 *
136 * @param gameWorld The GameWorld for one-time initialization.
137 *
138 * @pre System must be initialized (pimpl_ != nullptr).
139 */
140 void init(GameWorld& gameWorld) noexcept {
141 assert(pimpl_ && "System not initialized");
142 pimpl_->init(gameWorld);
143 }
144
145 /**
146 * @brief Returns a type-erased pointer to the wrapped system instance.
147 *
148 * @return Pointer to the underlying concrete system.
149 *
150 * @pre System must be initialized (pimpl_ != nullptr).
151 */
152 [[nodiscard]] void* underlying() noexcept {
153 assert(pimpl_ && "System not initialized");
154 return pimpl_->underlying();
155 }
156
157 /**
158 * @copydoc underlying()
159 */
160 [[nodiscard]] const void* underlying() const noexcept {
161 assert(pimpl_ && "System not initialized");
162 return pimpl_->underlying();
163 }
164
165 };
166
167
168}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.