00001 /* 00002 Copyright (C) 2001 The Exult Team 00003 00004 This program is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU General Public License 00006 as published by the Free Software Foundation; either version 2 00007 of the License, or (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU General Public License for more details. 00013 00014 You should have received a copy of the GNU General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 00019 #ifndef OBJLIST_H 00020 #define OBJLIST_H 00021 00022 #include "shapeid.h" 00023 00024 template<class T> 00025 class T_Object_iterator; 00026 template<class T, class L> 00027 class T_Flat_object_iterator; 00028 template<class T, class L> 00029 class T_Object_iterator_backwards; 00030 00031 /* 00032 * A list of objects chained together with the 'next' and 'prev' 00033 * fields: 00034 */ 00035 template<class T> 00036 class T_Object_list 00037 { 00038 friend class T_Object_iterator<T>; 00039 friend class T_Flat_object_iterator<T, class L>; 00040 friend class T_Object_iterator_backwards<T, class L>; 00041 00042 T first; // ->first in (circular) chain. 00043 unsigned short iter_count; // # of iterators. 00044 public: 00045 T_Object_list(T f = 0) : first(f), iter_count(0) 00046 { } 00047 // Delete the chain. 00048 ~T_Object_list() 00049 { 00050 if (!first) 00051 return; 00052 T objects = first; 00053 T obj; 00054 do 00055 { 00056 obj = objects; 00057 objects = obj->next; 00058 delete obj; 00059 } 00060 while (obj != first); 00061 } 00062 // Report iterator problem. 00063 void report_problem() const 00064 { 00065 std::cerr << "Danger! Danger! Object list modified while being iterated." << std::endl; 00066 std::cerr.flush(); 00067 } 00068 int is_empty() const 00069 { return first == 0; } 00070 void add_iterator() 00071 { iter_count++; } 00072 void remove_iterator() 00073 { iter_count--; } 00074 T get_first() const 00075 { return first; } 00076 // Insert at head of chain. 00077 void insert(T nobj) 00078 { 00079 if (iter_count) 00080 report_problem(); 00081 if (!first) // First one. 00082 nobj->next = nobj->prev = nobj; 00083 else 00084 { 00085 nobj->next = first; 00086 nobj->prev = first->prev; 00087 first->prev->next = nobj; 00088 first->prev = nobj; 00089 } 00090 first = nobj; 00091 } 00092 // Insert before given obj. 00093 void insert_before(T nobj, T before) 00094 { 00095 if (iter_count) 00096 report_problem(); 00097 nobj->next = before; 00098 nobj->prev = before->prev; 00099 before->prev->next = nobj; 00100 before->prev = nobj; 00101 first = before == first ? nobj : first; 00102 } 00103 // Append. 00104 void append(T nobj) 00105 { insert(nobj); first = nobj->next; } 00106 void remove(T dobj) 00107 { 00108 if (iter_count) 00109 report_problem(); 00110 if (dobj == first) 00111 first = dobj->next != first ? dobj->next : 0; 00112 dobj->next->prev = dobj->prev; 00113 dobj->prev->next = dobj->next; 00114 } 00115 }; 00116 00117 00118 class Game_object; 00119 typedef T_Object_list<Game_object *> Object_list; 00120 00121 00122 #endif