Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
iter.qh
Go to the documentation of this file.
1#pragma once
2
3#if 1
4#define ITER_CONST const
5#else
6#define ITER_CONST
7#endif
8
9#define FOREACH_ARRAY(arr, start, end, cond, body) MACRO_BEGIN \
10 for (int _i = start; _i < end; ++_i) \
11 { \
12 const noref int i = _i; \
13 ITER_CONST noref entity it = arr[i]; \
14 if (cond) \
15 LAMBDA(body) \
16 } \
17MACRO_END
18
19#define FOREACH(list, cond, body) FOREACH_LIST(list, enemy, cond, body)
20
21#define FOREACH_LIST(list, next, cond, body) MACRO_BEGIN \
22 int _i = 0; \
23 for (entity _it = list##_first, _next = NULL; _it; (_it = _next, ++_i)) \
24 { \
25 const noref int i = _i; \
26 ITER_CONST noref entity it = _it; \
27 _next = _it.next; \
28 if (cond) \
29 LAMBDA(body) \
30 } \
31MACRO_END
32
33#define FOREACH_WORD(words, cond, body) MACRO_BEGIN \
34 string _words = words; \
35 int _i = 0; \
36 for (string _it; (_it = car(_words)); (_words = cdr(_words), ++_i)) \
37 { \
38 const noref int i = _i; \
39 const noref string it = _it; \
40 if (cond) \
41 LAMBDA(body) \
42 } \
43MACRO_END
44
45#define STRING_ITERATOR(this, s, i) \
46 string this##_s = s; \
47 int this##_i = i
48
49#define STRING_ITERATOR_SET(this, s, i) MACRO_BEGIN \
50 this##_s = s; \
51 this##_i = i; \
52MACRO_END
53
54#define STRING_ITERATOR_GET(this) str2chr(this##_s, this##_i++)
55#define STRING_ITERATOR_PEEK(this) str2chr(this##_s, this##_i)
56#define STRING_ITERATOR_NEXT(this) MACRO_BEGIN ++this##_i; MACRO_END
57#define STRING_ITERATOR_UNGET(this) MACRO_BEGIN --this##_i; MACRO_END
58#define STRING_ITERATOR_SAVE(this) this##_i
59#define STRING_ITERATOR_LOAD(this, n) MACRO_BEGIN this##_i = n; MACRO_END
60
61#define FOREACH_CHAR(s, cond, body) MACRO_BEGIN \
62 STRING_ITERATOR(iter, s, 0); \
63 int _it; \
64 while ((_it = STRING_ITERATOR_GET(iter)) > 0) \
65 { \
66 const noref int it = _it; \
67 if (cond) \
68 LAMBDA(body) \
69 } \
70MACRO_END
71
72#ifdef CSQC
73 entity(entity start, .string fld, string match) _findstring = #18;
74 entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #402;
75
76 entity(entity start, .entity fld, entity match) _findentity = #98;
77 entity(.entity fld, entity match, .entity tofield) _findchainentity_tofield = #403;
78
79 entity(entity start, .float fld, float match) _findfloat = #98;
80 entity(.float fld, float match, .entity tofield) _findchainfloat_tofield = #403;
81
82 entity(entity start, .float fld, float match) _findflags = #449;
83 entity(.float fld, float match, .entity tofield) _findchainflags_tofield = #450;
84#elifdef SVQC
85 entity(entity start, .string fld, string match) _findstring = #18;
86 entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #402;
87
88 entity(entity start, .entity fld, entity match) _findentity = #98;
89 entity(.entity fld, entity match, .entity tofield) _findchainentity_tofield = #403;
90
91 entity(entity start, .float fld, float match) _findfloat = #98;
92 entity(.float fld, float match, .entity tofield) _findchainfloat_tofield = #403;
93
94 entity(entity start, .float fld, float match) _findflags = #449;
95 entity(.float fld, float match, .entity tofield) _findchainflags_tofield = #450;
96#elifdef MENUQC
97 entity(entity start, .string fld, string match) _findstring = #24;
98 entity(.string fld, string match, .entity tofield) _findchainstring_tofield = #26;
99
100 entity(entity start, .entity fld, entity match) _findentity = #25;
101 entity(.entity fld, entity match, .entity tofield) _findchainentity_tofield = #27;
102
103 entity(entity start, .float fld, float match) _findfloat = #25;
104 entity(.float fld, float match, .entity tofield) _findchainfloat_tofield = #27;
105
106 entity(entity start, .float fld, float match) _findflags = #87;
107 entity(.float fld, float match, .entity tofield) _findchainflags_tofield = #88;
108#endif
109
110#define ORDERED(F) F##_UNORDERED
111#define _FOREACH_ENTITY_FIND_ORDERED(T, fld, match, cond, body) MACRO_BEGIN \
112 int _i = 0; \
113 for (entity _it = NULL; (_it = _find##T(_it, fld, match)); ++_i) \
114 { \
115 const noref int i = _i; \
116 ITER_CONST noref entity it = _it; \
117 if (cond) \
118 LAMBDA(body) \
119 } \
120MACRO_END
121#define MUTEX_LOCK(this) MACRO_BEGIN \
122 if (this) \
123 LOG_SEVEREF("Loop mutex held by %s", this); \
124 this = __FUNC__; \
125MACRO_END
126#define MUTEX_UNLOCK(this) MACRO_BEGIN \
127 this = string_null; \
128MACRO_END
129#define _FOREACH_ENTITY_FIND_UNORDERED(id, T, fld, match, cond, body) MACRO_BEGIN \
130 MUTEX_LOCK(_FOREACH_ENTITY_FIND_##T##_##id##mutex); \
131 entity _foundchain_first = _findchain##T##_tofield(fld, match, _FOREACH_ENTITY_FIND_##T##_next##id); \
132 FOREACH_LIST(_foundchain, _FOREACH_ENTITY_FIND_##T##_next##id, cond, body); \
133 MUTEX_UNLOCK(_FOREACH_ENTITY_FIND_##T##_##id##mutex); \
134MACRO_END
135
136#define FOREACH_ENTITY(cond, body) ORDERED(FOREACH_ENTITY)(cond, body)
137#define FOREACH_ENTITY_ORDERED(cond, body) MACRO_BEGIN \
138 int _i = 0; \
139 for (entity _it = NULL; (_it = nextent(_it)); ++_i) \
140 { \
141 const noref int i = _i; \
142 ITER_CONST noref entity it = _it; \
143 if (cond) \
144 LAMBDA(body) \
145 } \
146MACRO_END
147
151#define FOREACH_ENTITY_UNORDERED(cond, body) _FOREACH_ENTITY_FIND_UNORDERED(all, entity, _FOREACH_ENTITY_fld, NULL, cond, body)
152
153#define FOREACH_ENTITY_FLAGS(fld, match, body) ORDERED(FOREACH_ENTITY_FLAGS)(fld, match, body)
154#define FOREACH_ENTITY_FLAGS_ORDERED(fld, match, body) _FOREACH_ENTITY_FIND_ORDERED(flags, fld, match, true, body)
156#define FOREACH_ENTITY_FLAGS_UNORDERED(fld, match, body) _FOREACH_ENTITY_FIND_UNORDERED(, flags, fld, match, true, body)
157
158#ifdef GAMEQC
159entity(vector org, float rad, .entity tofield) _findchainradius_tofield = #22;
160#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) ORDERED(FOREACH_ENTITY_RADIUS)(org, dist, cond, body)
162#define FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) _FOREACH_ENTITY_FIND_UNORDERED(, radius, org, dist, cond, body)
164#define FOREACH_ENTITY_RADIUS_ORDERED(org, dist, cond, body) \
165MACRO_BEGIN \
166 entity _rev_first = NULL; \
167 _FOREACH_ENTITY_FIND_UNORDERED(tmp, radius, org, dist, cond, (it._FOREACH_ENTITY_FIND_radius_nexttmp = _rev_first, _rev_first = it)); \
168 MUTEX_LOCK(_FOREACH_ENTITY_FIND_radius_tmpmutex); \
169 FOREACH_LIST(_rev, _FOREACH_ENTITY_FIND_radius_nexttmp, true, body); \
170 MUTEX_UNLOCK(_FOREACH_ENTITY_FIND_radius_tmpmutex); \
171MACRO_END
172#endif
173
174#define FOREACH_ENTITY_FLOAT(fld, match, body) ORDERED(FOREACH_ENTITY_FLOAT)(fld, match, body)
175#define FOREACH_ENTITY_FLOAT_ORDERED(fld, match, body) _FOREACH_ENTITY_FIND_ORDERED(float, fld, match, true, body)
177#define FOREACH_ENTITY_FLOAT_UNORDERED(fld, match, body) _FOREACH_ENTITY_FIND_UNORDERED(, float, fld, match, true, body)
178
179#define FOREACH_ENTITY_ENT(fld, match, body) ORDERED(FOREACH_ENTITY_ENT)(fld, match, body)
180#define FOREACH_ENTITY_ENT_ORDERED(fld, match, body) _FOREACH_ENTITY_FIND_ORDERED(entity, fld, match, true, body)
182#define FOREACH_ENTITY_ENT_UNORDERED(fld, match, body) _FOREACH_ENTITY_FIND_UNORDERED(, entity, fld, match, true, body)
183
184#define FOREACH_ENTITY_STRING(fld, match, body) ORDERED(FOREACH_ENTITY_STRING)(fld, match, body)
185#define FOREACH_ENTITY_STRING_ORDERED(fld, match, body) _FOREACH_ENTITY_FIND_ORDERED(string, fld, match, true, body)
187#define FOREACH_ENTITY_STRING_UNORDERED(fld, match, body) _FOREACH_ENTITY_FIND_UNORDERED(, string, fld, match, true, body)
188
189#define FOREACH_ENTITY_CLASS(class, cond, body) ORDERED(FOREACH_ENTITY_CLASS)(class, cond, body)
190#define FOREACH_ENTITY_CLASS_ORDERED(class, cond, body) _FOREACH_ENTITY_FIND_ORDERED(string, classname, class, cond, body)
192#define FOREACH_ENTITY_CLASS_UNORDERED(class, cond, body) _FOREACH_ENTITY_FIND_UNORDERED(clazz, string, classname, class, cond, body)
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
entity() spawn
entity _FOREACH_ENTITY_FIND_entity_next
Definition iter.qh:181
noref string _FOREACH_ENTITY_FIND_radius_tmpmutex
Definition iter.qh:163
noref string _FOREACH_ENTITY_FIND_radius_mutex
Definition iter.qh:161
noref string _FOREACH_ENTITY_FIND_float_mutex
Definition iter.qh:176
entity _FOREACH_ENTITY_FIND_string_next
Definition iter.qh:186
noref string _FOREACH_ENTITY_FIND_entity_mutex
Definition iter.qh:181
entity _FOREACH_ENTITY_FIND_float_next
Definition iter.qh:176
noref string _FOREACH_ENTITY_FIND_string_clazzmutex
Definition iter.qh:191
noref string _FOREACH_ENTITY_FIND_string_mutex
Definition iter.qh:186
entity _FOREACH_ENTITY_FIND_radius_nexttmp
Definition iter.qh:163
noref string _FOREACH_ENTITY_FIND_flags_mutex
Definition iter.qh:155
entity _FOREACH_ENTITY_FIND_flags_next
Definition iter.qh:155
entity _FOREACH_ENTITY_FIND_radius_next
Definition iter.qh:161
entity _FOREACH_ENTITY_FIND_entity_nextall
Definition iter.qh:150
entity _FOREACH_ENTITY_fld
Marker field, always NULL.
Definition iter.qh:149
noref string _FOREACH_ENTITY_FIND_entity_allmutex
Definition iter.qh:150
entity _FOREACH_ENTITY_FIND_string_nextclazz
Definition iter.qh:191
vector
Definition self.qh:96
vector org
Definition self.qh:96