3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
12 /* Compiled through coreset.cpp */
19 //#define xlogf(...) do { fprintf(stderr, __VA_ARGS__); fflush(stderr); } while (0)
23 ////////////////////////////////////////////////////////////////////////////////
24 typedef std::set
<entity
*> EntitySet
;
26 typedef struct EntityListItem
{
27 struct EntityListItem
*next
;
32 typedef struct EntityList
{
33 struct EntityListIterator
*iterators
;
34 struct EntityListItem
*head
;
35 struct EntityListItem
*tail
;
40 typedef struct EntityListIterator
{
41 struct EntityListIterator
*next
;
43 EntityListItem
*nextitem
;
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
));
70 if (el
->tail
!= NULL
) el
->tail
->next
= i
; else el
->head
= i
;
76 static void elClear (EntityList
*el
) {
77 while (el
->head
!= NULL
) {
78 EntityListItem
*i
= el
->head
;
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
;
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
;
109 static entity
*elInitIterator (EntityList
*el
, EntityListIterator
*it
) {
110 memset(it
, 0, sizeof(*it
));
112 it
->nextitem
= (el
->head
!= NULL
? el
->head
->next
: NULL
);
113 it
->next
= el
->iterators
;
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
;
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(); }
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
;
142 elRemoveIterator(it
);
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 ////////////////////////////////////////////////////////////////////////////////
160 elInitialize(&beList
);
161 elInitialize(&hellList
);
165 truth
pool::IsBurningHell () {
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. */
179 EntityListIterator it
;
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");
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
);
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();
204 elRemoveIterator(&it
);
207 elRemoveIterator(&it
);
214 void pool::AbortBe () {
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
;
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(); }
230 xlogf("BurnHell: START\n");
233 for (e
= elInitIterator(&hellList
, &it
); e
!= NULL
; e
= elIteratorNext(&it
)) {
235 elRemoveItem(&hellList
, e
);
238 elRemoveIterator(&it
);
241 elRemoveIterator(&it
);
244 xlogf("BurnHell: DONE\n");
248 void pool::KillBees () {
250 xlogf("pool::KillBees()\n");
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 () {
310 static pool poolsingleton
;