Flecs v3.1
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
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) {
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 }
110 }
111
112 flecs::term term(int32_t index) {
113 return flecs::term(m_world, m_filter_ptr->terms[index]);
114 }
115
116 int32_t field_count() {
117 return m_filter_ptr->term_count;
118 }
119
120 flecs::string str() {
121 char *result = ecs_filter_str(m_world, m_filter_ptr);
122 return flecs::string(result);
123 }
124
125 operator filter<>() const;
126
127protected:
128 world_t *m_world = nullptr;
129 filter_t m_filter = ECS_FILTER_INIT;
130 const filter_t *m_filter_ptr;
131};
132
133template<typename ... Components>
134struct filter : filter_base, iterable<Components...> {
135private:
136 using Terms = typename _::term_ptrs<Components...>::array;
137
138public:
139 using filter_base::filter_base;
140
141 filter() : filter_base() { } // necessary not not confuse msvc
142
143 filter(const filter& obj) : filter_base(obj) { }
144
145 filter& operator=(const filter& obj) {
146 filter_base::operator=(obj);
147 return *this;
148 }
149
150 filter(filter&& obj) : filter_base(FLECS_MOV(obj)) { }
151
152 filter& operator=(filter&& obj) {
153 filter_base::operator=(FLECS_FWD(obj));
154 return *this;
155 }
156
157private:
158 ecs_iter_t get_iter(flecs::world_t *world) const override {
159 if (!world) {
160 world = m_world;
161 }
162 return ecs_filter_iter(world, m_filter_ptr);
163 }
164
165 ecs_iter_next_action_t next_action() const override {
166 return ecs_filter_next;
167 }
168
169 ecs_iter_next_action_t next_each_action() const override {
171 }
172};
173
174// World mixin implementation
175template <typename... Comps, typename... Args>
176inline flecs::filter<Comps...> world::filter(Args &&... args) const {
177 return flecs::filter_builder<Comps...>(m_world, FLECS_FWD(args)...)
178 .build();
179}
180
181template <typename... Comps, typename... Args>
182inline flecs::filter_builder<Comps...> world::filter_builder(Args &&... args) const {
183 return flecs::filter_builder<Comps...>(m_world, FLECS_FWD(args)...);
184}
185
186// world::each
187namespace _ {
188
189// Each with entity parameter
190template<typename Func, typename ... Args>
192
193template<typename Func, typename E, typename ... Args>
194struct filter_invoker_w_ent<Func, arg_list<E, Args ...> >
195{
196 filter_invoker_w_ent(const flecs::world& world, Func&& func) {
197 auto f = world.filter<Args ...>();
198 f.each(FLECS_MOV(func));
199 }
200};
201
202// Each without entity parameter
203template<typename Func, typename ... Args>
205
206template<typename Func, typename ... Args>
207struct filter_invoker_no_ent<Func, arg_list<Args ...> >
208{
209 filter_invoker_no_ent(const flecs::world& world, Func&& func) {
210 auto f = world.filter<Args ...>();
211 f.each(FLECS_MOV(func));
212 }
213};
214
215// Switch between function with & without entity parameter
216template<typename Func, typename T = int>
218
219template <typename Func>
220struct filter_invoker<Func, if_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
221 filter_invoker(const flecs::world& world, Func&& func) {
223 }
224};
225
226template <typename Func>
227struct filter_invoker<Func, if_not_t<is_same<first_arg_t<Func>, flecs::entity>::value> > {
228 filter_invoker(const flecs::world& world, Func&& func) {
230 }
231};
232
233}
234
235template <typename Func>
236inline void world::each(Func&& func) const {
237 _::filter_invoker<Func> f_invoker(*this, FLECS_MOV(func));
238}
239
240template <typename T, typename Func>
241inline void world::each(Func&& func) const {
242 ecs_term_t t = {};
243 t.id = _::cpp_type<T>::id();
244 ecs_iter_t it = ecs_term_iter(m_world, &t);
245
246 while (ecs_term_next(&it)) {
247 _::each_invoker<Func, T>(func).invoke(&it);
248 }
249}
250
251template <typename Func>
252inline void world::each(flecs::id_t term_id, Func&& func) const {
253 ecs_term_t t = {};
254 t.id = term_id;
255 ecs_iter_t it = ecs_term_iter(m_world, &t);
256
257 while (ecs_term_next(&it)) {
258 _::each_invoker<Func>(func).invoke(&it);
259 }
260}
261
262// filter_base implementation
263inline filter_base::operator flecs::filter<> () const {
265 ecs_filter_copy(&f.m_filter, &this->m_filter);
266 f.m_filter_ptr = &f.m_filter;
267 f.m_world = this->m_world;
268 return f;
269}
270
271}
#define ecs_abort(error_code,...)
Abort.
Definition: log.h:343
flecs::filter< Comps... > filter(Args &&... args) const
Create a filter.
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:356
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.
Used with ecs_filter_init.
Definition: flecs.h:781
ecs_term_t * terms_buffer
For filters with lots of terms an outside array can be provided.
Definition: flecs.h:789
ecs_filter_t * storage
External storage to prevent allocation of the filter object.
Definition: flecs.h:795
Filters alllow for ad-hoc quick filtering of entity tables.
Definition: flecs.h:566
ecs_term_t * terms
Array containing terms for filter.
Definition: flecs.h:569
int32_t term_count
Number of elements in terms array.
Definition: flecs.h:570
Type that describes a term (single element in a query)
Definition: flecs.h:538
ecs_id_t id
Component id to be matched by term.
Definition: flecs.h:539
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:113
Builder base class.