2d48e577b8da2bf72b5ae3fa8cf19da46d8b89aa
[xonotic/xonotic-data.pk3dir.git] / qcsrc / ecs / lib.qh
1 #pragma once
2
3 /** Components always interpolate from the previous state */
4 #define COMPONENT(com) \
5         void com_##com##_interpolate(entity it, float a); \
6         .bool com_##com
7
8 #define FOREACH_COMPONENT(com, body) FOREACH_ENTITY_FLOAT(com_##com, true, body)
9
10
11 #define EVENT(T, args) .bool evt_##T##_listener; .void args evt_##T
12
13 #define emit(T, ...) \
14         MACRO_BEGIN \
15         FOREACH_ENTITY_FLOAT_ORDERED(evt_##T##_listener, true, it.evt_##T(__VA_ARGS__)); \
16         MACRO_END
17
18 #define subscribe(listener, T, fn) \
19         MACRO_BEGIN \
20         listener.evt_##T = (fn); \
21         listener.evt_##T##_listener = true; \
22         MACRO_END
23
24
25 /**
26  * framelimit 0 is no limit, interpolation does not apply
27  * framerate below minfps will result in less than 100% speed
28  */
29 #define SYSTEM(sys, frameLimit, minfps) \
30         void sys_##sys##_update(entity this, float dt); \
31         noref float autocvar_xon_sys_##sys##_dt = ((frameLimit) ? (1 / (frameLimit)) : 0); \
32         noref float autocvar_xon_sys_##sys##_minfps = (1 / (1 / (minfps)))
33
34 #define SYSTEM_UPDATE(sys) \
35         MACRO_BEGIN \
36         static float t = 0; \
37         float dt = autocvar_xon_sys_##sys##_dt; \
38         float minfps = autocvar_xon_sys_##sys##_minfps; \
39         static float accumulator = 0; \
40         float a = 0; \
41         if (dt) { \
42                 accumulator += min(frametime, 1 / (minfps)); \
43         } else { \
44                 accumulator += frametime; \
45                 dt = accumulator; \
46                 a = 1; \
47         } \
48         while (accumulator >= dt) \
49         { \
50                 time = t; \
51                 FOREACH_COMPONENT(sys, sys_##sys##_update(it, dt)); \
52                 t += dt; \
53                 accumulator -= dt; \
54         } \
55         if (!a) a = accumulator / dt; \
56         FOREACH_COMPONENT(sys, com_##sys##_interpolate(it, a)); \
57         MACRO_END