1 #include <tuple>
2 #include <cstddef>
3 #include <type_traits>
4 #include <gtest/gtest.h>
5 #include <entt/entity/observer.hpp>
6 #include <entt/entity/registry.hpp>
7
TEST(Observer,Functionalities)8 TEST(Observer, Functionalities) {
9 entt::registry registry;
10 entt::observer observer{registry, entt::collector.group<int>()};
11
12 ASSERT_EQ(observer.size(), 0u);
13 ASSERT_TRUE(observer.empty());
14 ASSERT_EQ(observer.begin(), observer.end());
15
16 const auto entity = registry.create();
17 registry.emplace<int>(entity);
18
19 ASSERT_EQ(observer.size(), 1u);
20 ASSERT_FALSE(observer.empty());
21 ASSERT_EQ(*observer.data(), entity);
22 ASSERT_NE(observer.begin(), observer.end());
23 ASSERT_EQ(++observer.begin(), observer.end());
24 ASSERT_EQ(*observer.begin(), entity);
25
26 observer.clear();
27
28 ASSERT_EQ(observer.size(), 0u);
29 ASSERT_TRUE(observer.empty());
30
31 observer.disconnect();
32 registry.erase<int>(entity);
33 registry.emplace<int>(entity);
34
35 ASSERT_EQ(observer.size(), 0u);
36 ASSERT_TRUE(observer.empty());
37 }
38
TEST(Observer,AllOf)39 TEST(Observer, AllOf) {
40 constexpr auto collector = entt::collector
41 .group<int, char>(entt::exclude<float>)
42 .group<int, double>();
43
44 entt::registry registry;
45 entt::observer observer{registry, collector};
46 const auto entity = registry.create();
47
48 ASSERT_TRUE(observer.empty());
49
50 registry.emplace<int>(entity);
51 registry.emplace<char>(entity);
52
53 ASSERT_EQ(observer.size(), 1u);
54 ASSERT_FALSE(observer.empty());
55 ASSERT_EQ(*observer.data(), entity);
56
57 registry.emplace<double>(entity);
58
59 ASSERT_FALSE(observer.empty());
60
61 registry.erase<int>(entity);
62
63 ASSERT_TRUE(observer.empty());
64
65 registry.emplace<float>(entity);
66 registry.emplace<int>(entity);
67
68 ASSERT_FALSE(observer.empty());
69
70 registry.erase<double>(entity);
71
72 ASSERT_TRUE(observer.empty());
73
74 registry.emplace<double>(entity);
75 observer.clear();
76
77 ASSERT_TRUE(observer.empty());
78
79 observer.disconnect();
80 registry.emplace_or_replace<int>(entity);
81 registry.emplace_or_replace<char>(entity);
82 registry.erase<float>(entity);
83
84 ASSERT_TRUE(observer.empty());
85 }
86
TEST(Observer,AllOfFiltered)87 TEST(Observer, AllOfFiltered) {
88 constexpr auto collector = entt::collector
89 .group<int>().where<char>(entt::exclude<double>);
90
91 entt::registry registry;
92 entt::observer observer{registry, collector};
93 const auto entity = registry.create();
94
95 ASSERT_TRUE(observer.empty());
96
97 registry.emplace<int>(entity);
98
99 ASSERT_EQ(observer.size(), 0u);
100 ASSERT_TRUE(observer.empty());
101
102 registry.erase<int>(entity);
103 registry.emplace<char>(entity);
104 registry.emplace<double>(entity);
105 registry.emplace<int>(entity);
106
107 ASSERT_TRUE(observer.empty());
108
109 registry.erase<int>(entity);
110 registry.erase<double>(entity);
111 registry.emplace<int>(entity);
112
113 ASSERT_EQ(observer.size(), 1u);
114 ASSERT_FALSE(observer.empty());
115 ASSERT_EQ(*observer.data(), entity);
116
117 registry.emplace<double>(entity);
118
119 ASSERT_TRUE(observer.empty());
120
121 registry.erase<double>(entity);
122
123 ASSERT_TRUE(observer.empty());
124
125 observer.disconnect();
126 registry.erase<int>(entity);
127 registry.emplace<int>(entity);
128
129 ASSERT_TRUE(observer.empty());
130 }
131
TEST(Observer,Observe)132 TEST(Observer, Observe) {
133 entt::registry registry;
134 entt::observer observer{registry, entt::collector.update<int>().update<char>()};
135 const auto entity = registry.create();
136
137 ASSERT_TRUE(observer.empty());
138
139 registry.emplace<int>(entity);
140 registry.emplace<char>(entity);
141
142 ASSERT_TRUE(observer.empty());
143
144 registry.emplace_or_replace<int>(entity);
145
146 ASSERT_EQ(observer.size(), 1u);
147 ASSERT_FALSE(observer.empty());
148 ASSERT_EQ(*observer.data(), entity);
149
150 observer.clear();
151 registry.replace<char>(entity);
152
153 ASSERT_FALSE(observer.empty());
154
155 observer.clear();
156
157 ASSERT_TRUE(observer.empty());
158
159 observer.disconnect();
160 registry.emplace_or_replace<int>(entity);
161 registry.emplace_or_replace<char>(entity);
162
163 ASSERT_TRUE(observer.empty());
164 }
165
TEST(Observer,ObserveFiltered)166 TEST(Observer, ObserveFiltered) {
167 constexpr auto collector = entt::collector
168 .update<int>().where<char>(entt::exclude<double>);
169
170 entt::registry registry;
171 entt::observer observer{registry, collector};
172 const auto entity = registry.create();
173
174 ASSERT_TRUE(observer.empty());
175
176 registry.emplace<int>(entity);
177 registry.replace<int>(entity);
178
179 ASSERT_EQ(observer.size(), 0u);
180 ASSERT_TRUE(observer.empty());
181
182 registry.emplace<char>(entity);
183 registry.emplace<double>(entity);
184 registry.replace<int>(entity);
185
186 ASSERT_TRUE(observer.empty());
187
188 registry.erase<double>(entity);
189 registry.replace<int>(entity);
190
191 ASSERT_EQ(observer.size(), 1u);
192 ASSERT_FALSE(observer.empty());
193 ASSERT_EQ(*observer.data(), entity);
194
195 registry.emplace<double>(entity);
196
197 ASSERT_TRUE(observer.empty());
198
199 registry.erase<double>(entity);
200
201 ASSERT_TRUE(observer.empty());
202
203 observer.disconnect();
204 registry.replace<int>(entity);
205
206 ASSERT_TRUE(observer.empty());
207 }
208
TEST(Observer,AllOfObserve)209 TEST(Observer, AllOfObserve) {
210 entt::registry registry;
211 entt::observer observer{};
212 const auto entity = registry.create();
213
214 observer.connect(registry, entt::collector.group<int>().update<char>());
215
216 ASSERT_TRUE(observer.empty());
217
218 registry.emplace<int>(entity);
219 registry.emplace<char>(entity);
220 registry.replace<char>(entity);
221 registry.erase<int>(entity);
222
223 ASSERT_EQ(observer.size(), 1u);
224 ASSERT_FALSE(observer.empty());
225 ASSERT_EQ(*observer.data(), entity);
226
227 registry.erase<char>(entity);
228 registry.emplace<char>(entity);
229
230 ASSERT_TRUE(observer.empty());
231
232 registry.replace<char>(entity);
233 observer.clear();
234
235 ASSERT_TRUE(observer.empty());
236
237 observer.disconnect();
238 registry.emplace_or_replace<int>(entity);
239 registry.emplace_or_replace<char>(entity);
240
241 ASSERT_TRUE(observer.empty());
242 }
243
TEST(Observer,CrossRulesCornerCase)244 TEST(Observer, CrossRulesCornerCase) {
245 entt::registry registry;
246 entt::observer observer{registry, entt::collector.group<int>().group<char>()};
247 const auto entity = registry.create();
248
249 registry.emplace<int>(entity);
250 observer.clear();
251
252 ASSERT_TRUE(observer.empty());
253
254 registry.emplace<char>(entity);
255 registry.erase<int>(entity);
256
257 ASSERT_FALSE(observer.empty());
258 }
259
TEST(Observer,Each)260 TEST(Observer, Each) {
261 entt::registry registry;
262 entt::observer observer{registry, entt::collector.group<int>()};
263 const auto entity = registry.create();
264 registry.emplace<int>(entity);
265
266 ASSERT_FALSE(observer.empty());
267 ASSERT_EQ(observer.size(), 1u);
268
269 std::as_const(observer).each([entity](const auto entt) {
270 ASSERT_EQ(entity, entt);
271 });
272
273 ASSERT_FALSE(observer.empty());
274 ASSERT_EQ(observer.size(), 1u);
275
276 observer.each([entity](const auto entt) {
277 ASSERT_EQ(entity, entt);
278 });
279
280 ASSERT_TRUE(observer.empty());
281 ASSERT_EQ(observer.size(), 0u);
282 }
283
TEST(Observer,MultipleFilters)284 TEST(Observer, MultipleFilters) {
285 constexpr auto collector = entt::collector
286 .update<int>().where<char>()
287 .update<double>().where<float>();
288
289 entt::registry registry;
290 entt::observer observer{registry, collector};
291 const auto entity = registry.create();
292
293 ASSERT_TRUE(observer.empty());
294
295 registry.emplace_or_replace<int>(entity);
296 registry.emplace<char>(entity);
297
298 ASSERT_TRUE(observer.empty());
299
300 registry.emplace_or_replace<int>(entity);
301
302 ASSERT_EQ(observer.size(), 1u);
303 ASSERT_FALSE(observer.empty());
304 ASSERT_EQ(*observer.data(), entity);
305
306 observer.clear();
307 registry.emplace<double>(entity);
308
309 ASSERT_TRUE(observer.empty());
310
311 registry.emplace_or_replace<double>(entity);
312 registry.emplace<float>(entity);
313
314 ASSERT_TRUE(observer.empty());
315
316 registry.emplace_or_replace<double>(entity);
317
318 ASSERT_EQ(observer.size(), 1u);
319 ASSERT_FALSE(observer.empty());
320 ASSERT_EQ(*observer.data(), entity);
321
322 registry.erase<float>(entity);
323
324 ASSERT_TRUE(observer.empty());
325
326 registry.emplace_or_replace<int>(entity);
327
328 ASSERT_EQ(observer.size(), 1u);
329 ASSERT_FALSE(observer.empty());
330 ASSERT_EQ(*observer.data(), entity);
331
332 observer.clear();
333 observer.disconnect();
334
335 registry.emplace_or_replace<int>(entity);
336
337 ASSERT_TRUE(observer.empty());
338 }
339
TEST(Observer,GroupCornerCase)340 TEST(Observer, GroupCornerCase) {
341 constexpr auto add_collector = entt::collector.group<int>(entt::exclude<char>);
342 constexpr auto remove_collector = entt::collector.group<int, char>();
343
344 entt::registry registry;
345 entt::observer add_observer{registry, add_collector};
346 entt::observer remove_observer{registry, remove_collector};
347
348 const auto entity = registry.create();
349 registry.emplace<int>(entity);
350
351 ASSERT_FALSE(add_observer.empty());
352 ASSERT_TRUE(remove_observer.empty());
353
354 add_observer.clear();
355 registry.emplace<char>(entity);
356
357 ASSERT_TRUE(add_observer.empty());
358 ASSERT_FALSE(remove_observer.empty());
359
360 remove_observer.clear();
361 registry.erase<char>(entity);
362
363 ASSERT_FALSE(add_observer.empty());
364 ASSERT_TRUE(remove_observer.empty());
365 }
366