moved almost all hardcoded constants to "define.dat"
[k8-i-v-a-n.git] / src / game / pool.cpp
blob673702aa49ec74dc4b54be90efd019063ae10f89
1 /*
3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
6 * Public License
8 * See LICENSING which should be included
9 * along with this file for more details
12 /* Compiled through coreset.cpp */
13 #include <stdio.h>
14 #include <set>
16 #include "game.h"
19 //#define xlogf(...) do { fprintf(stderr, __VA_ARGS__); fflush(stderr); } while (0)
20 #define xlogf(...)
23 ////////////////////////////////////////////////////////////////////////////////
24 typedef std::set<entity *> EntitySet;
26 typedef struct EntityListItem {
27 struct EntityListItem *next;
28 entity *e;
29 } EntityListItem;
32 typedef struct EntityList {
33 struct EntityListIterator *iterators;
34 struct EntityListItem *head;
35 struct EntityListItem *tail;
36 EntitySet *items;
37 } EntityList;
40 typedef struct EntityListIterator {
41 struct EntityListIterator *next;
42 EntityList *owner;
43 EntityListItem *nextitem;
44 } EntityListIterator;
47 ////////////////////////////////////////////////////////////////////////////////
48 static void elInitialize (EntityList *el) {
49 memset(el, 0, sizeof(*el));
50 el->items = new EntitySet();
54 static bool elIsInList (EntityList *el, entity *e) {
55 EntitySet::const_iterator it = el->items->find(e);
57 return (it != el->items->end());
61 static void elAddItem (EntityList *el, entity *e) {
62 EntitySet::const_iterator it = el->items->find(e);
64 if (it == el->items->end()) {
65 EntityListItem *i = (EntityListItem *)calloc(1, sizeof(EntityListItem));
67 el->items->insert(e);
68 i->e = e;
69 i->next = NULL;
70 if (el->tail != NULL) el->tail->next = i; else el->head = i;
71 el->tail = i;
76 static void elClear (EntityList *el) {
77 while (el->head != NULL) {
78 EntityListItem *i = el->head;
80 el->head = i->next;
81 free(i);
83 el->items->clear();
87 static void elRemoveItem (EntityList *el, entity *e) {
88 EntitySet::iterator it = el->items->find(e);
90 if (it != el->items->end()) {
91 EntityListItem *p = NULL, *i;
93 el->items->erase(it);
95 for (i = el->head; i != NULL; p = i, i = i->next) if (i->e == e) break;
96 if (i == NULL) { fprintf(stderr, "FATAL: elRemoveItem() desync!\n"); abort(); }
98 for (EntityListIterator *eit = el->iterators; eit != NULL; eit = eit->next) {
99 if (eit->nextitem == i) eit->nextitem = i->next;
102 if (p != NULL) p->next = i->next; else el->head = i->next;
103 if (i->next == NULL) el->tail = p;
104 free(i);
109 static entity *elInitIterator (EntityList *el, EntityListIterator *it) {
110 memset(it, 0, sizeof(*it));
111 it->owner = el;
112 it->nextitem = (el->head != NULL ? el->head->next : NULL);
113 it->next = el->iterators;
114 el->iterators = it;
115 return (el->head != NULL ? el->head->e : NULL);
119 static void elRemoveIterator (EntityListIterator *it) {
120 if (it->owner != NULL) {
121 if (it->owner->iterators == it) {
122 it->owner->iterators = it->next;
123 } else {
124 EntityListIterator *p = NULL, *c;
126 for (c = it->owner->iterators; c != NULL; p = c, c = c->next) if (c == it) break;
127 if (c == NULL || p == NULL) { fprintf(stderr, "FATAL: elRemoveIterator() desync!\n"); abort(); }
128 p->next = it->next;
130 memset(it, 0, sizeof(*it));
135 static entity *elIteratorNext (EntityListIterator *it) {
136 if (it->nextitem != NULL) {
137 entity *e = it->nextitem->e;
139 it->nextitem = it->nextitem->next;
140 return e;
141 } else {
142 elRemoveIterator(it);
144 return NULL;
148 ////////////////////////////////////////////////////////////////////////////////
149 static EntityList beList;
150 static EntityList hellList;
153 static bool burningHell = false; // is we burning lost souls?
154 static bool doBeing = false; // being process in progress?
155 static bool doRegister = true; // nothing %-)
158 ////////////////////////////////////////////////////////////////////////////////
159 pool::pool () {
160 elInitialize(&beList);
161 elInitialize(&hellList);
165 truth pool::IsBurningHell () {
166 return burningHell;
170 void pool::RegisterState (truth doreg) {
171 //doRegister = doreg;
175 ////////////////////////////////////////////////////////////////////////////////
176 /* Calls the Be() function of each self-changeable entity during each tick,
177 * thus allowing acting characters, spoiling food etc. */
178 void pool::Be () {
179 EntityListIterator it;
180 entity *e;
182 if (burningHell) { fprintf(stderr, "FATAL: started to being while burning souls!\n"); entity::DumpDeadSet(); abort(); }
183 if (doBeing) { fprintf(stderr, "FATAL: started to being while already being!\n"); entity::DumpDeadSet(); abort(); }
185 xlogf("Be: START\n");
186 doBeing = true;
188 try {
189 for (e = elInitIterator(&beList, &it); e != NULL; e = elIteratorNext(&it)) {
190 int mmark = entity::GetUniqueMemoryMark(e);
192 xlogf("Be: %p (%d)\n", e, mmark);
193 e->Be();
194 if (it.owner == NULL) break; // aborted
195 if (elIsInList(&beList, e)) {
196 if (entity::GetUniqueMemoryMark(e) != mmark) {
197 fprintf(stderr, "FATAL: entity polymorphed while being!\n");
198 entity::DumpDeadSet();
199 abort();
203 } catch (...) {
204 elRemoveIterator(&it);
205 throw;
207 elRemoveIterator(&it);
209 doBeing = false;
210 xlogf("Be: DONE\n");
214 void pool::AbortBe () {
215 doBeing = false;
216 for (EntityListIterator *eit = beList.iterators; eit != NULL; eit = eit->next) { eit->owner = NULL; eit->nextitem = NULL; }
217 beList.iterators = NULL;
221 void pool::BurnHell () {
222 EntityListIterator it;
223 entity *e;
225 if (!game::IsRunning()) AbortBe();
226 if (burningHell) { fprintf(stderr, "FATAL: started to burning souls while already burning souls!\n"); entity::DumpDeadSet(); abort(); }
227 if (doBeing) { fprintf(stderr, "FATAL: started to burning souls while being!\n"); entity::DumpDeadSet(); abort(); }
229 burningHell = true;
230 xlogf("BurnHell: START\n");
232 try {
233 for (e = elInitIterator(&hellList, &it); e != NULL; e = elIteratorNext(&it)) {
234 delete e;
235 elRemoveItem(&hellList, e);
237 } catch (...) {
238 elRemoveIterator(&it);
239 throw;
241 elRemoveIterator(&it);
243 burningHell = false;
244 xlogf("BurnHell: DONE\n");
248 void pool::KillBees () {
250 xlogf("pool::KillBees()\n");
251 beSets.clear();
252 xnewBeSet.clear();
253 notDoSet.clear();
254 BurnHell();
259 void pool::Add (entity *e) {
260 if (doRegister && e) {
261 elRemoveItem(&hellList, e);
262 if (!elIsInList(&beList, e)) {
263 elAddItem(&beList, e);
264 xlogf("Add: %p\n", e);
270 void pool::Remove (entity *e) {
271 if (doRegister && e) {
272 if (elIsInList(&beList, e)) {
273 xlogf("Remove: %p\n", e);
274 elRemoveItem(&beList, e);
280 void pool::AddToHell (entity *e) {
281 if (doRegister && e) {
282 Remove(e); // burn it with fire!
283 if (!elIsInList(&hellList, e)) {
284 xlogf("AddToHell: %p\n", e);
285 elAddItem(&hellList, e);
291 void pool::RemoveFromHell (entity *e) {
292 if (doRegister && e) {
293 if (elIsInList(&hellList, e)) {
294 xlogf("RemoveFromHell: %p\n", e);
295 elRemoveItem(&hellList, e);
301 void pool::RemoveEverything () {
302 elClear(&beList);
303 elClear(&hellList);
307 #undef xlogf
310 static pool poolsingleton;