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