-
Notifications
You must be signed in to change notification settings - Fork 0
/
systems.c
138 lines (124 loc) · 2.87 KB
/
systems.c
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
137
138
#include "systems.h"
#include "entities.h"
#include "xi.h"
#include "cflags.h"
#include <stdarg.h>
system_t system_init(void f(SYSTEM_ARG_REQUIREMENTS), uint32_t n, ...){
system_t s;
s.f = f;
s.filter = ENTITY_DEACTIVATED;
s.magnet = 0;
s.requisite = 0;
va_list v;
va_start(v, n);
uint32_t i;
s.mask = 0;
for (i = 0;i<n;++i){
uint32_t cid = va_arg(v, uint32_t);
s.mask = bit_on(s.mask, cid);
}
va_end(v);
return s;
}
void system_add_requirement(system_t* sys, uint32_t n, ...){
uint32_t i;
va_list v;
va_start(v, n);
for (i = 0;i<n;++i){
sys->requisite = bit_on(sys->requisite, va_arg(v, uint32_t));
}
va_end(v);
}
void system_remove_requirement(system_t* sys, uint32_t n, ...){
uint32_t i;
va_list v;
va_start(v, n);
for (i = 0;i<n;++i){
sys->requisite = bit_off(sys->requisite, va_arg(v, uint32_t));
}
va_end(v);
}
void system_add_filter(system_t* sys, uint32_t n, ...){
uint32_t i;
va_list v;
va_start(v, n);
for (i = 0;i<n;++i){
sys->filter = bit_on(sys->filter, va_arg(v, uint32_t));
}
va_end(v);
}
void system_remove_filter(system_t* sys, uint32_t n, ...){
uint32_t i;
va_list v;
va_start(v, n);
for (i = 0;i<n;++i){
sys->filter = bit_off(sys->filter, va_arg(v, uint32_t));
}
va_end(v);
}
void system_add_magnet(system_t* sys, uint32_t n, ...){
uint32_t i;
va_list v;
va_start(v, n);
for (i = 0;i<n;++i){
sys->magnet = bit_on(sys->magnet, va_arg(v, uint32_t));
}
va_end(v);
}
void system_remove_magnet(system_t* sys, uint32_t n, ...){
uint32_t i;
va_list v;
va_start(v, n);
for (i = 0;i<n;++i){
sys->magnet = bit_off(sys->magnet, va_arg(v, uint32_t));
}
va_end(v);
}
uint8_t system_filter(system_t sys, uint64_t targetFlag){
return (
(targetFlag & sys.magnet) |
(targetFlag & (~sys.filter)) |
((~targetFlag) & (~sys.requisite))
) == -1;
}
uint8_t system_mask_compare(uint64_t reference, uint64_t candidate){
return (reference & candidate) == reference;
}
void system_run(system_t s, xi_utils* xi){
uint32_t id;
uint32_t n = xi->ecs->entities;
for (id = 0;id<n;++id){
if (
system_mask_compare(s.mask, xi->ecs->masks[id]) &&
system_filter(s, xi->ecs->flags[id])
){
s.f(SYSTEM_ARGS);
}
}
}
void system_run_queued(system_t s, xi_utils* xi, renderq_t* render_order){
uint32_t id;
uint32_t n = xi->ecs->entities;
for (id = 0;id<n;++id){
if (
system_mask_compare(s.mask, xi->ecs->masks[id]) &&
system_filter(s, xi->ecs->flags[id])
){
renderq_entry_t args = {SYSTEM_ARGS, s.f};
renderq_insert(render_order, entity_get_layer(xi->ecs, id), args);
}
}
uint8_t gui = 0;
view original = renderGetView(xi->graphics);
while (render_order->size != 0){
if ((renderq_min(render_order) >= RENDER_GUI_DEPTH) &&( !gui)){
renderSetViewAbsolute(xi->graphics);
gui = 1;
}
renderq_entry_t data = renderq_pop(render_order);
data.f(data.xi, data.id);
}
if (gui){
renderSetView(xi->graphics, original);
}
}