]> jfr.im git - irc/gameservirc.git/blob - gameserv/list.h
Fixed a bug in check_idles() in tcpclient.cpp causing is_playing(0x0) to be called...
[irc/gameservirc.git] / gameserv / list.h
1 #ifndef LIST_H
2 #define LIST_H
3
4 #include <iostream>
5 #include <cassert>
6 #include "listnode.h"
7 #include "aClient.h"
8 #include "extern.h"
9 #include "options.h"
10
11 using std::cout;
12 using std::endl;
13 using std::flush;
14
15 template <class T>
16 class List {
17 public:
18 List(); //constructor
19 ~List(); //deconstructor
20 T *insertAtFront( const T & );
21 T *insertAtBack( T *&);
22 ListNode<T> *insertAtBack_RLN( T *&);
23 bool removeFromFront( T & );
24 bool removeFromBack( T & );
25 bool del( T *);
26 ListNode < T > *remove( T * );
27 bool isEmpty() const;
28 #ifdef DEBUGMODE
29 void print() const;
30 #endif
31 void deleteNodes();
32
33 ListNode < T > *Find( T * );
34 ListNode < T > *First() { return firstPtr; };
35 ListNode < T > *Last() { return lastPtr; };
36 private:
37 ListNode < T > *firstPtr;
38 ListNode < T > *lastPtr;
39
40 ListNode < T > *getNewNode ( const T & );
41 };
42
43 template <class T>
44 List<T>::List() : firstPtr (0), lastPtr (0) {}
45
46 template <class T>
47 void List<T>::deleteNodes()
48 {
49 if (isEmpty())
50 return;
51 ListNode<T> *it = firstPtr, *tempPtr;
52 while (it)
53 {
54 tempPtr = it;
55 it = it->Next();
56 delete tempPtr;
57 }
58 firstPtr = NULL;
59 lastPtr = NULL;
60 }
61
62 template <class T>
63 List<T>::~List()
64 {
65 deleteNodes();
66 }
67
68 template<class T>
69 T *List<T>::insertAtFront( const T &value )
70 {
71 ListNode<T> *newPtr = getNewNode ( value );
72
73
74 if (isEmpty())
75 firstPtr = lastPtr = newPtr;
76 else
77 {
78 newPtr->Next = firstPtr;
79 firstPtr->prev = newPtr;
80 firstPtr = newPtr;
81 }
82 return firstPtr->getData();
83 }
84
85 template<class T>
86 T *List<T>::insertAtBack(T *&value )
87 {
88 ListNode<T> *newPtr = getNewNode(*value);
89
90 if (isEmpty())
91 {
92 firstPtr = lastPtr = newPtr;
93 }
94 else
95 {
96 newPtr->prev = lastPtr;
97 lastPtr->next = newPtr;
98 lastPtr = newPtr;
99 }
100 return lastPtr->getData();
101 }
102
103 template<class T>
104 ListNode<T> *List<T>::insertAtBack_RLN(T *&value )
105 {
106 ListNode<T> *newPtr = getNewNode(*value);
107
108 if (isEmpty())
109 {
110 firstPtr = lastPtr = newPtr;
111 }
112 else
113 {
114 newPtr->prev = lastPtr;
115 lastPtr->next = newPtr;
116 lastPtr = newPtr;
117 }
118 return lastPtr;
119 }
120
121
122 template <class T>
123 bool List<T>::removeFromFront( T &value )
124 {
125 if ( isEmpty())
126 return false;
127 else
128 {
129 ListNode<T> *tempPtr = firstPtr;
130
131 if ( firstPtr == lastPtr )
132 firstPtr = lastPtr = 0;
133 else
134 firstPtr = firstPtr->next;
135
136 value = tempPtr->getData();
137 delete tempPtr;
138 return true;
139 }
140 }
141
142 template <class T>
143 bool List<T>::removeFromBack( T &value )
144 {
145 if ( isEmpty() )
146 return false;
147 else
148 {
149 ListNode<T> *tempPtr = lastPtr;
150
151 if ( firstPtr == lastPtr )
152 lastPtr = firstPtr = 0;
153 else
154 lastPtr = lastPtr->prev;
155
156 value = tempPtr->getData();
157 delete tempPtr;
158 return true;
159
160 }
161 }
162
163 template <class T>
164 bool List<T>::isEmpty() const
165 { return firstPtr == 0 && lastPtr == 0; }
166
167 template <class T>
168 ListNode<T> *List<T>::getNewNode( const T &value)
169 {
170 ListNode<T> *ptr = new ListNode<T>(value);
171
172 assert( ptr != 0);
173
174 return ptr;
175 }
176 template<class T>
177 ListNode<T> *List<T>::Find( T *value )
178 {
179 if (isEmpty()) {return NULL;}
180
181 ListNode<T> *currentPtr;
182 currentPtr = firstPtr;
183 while (currentPtr)
184 {
185 cout << currentPtr->getData() << endl << value << endl;
186 if (currentPtr->getData() == value)
187 return currentPtr;
188 currentPtr = currentPtr->Next();
189 }
190 return NULL;
191 }
192
193 #ifdef DEBUGMODE
194 template <class T>
195 void List<T>::print() const
196 {
197 if (isEmpty())
198 {
199 cout << "Empty list" << endl;
200 return;
201 }
202
203 ListNode<T> *currentPtr;
204 currentPtr = firstPtr;
205 while (currentPtr)
206 {
207 /*
208 cout << "aClient: " << *currentPtr->getData() << flush;
209
210 if (currentPtr->getData()->stats)
211 cout << " Player Name: " << currentPtr->getData()->stats->name
212 << " Password: " << currentPtr->getData()->stats->password << flush;
213 cout << endl;
214 */
215 cout << currentPtr->getData()->getString() << endl;
216 currentPtr = currentPtr->next;
217 }
218 }
219 #endif
220
221 template <class T>
222 bool List<T>::del(T *remPtr)
223 {
224 ListNode<T> *removed = remove( remPtr );
225 if (removed != NULL)
226 {
227 delete removed;
228 return true;
229 }
230 return false;
231 }
232
233 template <class T>
234 ListNode<T> *List<T>::remove(T *remPtr)
235 {
236 ListNode<T> *newPtr = firstPtr;
237 T *testPtr;
238
239 if (isEmpty())
240 return false;
241
242 while (newPtr)
243 {
244 testPtr = newPtr->getData();
245 if (testPtr == remPtr)
246 {
247 if (firstPtr == lastPtr)
248 {
249 #ifdef DEBUGMODE
250 log("One Element. Deleting it");
251 #endif
252 firstPtr = lastPtr = NULL;
253 return newPtr;
254 }
255 else if (newPtr != lastPtr && newPtr != firstPtr)
256 {
257 #ifdef DEBUGMODE
258 log("Many elements, this one is in the middle. Deleting it, linking front to back, and back to front.");
259 #endif
260 newPtr->prev->next = newPtr->next;
261 newPtr->next->prev = newPtr->prev;
262 return newPtr;
263 }
264 else if (newPtr == lastPtr)
265 {
266 #ifdef DEBUGMODE
267 log("This was the last element. Deleting it, and pointing the tail to its previous element.");
268 #endif
269 lastPtr = newPtr->prev;
270 lastPtr->next = 0;
271 return newPtr;
272 }
273 else if (newPtr == firstPtr)
274 {
275 #ifdef DEBUGMODE
276 log("This was the first element. Deleting it, and pointing the head to its next element.");
277 #endif
278 firstPtr = newPtr->next;
279 firstPtr->prev = 0;
280 return newPtr;
281 }
282 }
283 newPtr = newPtr->next;
284 }
285 return NULL;
286 }
287 #endif