Main Page   Class Hierarchy   Compound List   File List   Compound Members  

glcirclelist.h

00001 /*--License:
00002         Kyra Sprite Engine
00003         Copyright Lee Thomason (Grinning Lizard Software) 2001-2002
00004         www.grinninglizard.com/kyra
00005         www.sourceforge.net/projects/kyra
00006 
00007         Kyra is provided under 2 licenses:
00008 
00009         - The GPL, with no additional restrictions.
00010         - The LGPL, provided you display the Kyra splash screen, described below.
00011 
00012 
00013 --- GPL License --
00014         This program is free software; you can redistribute it and/or
00015         modify it under the terms of the GNU General Public License
00016         as published by the Free Software Foundation; either version 2
00017         of the License, or (at your option) any later version.
00018 
00019         This program is distributed in the hope that it will be useful,
00020         but WITHOUT ANY WARRANTY; without even the implied warranty of
00021         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022         GNU General Public License for more details.
00023 
00024         You should have received a copy of the GNU General Public License
00025         along with this program; if not, write to the Free Software
00026         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028         The full text of the license can be found in license.txt
00029 
00030 
00031 --- LGPL License --
00032   **Provided you kindly display the Kyra splash screen (details below), 
00033         you     may use the LGPL license:**
00034 
00035     This library is free software; you can redistribute it and/or
00036     modify it under the terms of the GNU Lesser General Public
00037     License as published by the Free Software Foundation; either
00038     version 2.1 of the License, or (at your option) any later version.
00039 
00040     This library is distributed in the hope that it will be useful,
00041     but WITHOUT ANY WARRANTY; without even the implied warranty of
00042     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00043     Lesser General Public License for more details.
00044 
00045     You should have received a copy of the GNU Lesser General Public
00046     License along with this library; if not, write to the Free Software
00047     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00048 
00049         The full text of the license can be found in lgpl.txt
00050 
00051 
00052 --- Kyra Splash Screen.
00053 
00054         It would be appreciate if you display the Kyra splash screen when using
00055         either license, however it is only required for the LGPL. All the
00056         resources for the splash are compiled into the library, and it can be
00057         accessed through the following API:
00058 
00059                 KrEngine::StartSplash
00060                 KrEngine::UpdateSplash
00061                 KrEngine::EndSplash
00062 
00063         Full documentation is provided with the KrEngine class. The splash screen
00064         should be displayed for 2 seconds.
00065 
00066         Thank you.
00067 */
00068 
00069 
00070 #ifndef KYRA_CIRCLELIST_INCLUDED
00071 #define KYRA_CIRCLELIST_INCLUDED
00072 
00073 #include "../util/gldebug.h"
00074 
00075 // OPT improvements:
00076 // - add memory allocator
00077 // - remove the 'data' from circle node, so the overhead isn't in
00078 //       the sentinels.
00079 
00080 template <class T>
00081 struct GlCircleNode
00082 {
00083         T data;
00084 
00085         GlCircleNode<T>* next;
00086         GlCircleNode<T>* prev;
00087 };
00088 
00089 /*
00090         A circular, double linked list.
00091 */
00092 template <class T>
00093 class GlCircleList
00094 {
00095   public:
00096         GlCircleList()          { sentinel.next = &sentinel; sentinel.prev = &sentinel; }
00097         ~GlCircleList()         { Clear(); }
00098 
00099         bool    Empty() const   { return sentinel.next == &sentinel; }
00100         T&              Front() const   { return sentinel.next->data; }
00101         T&              Back()  const   { return sentinel.prev->data; }
00102         GlCircleNode<T>* FrontNode() const      { return sentinel.next; }
00103         GlCircleNode<T>* BackNode()  const      { return sentinel.prev; }
00104 
00105         void Clear()                    {       GlCircleNode<T>* temp;
00106                                                                 while( sentinel.next != &sentinel )
00107                                                                 {
00108                                                                         temp = sentinel.next;
00109                                                                         sentinel.next = sentinel.next->next;
00110                                                                         delete temp;
00111                                                                 }
00112                                                                 sentinel.prev = &sentinel;
00113                                                         }
00114         void PushFront( const T& insert ) {
00115                                                                 GlCircleNode<T>* node = new GlCircleNode<T>;
00116                                                                 node->data = insert;
00117 
00118                                                                 node->prev = &sentinel;
00119                                                                 node->next = sentinel.next;
00120                                                                 sentinel.next->prev = node;
00121                                                                 sentinel.next = node;
00122                                                         }
00123         void PushBack( const T& insert ) {
00124                                                                 GlCircleNode<T>* node = new GlCircleNode<T>;
00125                                                                 node->data = insert;
00126 
00127                                                                 node->prev = sentinel.prev;
00128                                                                 node->next = &sentinel;
00129                                                                 sentinel.prev->next = node;
00130                                                                 sentinel.prev = node;
00131                                                         }
00132         void PopFront()                 {
00133                                                                 GLASSERT( sentinel.next != &sentinel );
00134                                                                 GlCircleNode<T>* node = sentinel.next;
00135 //                                                              node->prev->next = node->next;
00136 //                                                              node->next->prev = node->prev;
00137 //                                                              delete node;
00138                                                                 Delete( node );
00139                                                         }
00140         void PopBack()                  {
00141                                                                 GLASSERT( sentinel.prev != &sentinel );
00142                                                                 GlCircleNode<T>* node = sentinel.prev;
00143 //                                                              node->prev->next = node->next;
00144 //                                                              node->next->prev = node->prev;
00145 //                                                              delete node;
00146                                                                 Delete( node );
00147                                                         }
00148 
00149         void Delete( GlCircleNode<T>* node )    {
00150                                                                                                 GLASSERT( node != &sentinel );
00151                                                                                                 node->prev->next = node->next;
00152                                                                                                 node->next->prev = node->prev;
00153                                                                                                 delete node;
00154                                                                                         }
00155         GlCircleNode<T>* Find( T value )                {
00156                                                                                                 GlCircleNode<T>* node = sentinel.next;
00157                                                                                                 while ( node != &sentinel )
00158                                                                                                 {
00159                                                                                                         if ( node->data == value )
00160                                                                                                                 return node;
00161                                                                                                         node = node->next;
00162                                                                                                 }
00163                                                                                                 return 0;
00164                                                                                         }
00165 
00166         // Scoping problems. Pretend this is private.
00167         GlCircleNode<T> sentinel;
00168 };
00169 
00170 
00171 template <class T>
00172 class GlCircleListIterator
00173 {
00174   public:
00175         GlCircleListIterator( GlCircleList<T>& _list ) : current( 0 ), list( &_list )   {}
00176 
00177         void Begin()            { current = list->sentinel.next; }
00178         void Next()                     { current = current->next; }
00179         void Prev()                     { current = current->prev; }
00180         bool Done()                     { return ( current == &(list->sentinel) ); }
00181 
00183         T& Current()                                    { return (current->data); }
00184 
00185         void InsertBefore( const T& addMe )
00186         {
00187                 GlCircleNode<T>* node = new GlCircleNode<T>;
00188                 node->data = addMe;
00189 
00190                 node->prev = current->prev;
00191                 node->next = current;
00192                 current->prev->next = node;
00193                 current->prev = node;
00194         }
00195 
00196         void InsertAfter( const T& addMe )
00197         {
00198                 GlCircleNode<T>* node = new GlCircleNode<T>;
00199                 node->data = addMe;
00200 
00201                 node->prev = current;
00202                 node->next = current->next;
00203                 current->next->prev = node;
00204                 current->next = node;
00205         }
00206 
00207         void Remove()
00208         {
00209                 GLASSERT( current != &(list->sentinel) );
00210 
00211                 GlCircleNode<T>* temp = current;
00212                 current = current->next;
00213 
00214                 temp->prev->next = temp->next;
00215                 temp->next->prev = temp->prev;
00216                 delete temp;
00217         }
00218 
00219   private:
00220         GlCircleNode<T>* current;       
00221         GlCircleList<T>* list;
00222 };
00223 
00224 
00225 #endif

Generated on Fri Feb 7 20:44:20 2003 for Kyra by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001