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