1 /* 2 This file is part of "Avanor, the Land of Mystery" roguelike game 3 Home page: http://www.avanor.com/ 4 Copyright (C) 2000-2003 Vadim Gaidukevich 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 #ifndef __XLIST_H 22 #define __XLIST_H 23 24 #include "xobject.h" 25 26 template <class T> class XList 27 { 28 struct XNode 29 { 30 XNode * pNext; 31 XNode * pPrev; 32 XObject * o; 33 }; 34 35 XNode * pBeginList; 36 public: XList()37 XList() 38 { 39 pBeginList = iterator::CreateNode(); 40 pBeginList->o = NULL; 41 pBeginList->pNext = pBeginList; 42 pBeginList->pPrev = pBeginList; 43 } 44 ~XList()45 ~XList() 46 { 47 erase(begin(), end()); 48 iterator::DestroyNode(pBeginList); 49 } 50 51 class iterator 52 { 53 protected: 54 friend class XList<T>; 55 XNode * position; 56 CreateNode()57 static XNode * CreateNode() { return new XNode(); } DestroyNode(XNode * pNode)58 static void DestroyNode(XNode * pNode) { delete pNode; } 59 60 public: iterator()61 iterator() {} iterator(XNode * pNode)62 iterator(XNode * pNode) : position(pNode) {} 63 void operator++() 64 { 65 assert(position); 66 position = position->pNext; 67 while (true) 68 { 69 //position->o == NULL means end of list 70 if (position->o == NULL || position->o->isValid()) 71 return; 72 destroy(); 73 } 74 } 75 76 void operator++(int) { operator++(); } 77 void operator--() { assert(position); position = position->pPrev; } 78 void operator--(int) { operator--(); } 79 iterator& operator=(const iterator& x) { position = x.position; return *this; } 80 bool operator==(const iterator& x) { return position == x.position; } 81 bool operator!=(const iterator& x) { return !(position == x.position); } 82 T operator*() 83 { 84 // assert(position->o && position->o->isValid()); 85 return (T)position->o; 86 } 87 T operator->() 88 { 89 // assert(position->o && position->o->isValid()); 90 return (T)position->o; 91 } 92 T()93 operator T() 94 { 95 // assert(position->o && position->o->isValid()); 96 return (T)position->o; 97 } 98 destroy()99 iterator destroy() 100 { 101 XNode * pNext = position->pNext; 102 XNode * pPrev = position->pPrev; 103 pPrev->pNext = pNext; 104 pNext->pPrev = pPrev; 105 position->o->Release(); 106 DestroyNode(position); 107 position = pNext; 108 return iterator(pNext); 109 } 110 }; 111 begin()112 iterator begin() 113 { 114 XNode * pNode = pBeginList->pNext; 115 116 while (true) 117 { 118 if (pNode->o == NULL || pNode->o->isValid()) 119 return iterator(pNode); 120 pNode = erase(iterator(pNode)).position; 121 } 122 } 123 end()124 iterator end() {return iterator(pBeginList);} empty()125 bool empty () 126 { 127 //we need to call begin for remove invalid objects 128 return (begin().position->o == NULL); 129 } 130 insert(iterator it,T object)131 iterator insert(iterator it, T object) 132 { 133 assert(object); 134 XNode * tNode = iterator::CreateNode(); 135 tNode->o = object; 136 object->AddRef(); 137 tNode->pNext = it.position; 138 tNode->pPrev = it.position->pPrev; 139 it.position->pPrev->pNext = tNode; 140 it.position->pPrev = tNode; 141 it.position = tNode; 142 return it; 143 } 144 erase(iterator it)145 iterator erase(iterator it) 146 { 147 return it.destroy(); 148 } 149 erase(iterator begin,iterator end)150 iterator erase(iterator begin, iterator end) 151 { 152 while (begin != end) 153 begin = erase(begin); 154 return begin; 155 } 156 clear()157 void clear() { return erase(begin(), end());} 158 Add(T object)159 void Add(T object) {push_back(object);} push_front(const T & o)160 void push_front(const T& o) { insert(begin(), o); } push_back(const T & o)161 void push_back(const T& o) { insert(end(), o); } pop_front()162 void pop_front() { erase(begin()); } pop_back()163 void pop_back() 164 { 165 iterator tmp = end(); 166 erase(--tmp); 167 } 168 size()169 size_t size() 170 { 171 size_t count = 0; 172 for (iterator it = begin(); it != end(); it++) 173 count++; 174 return count; 175 } 176 Find(XGUID xguid)177 iterator Find(XGUID xguid) 178 { 179 for (iterator it = begin(); it != end(); it++) 180 if ((*it)->xguid == xguid) 181 return it; 182 return end(); 183 } 184 Remove(XGUID xguid)185 T Remove(XGUID xguid) {return Remove(Find(xguid));} Remove(iterator it)186 T Remove(iterator it) 187 { 188 if(it == end()) 189 return NULL; 190 191 T p = (*it); 192 it = erase(it); 193 return p; 194 } 195 RemoveFirst()196 T RemoveFirst() { return Remove(begin()); } 197 KillAll()198 void KillAll() 199 { 200 T o; 201 while((o = RemoveFirst())) 202 o->Invalidate(); 203 } 204 StoreList(XFile * f)205 void StoreList(XFile * f) 206 { 207 unsigned long count = size(); 208 f->Write(&count, sizeof(count)); 209 for(iterator it = begin(); it != end(); ++it) XObject::StorePointer(f, it); 210 } 211 RestoreList(XFile * f)212 void RestoreList(XFile * f) 213 { 214 assert(empty()); 215 unsigned long count = 0; 216 f->Read(&count, sizeof(count)); 217 while(count-- > 0) 218 { 219 T p = (T)XObject::RestorePointer(f, NULL); 220 push_back(p); 221 } 222 } 223 224 }; 225 226 template <class T> class XSortedList : public XList < T > 227 { 228 typedef typename XList<T>::iterator XList_iteraror; 229 public: insert(XList_iteraror it,T object)230 XList_iteraror insert(XList_iteraror it, T object) 231 { 232 XList_iteraror i; 233 for (i = this->begin(); i != this->end(); i++) 234 { 235 if(object->im < i->im) break; 236 if(object->im == i->im && object->Compare(i) <= 0) break; 237 } 238 239 if (object->GetRef() == 0 && i != this->end() && i->GetRef() == 1 240 && object->im == i->im && object->Compare(i) == 0) 241 { 242 i->Concat(object); 243 return i; 244 } 245 else 246 { 247 return XList<T>::insert(i, object); 248 } 249 } 250 Add(T object)251 void Add(T object) {push_back(object);} push_front(const T & o)252 void push_front(const T& o) { insert(this->begin(), o); } push_back(const T & o)253 void push_back(const T& o) { insert(this->end(), o); } 254 255 }; 256 257 258 259 260 261 262 263 template <class T> class XQList 264 { 265 struct XNode 266 { 267 XNode * pNext; 268 XNode * pPrev; 269 T o; 270 }; 271 272 XNode * pBeginList; 273 public: XQList()274 XQList() 275 { 276 pBeginList = iterator::CreateNode(); 277 pBeginList->pNext = pBeginList; 278 pBeginList->pPrev = pBeginList; 279 } 280 ~XQList()281 ~XQList() 282 { 283 erase(begin(), end()); 284 iterator::DestroyNode(pBeginList); 285 } 286 287 class iterator 288 { 289 protected: 290 friend class XQList<T>; 291 XNode * position; 292 CreateNode()293 static XNode * CreateNode() { return new XNode(); } DestroyNode(XNode * pNode)294 static void DestroyNode(XNode * pNode) { delete pNode; } 295 296 public: iterator()297 iterator() {} iterator(XNode * pNode)298 iterator(XNode * pNode) : position(pNode) {} 299 void operator++() 300 { 301 assert(position); 302 position = position->pNext; 303 } 304 305 void operator++(int) { operator++(); } 306 void operator--() { assert(position); position = position->pPrev; } 307 void operator--(int) { operator--(); } 308 iterator& operator=(const iterator& x) { position = x.position; return *this; } 309 bool operator==(const iterator& x) { return position == x.position; } 310 bool operator!=(const iterator& x) { return !(position == x.position); } 311 T operator*() 312 { 313 return (T)position->o; 314 } 315 destroy()316 iterator destroy() 317 { 318 XNode * pNext = position->pNext; 319 XNode * pPrev = position->pPrev; 320 pPrev->pNext = pNext; 321 pNext->pPrev = pPrev; 322 DestroyNode(position); 323 position = pNext; 324 return iterator(pNext); 325 } 326 }; 327 begin()328 iterator begin() 329 { 330 return iterator(pBeginList->pNext); 331 } 332 end()333 iterator end() {return iterator(pBeginList);} empty()334 bool empty () 335 { 336 return (begin() == end()); 337 } 338 insert(iterator it,T object)339 iterator insert(iterator it, T object) 340 { 341 XNode * tNode = iterator::CreateNode(); 342 tNode->o = object; 343 tNode->pNext = it.position; 344 tNode->pPrev = it.position->pPrev; 345 it.position->pPrev->pNext = tNode; 346 it.position->pPrev = tNode; 347 it.position = tNode; 348 return it; 349 } 350 erase(iterator it)351 iterator erase(iterator it) 352 { 353 return it.destroy(); 354 } 355 erase(iterator begin,iterator end)356 iterator erase(iterator begin, iterator end) 357 { 358 while (begin != end) 359 begin = erase(begin); 360 return begin; 361 } 362 clear()363 void clear() { erase(begin(), end());} 364 Add(T object)365 void Add(T object) {push_back(object);} push_front(const T & o)366 void push_front(const T& o) { insert(begin(), o); } push_back(const T & o)367 void push_back(const T& o) { insert(end(), o); } pop_front()368 void pop_front() { erase(begin()); } pop_back()369 void pop_back() 370 { 371 iterator tmp = end(); 372 erase(--tmp); 373 } 374 size()375 size_t size() 376 { 377 size_t count = 0; 378 for (iterator it = begin(); it != end(); it++) 379 count++; 380 return count; 381 } 382 Remove(iterator it)383 T Remove(iterator it) 384 { 385 if(it == end()) 386 return NULL; 387 388 T p = (*it); 389 it = erase(it); 390 return p; 391 } 392 RemoveFirst()393 T RemoveFirst() { return Remove(begin()); } 394 front()395 T& front() { return pBeginList->pNext->o; } 396 }; 397 398 399 #endif 400