Entity Generator 4.2.0
Composable, deterministic entity generation for C++23
Loading...
Searching...
No Matches
entt_adapter.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2020-2026 Diego Dasso Migotto
3
4#ifndef DASMIG_EXT_ENTT_ADAPTER_HPP
5#define DASMIG_EXT_ENTT_ADAPTER_HPP
6
7#include "../entitygen.hpp"
8#include <entt/entt.hpp>
9#include <functional>
10#include <string>
11#include <vector>
12
13namespace dasmig::ext
14{
15
16/// @file entt_adapter.hpp
17/// @brief Adapter bridging entity-generator with EnTT.
18
19/// @brief Adapter that bridges entity-generator with EnTT.
20///
21/// Users register mappings from generator component keys to EnTT component
22/// types, then spawn() converts generated entities into EnTT entities with
23/// typed components.
24///
25/// @par Example
26/// @code
27/// entt::registry registry;
28/// dasmig::ext::entt_adapter adapter(registry);
29/// adapter.map<Position>(L"pos", [](const dasmig::entity& e) {
30/// return Position{ e.get<float>(L"x"), e.get<float>(L"y") };
31/// });
32/// auto entt_entity = adapter.spawn(gen.generate({}));
33/// @endcode
34/// @see flecs_adapter
36{
37 public:
38 /// @brief Construct an adapter bound to an EnTT registry.
39 /// @param registry The EnTT registry to create entities in.
40 explicit entt_adapter(entt::registry& registry)
41 : _registry{registry} {}
42
43 /// @brief Register a transform mapping from a generator key to an EnTT component.
44 ///
45 /// The mapper receives the full generated entity so it can read any
46 /// combination of keys. The component is only emplaced when the
47 /// specified key is present in the generated entity.
48 /// @tparam Component The EnTT component type to emplace.
49 /// @param key Generator component key to watch for.
50 /// @param mapper Transform function producing the EnTT component.
51 /// @return `*this` for chaining.
52 template <typename Component>
53 entt_adapter& map(const std::wstring& key,
54 std::function<Component(const entity&)> mapper)
55 {
56 _mappings.push_back({key,
57 [mapper = std::move(mapper)](entt::registry& reg,
58 entt::entity target,
59 const entity& src) {
60 reg.emplace<Component>(target, mapper(src));
61 }});
62 return *this;
63 }
64
65 /// @brief Register a direct mapping (value type matches EnTT component type).
66 /// @tparam Component The EnTT component type.
67 /// @param key Generator component key whose value type is @p Component.
68 /// @return `*this` for chaining.
69 template <typename Component>
70 entt_adapter& map(const std::wstring& key)
71 {
72 _mappings.push_back({key,
73 [key](entt::registry& reg, entt::entity target,
74 const entity& src) {
75 reg.emplace<Component>(target,
76 src.get<Component>(key));
77 }});
78 return *this;
79 }
80
81 /// @brief Create an EnTT entity from a generated entity.
82 ///
83 /// Emplaces all mapped components whose keys are present.
84 /// @param src The generated entity.
85 /// @return The new EnTT entity.
86 [[nodiscard]] entt::entity spawn(const entity& src)
87 {
88 auto target = _registry.create();
89 apply(target, src);
90 return target;
91 }
92
93 /// @brief Emplace mapped components onto an existing EnTT entity.
94 /// @param target The pre-existing EnTT entity.
95 /// @param src The generated entity.
96 void spawn_into(entt::entity target, const entity& src)
97 {
98 apply(target, src);
99 }
100
101 /// @brief Create EnTT entities for a batch of generated entities.
102 /// @param sources A vector of generated entities.
103 /// @return A vector of new EnTT entities.
104 [[nodiscard]] std::vector<entt::entity> spawn_batch(
105 const std::vector<entity>& sources)
106 {
107 std::vector<entt::entity> result;
108 result.reserve(sources.size());
109 for (const auto& src : sources)
110 {
111 result.push_back(spawn(src));
112 }
113 return result;
114 }
115
116 /// @brief Remove all registered mappings.
117 /// @return `*this` for chaining.
119 {
120 _mappings.clear();
121 return *this;
122 }
123
124 private:
125 using emplace_fn = std::function<void(entt::registry&, entt::entity,
126 const entity&)>;
127
128 struct mapping
129 {
130 std::wstring key;
131 emplace_fn emplace;
132 };
133
134 void apply(entt::entity target, const entity& src)
135 {
136 for (const auto& m : _mappings)
137 {
138 if (src.has(m.key))
139 {
140 m.emplace(_registry, target, src);
141 }
142 }
143 }
144
145 entt::registry& _registry;
146 std::vector<mapping> _mappings;
147};
148
149} // namespace dasmig::ext
150
151#endif // DASMIG_EXT_ENTT_ADAPTER_HPP
A generated entity holding component values in registration order.
bool has(const std::wstring &component_key) const
Check if a component value exists by key.
Adapter that bridges entity-generator with EnTT.
entt_adapter & clear_mappings()
Remove all registered mappings.
entt_adapter & map(const std::wstring &key)
Register a direct mapping (value type matches EnTT component type).
void spawn_into(entt::entity target, const entity &src)
Emplace mapped components onto an existing EnTT entity.
std::vector< entt::entity > spawn_batch(const std::vector< entity > &sources)
Create EnTT entities for a batch of generated entities.
entt_adapter(entt::registry &registry)
Construct an adapter bound to an EnTT registry.
entt_adapter & map(const std::wstring &key, std::function< Component(const entity &)> mapper)
Register a transform mapping from a generator key to an EnTT component.
entt::entity spawn(const entity &src)
Create an EnTT entity from a generated entity.