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