-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsystem.hh
136 lines (104 loc) · 2.96 KB
/
system.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <algorithm>
#include <functional>
#include "util/util.hh"
#include "util/range.hh"
#include "entity_space.hh"
template <class Space, class... Laws>
struct System
{
using EntityType = typename Space::EntityType;
using BitMask = std::bitset<Space::max_components>;
using BitMasks = std::array<BitMask, sizeof...(Laws)>;
using Routines = util::TypeVector<Laws...>;
Routines routines;
Space space;
BitMasks masks;
System()
{
BitMask mask;
util::swallow {(
masks[util::index_of<Laws, Laws...>::value] =
Laws::template create_mask<Space>(),
0)...};
}
template <class Law>
BitMask get_mask()
{ return masks[util::index_of<Law, Laws...>::value]; }
/** Create a new entity with default components */
template <class... InitCpts>
EntityID create_entity()
{
EntityType entity(InitCpts {}...);
return space.insert(std::move(entity));
}
/** Create a new entity with specified components */
template <class... InitCpts>
EntityID create_entity(InitCpts&&... cpts)
{
EntityType entity(std::forward<InitCpts>(cpts)...);
return space.insert(std::move(entity));
}
// // to avoid sys.template ... cruft
// template <class... InitCpts>
// friend EntityID create_entity(System& sys)
// { return sys.template create_entity<InitCpts...>(); }
template <class L>
L& get_law()
{
util::println(util::format("get_law() [L = '%s', Routines = '%s']", util::type_name<L>(), util::type_name(routines)));
return util::get<L>(routines);
}
void update()
{
BitMask mask;
auto supports = [&] (const EntityType& ent) { return ent.supports(mask); };
util::swallow {(
mask = get_mask<Laws>(),
get_law<Laws>().run(util::range::filter(supports, space.begin(), space.end())),
0)...};
}
};
template <class... Components>
struct Logic
{
using Index = util::TypeVector<Components...>;
template <class Space>
static typename Space::BitMask create_mask()
{
typename Space::BitMask mask;
util::swallow {(
mask.set(util::index_within<
Components, typename Space::Index>::value),
0)...};
return mask;
}
template <class Entities>
void run(Entities&& ents)
{
// println("Running Logic");
for (auto& ent : ents) {
util::swallow {(
assert(ent.template has_component<Components>()),
0)...};
operate(ent.template get_component<Components>()...);
}
}
virtual void operate(Components&... cs)
{
println("Empty Logic operation");
}
std::string to_string() const
{
using util::io::print_to;
std::stringstream out;
out << "Logic<";
bool at_0 = true;
util::swallow {(
print_to(out, at_0 ? "" : ", ",
name<Components>()),
at_0 = false,
0)...};
out << ">";
return out.str();
}
};