6
6
7
7
namespace ecsact ::entt {
8
8
9
+ template <typename T>
10
+ using is_not_empty = boost::mp11::mp_not<std::is_empty<T>>;
11
+
9
12
/* *
10
13
* Checks if a system 'trivial' i.e. there is only a single possible
11
14
* meaningful implementation.
12
15
*/
13
- template <typename Package, typename SystemT>
16
+ template <typename SystemT>
14
17
constexpr bool is_trivial_system () {
15
18
using boost::mp11::mp_filter;
16
19
using boost::mp11::mp_empty;
@@ -22,81 +25,72 @@ namespace ecsact::entt {
22
25
using readonly_components = typename caps_info::readonly_components;
23
26
using readwrite_components = typename caps_info::readwrite_components;
24
27
using writeonly_components = typename caps_info::writeonly_components;
28
+ using include_components = typename caps_info::include_components;
29
+ using exclude_components = typename caps_info::exclude_components;
25
30
using adds_components = typename caps_info::adds_components;
26
31
using removes_components = typename caps_info::removes_components;
27
32
using adds_tag_components = mp_filter<std::is_empty, adds_components>;
33
+ using remove_tag_components = mp_filter<std::is_empty, removes_components>;
34
+ using adds_non_tag_components = mp_filter<is_not_empty, adds_components>;
35
+
36
+ const bool can_add = !mp_empty<adds_components>::value;
37
+ const bool can_remove = !mp_empty<removes_components>::value;
38
+ const bool can_add_non_tag = !mp_empty<adds_non_tag_components>::value;
39
+
40
+ const bool can_only_add_tag =
41
+ mp_size<adds_tag_components>::value == mp_size<adds_components>::value;
42
+
43
+ const bool has_only_trivial_modifiers = can_remove || can_only_add_tag;
44
+ const bool can_access =
45
+ !mp_empty<readwrite_components>::value ||
46
+ !mp_empty<readonly_components>::value ||
47
+ !mp_empty<writeonly_components>::value;
48
+
49
+ if (!can_access && has_only_trivial_modifiers) {
50
+ return true ;
51
+ }
28
52
29
- const bool can_add_non_tag_compnents =
30
- mp_size<adds_components>::value != 0 && (
31
- mp_size<adds_tag_components>::value !=
32
- mp_size<adds_components>::value
33
- );
34
53
const bool cant_write =
35
- mp_empty<readwrite_components>::value &&
36
- mp_empty<writeonly_components>::value;
37
- const bool cant_add = mp_empty<adds_components>::value;
38
- const bool cant_remove = mp_empty<removes_components>::value;
39
- const bool cant_read =
40
- mp_empty<readonly_components>::value &&
54
+ mp_empty<writeonly_components>::value &&
41
55
mp_empty<readwrite_components>::value;
56
+ const bool has_modifiers = can_add || can_remove;
57
+
58
+ if (cant_write && !has_modifiers) {
59
+ return true ;
60
+ }
42
61
43
- return cant_write && cant_add && cant_remove && cant_read ;
62
+ return false ;
44
63
}
45
64
46
- template <typename Package, typename SystemT, typename EachCallbackT>
47
- requires (is_trivial_system<Package, SystemT>())
65
+ template <typename SystemT, typename EachCallbackT>
66
+ requires (is_trivial_system<SystemT>())
48
67
void trivial_system_impl
49
- ( ::entt::registry & registry
50
- , EachCallbackT&& each_callback = [](auto &, auto ){}
68
+ ( auto & info
69
+ , EachCallbackT&& each_callback = [](auto &, auto &, auto ){}
51
70
)
52
71
{
53
- using boost::mp11::mp_empty;
54
- using boost::mp11::mp_list;
55
72
using boost::mp11::mp_for_each;
56
73
57
74
using caps_info = ecsact::system_capabilities_info<SystemT>;
58
-
59
- using readonly_components = typename caps_info::readonly_components;
60
- using readwrite_components = typename caps_info::readwrite_components;
61
- using writeonly_components = typename caps_info::writeonly_components;
62
75
using adds_components = typename caps_info::adds_components;
63
76
using removes_components = typename caps_info::removes_components;
64
- using include_components = typename caps_info::include_components;
65
- using exclude_components = typename caps_info::exclude_components;
66
- using optional_components = typename caps_info::optional_components;
67
-
68
- // If we have a system that can only remove and does not use any filtering
69
- // i.e. simply removes all of a component, then we can use a short cut and
70
- // use `registry.clear`.
71
- constexpr bool is_removes_only =
72
- !mp_empty<removes_components>::value &&
73
- mp_empty<readonly_components>::value &&
74
- mp_empty<readwrite_components>::value &&
75
- mp_empty<optional_components>::value &&
76
- mp_empty<adds_components>::value &&
77
- mp_empty<include_components>::value &&
78
- mp_empty<exclude_components>::value;
79
-
80
- if constexpr (is_removes_only) {
77
+
78
+ auto view = system_view<SystemT>(info.registry );
79
+ // TODO(zaucy): Iterate over association views in trivial systems
80
+ auto assoc_views = system_association_views<SystemT>(info.registry );
81
+ for (auto entity : view) {
82
+ mp_for_each<adds_components>([&]<typename C>(C) {
83
+ // Only empty components should have made it into this list if the
84
+ // `is_trivial_system` constraint succeeded.
85
+ static_assert (std::is_empty_v<C>);
86
+ info.template add_component <C>(entity);
87
+ });
88
+
81
89
mp_for_each<removes_components>([&]<typename C>(C) {
82
- registry. clear <C>();
90
+ info. template remove_component <C>(entity );
83
91
});
84
- } else {
85
- auto view = system_view<Package, SystemT>(registry);
86
- for (auto entity : view) {
87
- mp_for_each<adds_components>([&]<typename C>(C) {
88
- // Only empty comopnents should have made it into this list if the
89
- // `is_trivial_system` constraint succeeded.
90
- static_assert (std::is_empty_v<C>);
91
- registry.emplace <C>(entity);
92
- });
93
-
94
- mp_for_each<removes_components>([&]<typename C>(C) {
95
- registry.erase <C>(entity);
96
- });
97
-
98
- each_callback (view, entity);
99
- }
92
+
93
+ each_callback (view, assoc_views, entity);
100
94
}
101
95
}
102
96
0 commit comments