Flecs v3.2
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
impl.hpp
Go to the documentation of this file.
1
6#pragma once
7
8#include "builder.hpp"
9
10namespace flecs
11{
12
15 : m_world(nullptr)
16 , m_filter({})
17 , m_filter_ptr(nullptr) { }
18
19 filter_base(world_t *world, const ecs_filter_t *filter)
20 : m_world(world)
21 , m_filter({})
22 , m_filter_ptr(filter) { }
23
25 : m_world(world)
26 , m_filter_ptr(&m_filter) {
27 ecs_filter_move(&m_filter, filter);
28 }
29
30 filter_base(world_t *world, ecs_filter_desc_t *desc)
31 : m_world(world)
32 {
33 desc->storage = &m_filter;
34
35 if (ecs_filter_init(world, desc) == NULL) {
36 ecs_abort(ECS_INVALID_PARAMETER, NULL);
37 }
38
39 if (desc->terms_buffer) {
40 ecs_os_free(desc->terms_buffer);
41 }
42
43 m_filter_ptr = &m_filter;
44 }
45
46 filter_base(const filter_base& obj) {
47 this->m_world = obj.m_world;
48 if (obj.m_filter_ptr) {
49 this->m_filter_ptr = &this->m_filter;
50 } else {
51 this->m_filter_ptr = nullptr;
52 }
53 ecs_filter_copy(&m_filter, &obj.m_filter);
54 }
55
56 filter_base& operator=(const filter_base& obj) {
57 this->m_world = obj.m_world;
58 if (obj.m_filter_ptr) {
59 this->m_filter_ptr = &this->m_filter;
60 } else {
61 this->m_filter_ptr = nullptr;
62 }
63 ecs_filter_copy(&m_filter, &obj.m_filter);
64 return *this;
65 }
66
67 filter_base(filter_base&& obj) noexcept {
68 this->m_world = obj.m_world;
69 if (obj.m_filter_ptr) {
70 this->m_filter_ptr = &this->m_filter;
71 } else {
72 this->m_filter_ptr = nullptr;
73 }
74 ecs_filter_move(&m_filter, &obj.m_filter);
75 }
76
77 filter_base& operator=(filter_base&& obj) noexcept {
78 this->m_world = obj.m_world;
79 if (obj.m_filter_ptr) {
80 this->m_filter_ptr = &this->m_filter;
81 } else {
82 this->m_filter_ptr = nullptr;
83 }
84 ecs_filter_move(&m_filter, &obj.m_filter);
85 return *this;
86 }
87
89 return flecs::entity(m_world, ecs_get_entity(m_filter_ptr));
90 }
91
92 operator const flecs::filter_t*() const {
93 return m_filter_ptr;
94 }
95
99 if ((&m_filter == m_filter_ptr) && m_filter_ptr) {
100 ecs_filter_fini(&m_filter);
101 }
102 }
103
104 template <typename Func>
105 void each_term(const Func& func) {
106 for (int i = 0; i < m_filter_ptr->term_count; i ++) {
107 flecs::term t(m_world, m_filter_ptr->terms[i]);
108 func(t);
109 t.reset(); // prevent freeing resources
110 }
111 }
112
113 flecs::term term(int32_t index) {
114 return flecs::term(m_world, m_filter_ptr->terms[index]);
115 }
116
117 int32_t field_count() {
118 return m_filter_ptr->term_count;
119 }
120
121 flecs::string str() {
122 char *result = ecs_filter_str(m_world, m_filter_ptr);
123 return flecs::string(result);
124 }
125
126 operator filter<>() const;
127
128protected:
129 world_t *m_world = nullptr;
130 filter_t m_filter = ECS_FILTER_INIT;
131 const filter_t *m_filter_ptr;
132};
133
134template<typename ... Components>
135struct filter : filter_base, iterable<Components...> {
136private:
137 using Terms = typename _::term_ptrs<Components...>::array;
138
139public:
140 using filter_base::filter_base;
141
142 filter() : filter_base() { } // necessary not to confuse msvc
143
144 filter(const filter& obj) : filter_base(obj) { }
145
146 filter& operator=(const filter& obj) {
147 filter_base::operator=(obj);
148 return *this;
149 }
150
151 filter(filter&& obj) noexcept : filter_base(FLECS_MOV(obj)) { }
152
153 filter& operator=(filter&& obj) noexcept {
154 filter_base::operator=(FLECS_FWD(obj));
155 return *this;
156 }
157
158private:
159 ecs_iter_t get_iter(flecs::world_t *world) const override {
160 if (!world) {
161 world = m_world;
162 }
163 return ecs_filter_iter(world, m_filter_ptr);
164 }
165
166 ecs_iter_next_action_t next_action() const override {
167 return ecs_filter_next;
168 }
169
170 ecs_iter_next_action_t next_each_action() const override {
172 }
173};
174
175// World mixin implementation
176template <typename... Comps, typename... Args>
177inline flecs::filter<Comps...> world::filter(Args &&... args) const {
178 return flecs::filter_builder<Comps...>(m_world, FLECS_FWD(args)...)
179 .build();
180}
181
182template <typename... Comps, typename... Args>
183inline flecs::filter_builder<Comps...> world::filter_builder(Args &&... args) const {
184 return flecs::filter_builder<Comps...>(m_world, FLECS_FWD(args)...);
185}
186
187// world::each
188namespace _ {
189
190// Each with entity parameter
191template<typename Func, typename ... Args>
193
194template<typename Func, typename E, typename ... Args>
195struct filter_delegate_w_ent<Func, arg_list<E, Args ...> >
196{
197 filter_delegate_w_ent(const flecs::world& world, Func&& func) {
198 auto f = world.filter<Args ...>();
199 f.each(FLECS_MOV(func));
200 }
201};
202
203// Each without entity parameter
204template<typename Func, typename ... Args>
206
207template<typename Func, typename ... Args>
208struct filter_delegate_no_ent<Func, arg_list<Args ...> >
209{
210 filter_delegate_no_ent(const flecs::world& world, Func&& func) {
211 auto f = world.filter<Args ...>();
212 f.each(FLECS_MOV(func));
213 }
214};
215
216// Switch between function with & without entity parameter
217template<typename Func, typename T = int>
219
220template <typename Func>
221struct filter_delegate<Func, if_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
222 filter_delegate(const flecs::world& world, Func&& func) {
224 }
225};
226
227template <typename Func>
228struct filter_delegate<Func, if_not_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
229 filter_delegate(const flecs::world& world, Func&& func) {
231 }
232};
233
234}
235
236template <typename Func>
237inline void world::each(Func&& func) const {
238 _::filter_delegate<Func> f_delegate(*this, FLECS_MOV(func));
239}
240
241template <typename T, typename Func>
242inline void world::each(Func&& func) const {
243 ecs_term_t t = {};
244 t.id = _::cpp_type<T>::id();
245 ecs_iter_t it = ecs_term_iter(m_world, &t);
246
247 while (ecs_term_next(&it)) {
248 _::each_delegate<Func, T>(func).invoke(&it);
249 }
250}
251
252template <typename Func>
253inline void world::each(flecs::id_t term_id, Func&& func) const {
254 ecs_term_t t = {};
255 t.id = term_id;
256 ecs_iter_t it = ecs_term_iter(m_world, &t);
257
258 while (ecs_term_next(&it)) {
259 _::each_delegate<Func>(func).invoke(&it);
260 }
261}
262
263// filter_base implementation
264inline filter_base::operator flecs::filter<> () const {
266 ecs_filter_copy(&f.m_filter, &this->m_filter);
267 f.m_filter_ptr = &f.m_filter;
268 f.m_world = this->m_world;
269 return f;
270}
271
272}
#define ecs_abort(error_code,...)
Abort.
Definition log.h:342
flecs::filter< Comps... > filter(Args &&... args) const
Create a filter.
void each(Func &&func) const
Iterate over all entities with components in argument list of function.
flecs::filter_builder< Comps... > filter_builder(Args &&... args) const
Create a filter builder.
ecs_filter_t * ecs_filter_init(ecs_world_t *world, const ecs_filter_desc_t *desc)
Initialize filter A filter is a lightweight object that can be used to query for entities in a world.
bool ecs_filter_next(ecs_iter_t *it)
Iterate tables matched by filter.
ecs_iter_t ecs_filter_iter(const ecs_world_t *world, const ecs_filter_t *filter)
Return a filter iterator.
char * ecs_filter_str(const ecs_world_t *world, const ecs_filter_t *filter)
Convert filter to string expression.
void ecs_filter_fini(ecs_filter_t *filter)
Deinitialize filter.
bool ecs_filter_next_instanced(ecs_iter_t *it)
Same as ecs_filter_next, but always instanced.
bool ecs_term_next(ecs_iter_t *it)
Progress a term iterator.
void ecs_filter_move(ecs_filter_t *dst, ecs_filter_t *src)
Move resources of one filter to another.
void ecs_filter_copy(ecs_filter_t *dst, const ecs_filter_t *src)
Copy resources of one filter to another.
ecs_iter_t ecs_term_iter(const ecs_world_t *world, ecs_term_t *term)
Iterator for a single (component) id.
bool(* ecs_iter_next_action_t)(ecs_iter_t *it)
Function prototype for iterating an iterator.
Definition flecs.h:567
ecs_filter_t ECS_FILTER_INIT
Use $this variable to initialize user-allocated filter object.
ecs_entity_t ecs_get_entity(const ecs_poly_t *poly)
Get entity from poly.
Filter builder.
Used with ecs_filter_init().
Definition flecs.h:998
ecs_term_t * terms_buffer
For filters with lots of terms an outside array can be provided.
Definition flecs.h:1006
ecs_filter_t * storage
External storage to prevent allocation of the filter object.
Definition flecs.h:1012
Filters allow for ad-hoc quick filtering of entity tables.
Definition flecs.h:786
ecs_term_t * terms
Array containing terms for filter.
Definition flecs.h:794
int8_t term_count
Number of elements in terms array.
Definition flecs.h:789
Type that describes a term (single element in a query)
Definition flecs.h:758
ecs_id_t id
Component id to be matched by term.
Definition flecs.h:759
Entity.
Definition entity.hpp:30
~filter_base()
Free the filter.
Definition impl.hpp:98
Filter builder.
Definition builder.hpp:24
Class that describes a term.
Definition impl.hpp:16
The world.
Definition world.hpp:132