Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

id.h

Go to the documentation of this file.
00001 /******************************************************************************** 00002 * 00003 * urbanVictory engine 00004 * Copyright (C) 2003, 2004 Adam Cubitt 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00019 * 00020 ********************************************************************************/ 00021 00029 #ifndef __ID__ 00030 #define __ID__ 00031 00032 00033 #include <list> 00034 #include <cassert> 00035 #include <iostream> 00036 00037 00038 00039 00040 typedef unsigned int uInt; 00041 #define Assert(a, b) assert( a && b) 00042 00043 00044 class noRecycling; 00045 template<class> 00046 class wrapAround; 00047 00049 00055 template<uInt bitsIndex, uInt bitsMagic> 00056 class id 00057 { 00058 public: 00059 id<bitsIndex,bitsMagic>() : m_id(0) {} 00060 id<bitsIndex,bitsMagic>(const uInt& v) { m_id = v; } 00061 ~id<bitsIndex,bitsMagic>() {} 00062 00064 id<bitsIndex,bitsMagic> & operator=(const id<bitsIndex,bitsMagic>& id_) { m_id = id_; return *this; } 00066 id<bitsIndex,bitsMagic> & operator=(const uInt& v) { m_id = v; return *this; } 00068 operator uInt () const { return m_id; } 00070 bool operator==(const id<bitsIndex,bitsMagic>& id_) const { return m_id == id_; } 00072 bool operator!=(const id<bitsIndex,bitsMagic>& id_) const { return m_id != id_; } 00074 bool isNull() const { return m_id == 0; } 00076 template<uInt bitsIndex_, uInt bitsMagic_> 00077 id<bitsIndex,bitsMagic> & operator=(const id<bitsIndex_,bitsMagic_>& id_) 00078 { 00079 Assert(id_.m_index<=MAX_INDEX && id_.m_magic<=MAX_MAGIC, "invalid assignment to an id from an id of a different type"); 00080 m_index = id_.m_index; 00081 m_magic = id_.m_magic; 00082 return *this; 00083 } 00084 00086 enum 00087 { 00088 BITS_INDEX = bitsIndex, 00089 BITS_MAGIC = bitsMagic, 00090 MAX_INDEX = 1<<(bitsIndex - 1), 00091 MAX_MAGIC = 1<<(bitsMagic - 1) 00092 }; 00093 00095 union 00096 { 00097 struct 00098 { 00099 uInt m_index : bitsIndex; 00100 uInt m_magic : bitsMagic; 00101 }; 00102 00103 uInt m_id : (bitsIndex+bitsMagic); 00104 }; 00105 protected: 00106 private: 00107 }; 00108 00109 00110 00112 00115 template< uInt numBits > 00116 class newIdGen 00117 { 00118 protected: 00119 newIdGen() : m_idGen(0) {} 00120 00123 enum 00124 { 00125 NUM_BITS = numBits, 00126 MAX_ID = 1 << (numBits - 1) 00127 }; 00128 00130 uInt m_idGen : numBits; 00131 }; 00132 00133 00135 00142 template< 00143 class recyclingPolicy = noRecycling, 00144 template <class> class wrapAroundPolicy = wrapAround, 00145 uInt numBits = 32 00146 > 00147 class idGen 00148 : public recyclingPolicy 00149 , public wrapAroundPolicy< newIdGen<numBits> > 00150 { 00151 public: 00153 uInt getId() 00154 { 00155 // attempt to get a recycled id (dependant on the policiy used) 00156 uInt id = getRecycledId(); 00157 00158 // if we didn't get a recycled id then get a new one 00159 if(!id) id = getNewId(); 00160 00161 // otherwise attempt to generate a new id and return the result 00162 return id; 00163 } 00164 00165 00166 protected: 00167 private: 00168 }; 00169 00170 00171 00172 00174 class noRecycling 00175 { 00176 public: 00178 void releaseId(uInt id) {} 00179 00180 protected: 00182 uInt getRecycledId() { return 0; } 00183 00184 private: 00185 }; 00186 00187 00189 class recycleReleasedIds 00190 { 00191 public: 00193 void releaseId(uInt id) 00194 { 00195 m_releasedIds.push_back(id); 00196 } 00197 00198 protected: 00201 uInt getRecycledId() 00202 { 00203 if(m_releasedIds.size()) 00204 { 00205 uInt id = *(m_releasedIds.begin()); 00206 m_releasedIds.pop_front(); 00207 return id; 00208 } else 00209 { 00210 return 0; 00211 } 00212 } 00213 00214 private: 00216 std::list<uInt> m_releasedIds; 00217 }; 00218 00219 00221 template<class _newIdGen> 00222 class wrapAround : public _newIdGen 00223 { 00224 public: 00226 uInt getNewId() 00227 { 00228 if(++m_idGen==0) 00229 { 00230 m_idGen = 1; 00231 } 00232 return m_idGen; 00233 } 00234 protected: 00235 private: 00237 //uInt m_idGen; 00238 }; 00239 00240 00244 template<class _newIdGen> 00245 class assertOnWrapAround : public _newIdGen 00246 { 00247 public: 00250 uInt getNewId() 00251 { 00252 ++m_idGen; 00253 Assert(m_idGen,"exceeded maximum id"); 00254 return m_idGen; 00255 } 00256 protected: 00257 private: 00258 }; 00259 00260 00261 00262 00265 template<class _newIdGen> 00266 class noWrapAround : public _newIdGen 00267 { 00268 public: 00271 uInt getNewId() 00272 { 00273 // if this is the maximum id 00274 if(m_idGen==MAX_ID) 00275 { 00276 // return the null id 00277 return 0; 00278 } 00279 return ++m_idGen; 00280 } 00281 protected: 00282 private: 00283 }; 00284 00285 #endif

Generated on Sun Mar 6 22:12:28 2005 for virtualMachine03 by doxygen 1.3.7