raSystem  1.0 bata
raList.h
Go to the documentation of this file.
1 #pragma once
2 
3  template <typename T> struct raListEntry
4  {
7  T Data;
8  };
9 
10  template <typename T> class raList
11  {
12  private:
13  raListEntry<T>* m_pFirstEntry;
14  raListEntry<T>* m_pLastEntry;
15  int m_iNumEntries;
16 
17  public:
18  raList();
19  ~raList();
20 
21  raListEntry<T>* AddEntry(T* pData);
22  bool FindEntry(T* pData, raListEntry<T>** ppOut);
23  bool DeleteEntry(raListEntry<T>* pEntry);
24  bool Clear();
25  bool Traverse(bool (* pCallback)(raListEntry<T>*));
26 
27  T* GetEntryData(raListEntry<T>* pEntry) {return &pEntry->Data;}
28 
29  READONLY_PROPERTY(raListEntry<T>*, FirstEntry);
30  GET(FirstEntry) { return m_pFirstEntry; }
31  READONLY_PROPERTY(raListEntry<T>*, LastEntry);
32  GET(LastEntry) { return m_pLastEntry; }
33  READONLY_PROPERTY(int, Count);
34  GET(Count) { return m_iNumEntries; }
35 
36  protected:
37  virtual void __vsforeach( void (* func)(T&))
38  {
39  raListEntry<T>* pCurrentEntry = m_pFirstEntry;
40 
41  while(pCurrentEntry)
42  {
43  if(func) func(pCurrentEntry->Data);
44 
45  // Fortschreiten
46  pCurrentEntry = pCurrentEntry->pNextEntry;
47  }
48  }
49  };
50 
51  // ******************************************************************
52  // Konstruktor der raList-Klasse
53  template <typename T> raList<T>::raList()
54  {
55  // Alles zurücksetzen
56  memset(this, 0,sizeof(raList<T>));
57  }
58 
59  // ******************************************************************
60  // Destruktor der raList-Klasse
61  template <typename T> raList<T>::~raList()
62  {
63  }
64 
65  // ******************************************************************
66  // Diese Methode fügt einen neuen Eintrag zur Liste hinzu.
67  template <typename T> raListEntry<T>* raList<T>::AddEntry(T* pData)
68  {
69  raListEntry<T>* pNewEntry;
70 
71  // Parameter prüfen
72  if(!pData) { RERROR_NULLPOINTER("pData"); return NULL; }
73 
74  // Speicher für die Listeneintragsstruktur reservieren
75  pNewEntry = new raListEntry<T>;
76  if(!pNewEntry) { RERROR_OUTOFMEM(); return NULL; }
77 
78  // Der neue Eintrag steht an letzter Stelle der Liste.
79  // Daher gibt es keinen nächsten Eintrag und der vorherige Eintrag
80  // ist der ursprüngliche letzte Listeneintrag.
81  pNewEntry->pPrevEntry = m_pLastEntry;
82  if(m_pLastEntry) m_pLastEntry->pNextEntry = pNewEntry;
83  pNewEntry->pNextEntry = NULL;
84  m_pLastEntry = pNewEntry;
85 
86  // Wenn die Liste noch ganz leer ist, dann ist dieser Eintrag auch
87  // gleichzeitig der erste Eintrag.
88  if(!m_pFirstEntry) m_pFirstEntry = pNewEntry;
89 
90  // Daten kopieren
91  memcpy(&pNewEntry->Data, pData, sizeof(T));
92 
93  // Eintragszähler erhöhen
94  m_iNumEntries++;
95 
96  // Zeiger auf die Listeneintragsstruktur zurückliefern
97  return pNewEntry;
98  }
99 
100  // ******************************************************************
101  // Diese Methode sucht einen Eintrag in der Liste mit den angegebenen Daten.
102  template <typename T> bool raList<T>::FindEntry(T* pData, raListEntry<T>** ppOut)
103  {
104  raListEntry<T>* pCurrentEntry;
105 
106  // Parameter prüfen
107  if(!pData) RERROR_NULLPOINTER("pData", false);
108 
109  // Zuerst den allerersten Listeneintrag testen
110  pCurrentEntry = m_pFirstEntry;
111 
112  while(pCurrentEntry)
113  {
114  // Die Daten des aktuellen Eintrags mit den angegebenen Daten
115  // vergleichen. Falls sie übereinstimmen, ist die Suche beendet.
116  if(!memcmp(&pCurrentEntry->Data, pData, sizeof(T)))
117  {
118  // Falls gewünscht, wird der als Parameter angegebene Doppelzeiger
119  // nun auf die Adresse der Listeneintragsstruktur gesetzt.
120  if(ppOut) *ppOut = pCurrentEntry;
121  return true;
122  }
123 
124  // Fortschreiten
125  pCurrentEntry = pCurrentEntry->pNextEntry;
126  }
127 
128  // Es wurde nichts gefunden!
129  return false;
130  }
131 
132  // ******************************************************************
133  // Diese Methode löscht einen Eintrag in der Liste.
134  template <typename T> bool raList<T>::DeleteEntry(raListEntry<T>* pEntry)
135  {
136  // Parameter prüfen
137  if(!pEntry) { RERROR_NULLPOINTER("pEntry"); return false; }
138 
139  // Beim Löschen entsteht ein Loch in der Liste, welches nun "gestopft"
140  // werden muss. Dabei spielt es eine Rolle, ob der Eintrag an erster
141  // oder letzter Stelle oder irgendwo in der Mitte der Liste steht.
142  if(pEntry == m_pFirstEntry &&
143  pEntry == m_pLastEntry)
144  {
145  // Der Eintrag ist der erste und einzige.
146  m_pFirstEntry = NULL;
147  m_pLastEntry = NULL;
148  }
149  else if(pEntry == m_pFirstEntry)
150  {
151  // Der Eintrag steht an erster Stelle.
152  // Der neue erste Eintrag ist nun der Folgende des zu löschenden Eintrags.
153  m_pFirstEntry = pEntry->pNextEntry;
154  m_pFirstEntry->pPrevEntry = NULL;
155  }
156  else if(pEntry == m_pLastEntry)
157  {
158  // Der Eintrag steht an letzter Stelle.
159  // Der neue letzte Eintrag ist nun der Vorherige des zu löschenden Eintrags.
160  m_pLastEntry = pEntry->pPrevEntry;
161  m_pLastEntry->pNextEntry = NULL;
162  }
163  else
164  {
165  // Der Eintrag steht irgendwo in der Mitte.
166  // Der vorherige und der folgende Eintrag werden nun verknüpft.
167  pEntry->pPrevEntry->pNextEntry = pEntry->pNextEntry;
168  pEntry->pNextEntry->pPrevEntry = pEntry->pPrevEntry;
169  }
170 
171  // Der Speicher für sie wurde beim Erstellen eines neuen Eintrags
172  // reserviert und kann nun wieder freigegeben werden.
173  SAFE_DELETE(pEntry);
174 
175  // Eintragszähler verringern
176  m_iNumEntries--;
177 
178  return true;
179  }
180 
181  // ******************************************************************
182  // Diese Methode löscht die gesamte Liste.
183  template <typename T> bool raList<T>::Clear()
184  {
185  // Es wird so lange der erste Listeneintrag gelöscht, bis keiner mehr da ist.
186  while(m_pFirstEntry) DeleteEntry(m_pFirstEntry);
187 
188  return true;
189  }
190 
191  // ******************************************************************
192  // Durchlaufen der Liste
193  template <typename T> bool raList<T>::Traverse(bool (* pCallback)(raListEntry<T>*))
194  {
195  raListEntry<T>* pCurrentEntry;
196 
197  // Parameter prüfen
198  if(!pCallback) RERROR_NULLPOINTER("pCallback", false);
199 
200  // Die ganze Liste durchlaufen
201  pCurrentEntry = m_pFirstEntry;
202 
203  while(pCurrentEntry)
204  {
205  // Rückruffunktion aufrufen
206  if(pCallback(pCurrentEntry) == false) break;
207 
208  // Fortfahren
209  pCurrentEntry = pCurrentEntry->pNextEntry;
210  }
211 
212  return true;
213  }
raListEntry< T > * AddEntry(T *pData)
Definition: raList.h:67
bool DeleteEntry(raListEntry< T > *pEntry)
Definition: raList.h:134
raList()
Definition: raList.h:53
bool FindEntry(T *pData, raListEntry< T > **ppOut)
Definition: raList.h:102
GET(FirstEntry)
Definition: raList.h:30
virtual void __vsforeach(void(*func)(T &))
Definition: raList.h:37
raListEntry< T > * pPrevEntry
Definition: raList.h:5
bool Clear()
Definition: raList.h:183
Definition: raList.h:10
void RAPI RERROR_NULLPOINTER(raString x)
Definition: raMain.cpp:134
Definition: raList.h:3
T * GetEntryData(raListEntry< T > *pEntry)
Definition: raList.h:27
ID3D11Buffer D3D11_BUFFER_DESC void * pData
Definition: raSDKmesh.h:238
raListEntry< T > * pNextEntry
Definition: raList.h:6
T Data
Definition: raList.h:7
GET(LastEntry)
Definition: raList.h:32
bool Traverse(bool(*pCallback)(raListEntry< T > *))
Definition: raList.h:193
GET(Count)
Definition: raList.h:34
void RAPI RERROR_OUTOFMEM()
Definition: raMain.cpp:144
#define READONLY_PROPERTY(t, n)
#define SAFE_DELETE(p)
Definition: d3dxGlobal.h:26
~raList()
Definition: raList.h:61