Entity Generator 4.2.0
Composable, deterministic entity generation for C++23
Loading...
Searching...
No Matches
flecs_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_FLECS_ADAPTER_HPP
5#define DASMIG_EXT_FLECS_ADAPTER_HPP
6
7#include "../entitygen.hpp"
8#include <flecs.h>
9#include <functional>
10#include <string>
11#include <vector>
12
13namespace dasmig::ext
14{
15
16/// @file flecs_adapter.hpp
17/// @brief Adapter bridging entity-generator with Flecs.
18
19/// @brief Adapter that bridges entity-generator with Flecs.
20///
21/// Users register mappings from generator component keys to Flecs component
22/// types, then spawn() converts generated entities into Flecs entities with
23/// typed components.
24///
25/// @par Example
26/// @code
27/// flecs::world world;
28/// dasmig::ext::flecs_adapter adapter(world);
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 flecs_entity = adapter.spawn(gen.generate({}));
33/// @endcode
34/// @see entt_adapter
36{
37 public:
38 /// @brief Construct an adapter bound to a Flecs world.
39 /// @param world The Flecs world to create entities in.
40 explicit flecs_adapter(flecs::world& world)
41 : _world{world} {}
42
43 /// @brief Register a transform mapping from a generator key to a Flecs component.
44 ///
45 /// The mapper receives the full generated entity so it can read any
46 /// combination of keys. The component is only set when the specified
47 /// key is present in the generated entity.
48 /// @tparam Component The Flecs component type.
49 /// @param key Generator component key to watch for.
50 /// @param mapper Transform function producing the Flecs component.
51 /// @return `*this` for chaining.
52 template <typename Component>
53 flecs_adapter& map(const std::wstring& key,
54 std::function<Component(const entity&)> mapper)
55 {
56 _mappings.push_back({key,
57 [mapper = std::move(mapper)](flecs::entity target,
58 const entity& src) {
59 target.set<Component>(mapper(src));
60 }});
61 return *this;
62 }
63
64 /// @brief Register a direct mapping (value type matches Flecs component type).
65 /// @tparam Component The Flecs component type.
66 /// @param key Generator component key whose value type is @p Component.
67 /// @return `*this` for chaining.
68 template <typename Component>
69 flecs_adapter& map(const std::wstring& key)
70 {
71 _mappings.push_back({key,
72 [key](flecs::entity target, const entity& src) {
73 target.set<Component>(src.get<Component>(key));
74 }});
75 return *this;
76 }
77
78 /// @brief Create a Flecs entity from a generated entity.
79 ///
80 /// Sets all mapped components whose keys are present.
81 /// @param src The generated entity.
82 /// @return The new Flecs entity.
83 [[nodiscard]] flecs::entity spawn(const entity& src)
84 {
85 auto target = _world.entity();
86 apply(target, src);
87 return target;
88 }
89
90 /// @brief Set mapped components onto an existing Flecs entity.
91 /// @param target The pre-existing Flecs entity.
92 /// @param src The generated entity.
93 void spawn_into(flecs::entity target, const entity& src)
94 {
95 apply(target, src);
96 }
97
98 /// @brief Create Flecs entities for a batch of generated entities.
99 /// @param sources A vector of generated entities.
100 /// @return A vector of new Flecs entities.
101 [[nodiscard]] std::vector<flecs::entity> spawn_batch(
102 const std::vector<entity>& sources)
103 {
104 std::vector<flecs::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 set_fn = std::function<void(flecs::entity, const entity&)>;
123
124 struct mapping
125 {
126 std::wstring key;
127 set_fn apply_component;
128 };
129
130 void apply(flecs::entity target, const entity& src)
131 {
132 for (const auto& m : _mappings)
133 {
134 if (src.has(m.key))
135 {
136 m.apply_component(target, src);
137 }
138 }
139 }
140
141 flecs::world& _world;
142 std::vector<mapping> _mappings;
143};
144
145} // namespace dasmig::ext
146
147#endif // DASMIG_EXT_FLECS_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 Flecs.
std::vector< flecs::entity > spawn_batch(const std::vector< entity > &sources)
Create Flecs entities for a batch of generated entities.
void spawn_into(flecs::entity target, const entity &src)
Set mapped components onto an existing Flecs entity.
flecs::entity spawn(const entity &src)
Create a Flecs entity from a generated entity.
flecs_adapter(flecs::world &world)
Construct an adapter bound to a Flecs world.
flecs_adapter & clear_mappings()
Remove all registered mappings.
flecs_adapter & map(const std::wstring &key, std::function< Component(const entity &)> mapper)
Register a transform mapping from a generator key to a Flecs component.
flecs_adapter & map(const std::wstring &key)
Register a direct mapping (value type matches Flecs component type).