$treeview $search $mathjax
Stratagus
2.2.6
$projectbrief
|
$projectbrief
|
$searchbox |
_________ __ __ / _____// |_____________ _/ |______ ____ __ __ ______ \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ \ /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > \/ \/ \//_____/ \/ ______________________ ______________________ T H E W A R B E G I N S Stratagus - A free fantasy real time strategy game engine
00001 // _________ __ __ 00002 // / _____// |_____________ _/ |______ ____ __ __ ______ 00003 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ 00004 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ | 00005 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > 00006 // \/ \/ \//_____/ \/ 00007 // ______________________ ______________________ 00008 // T H E W A R B E G I N S 00009 // Stratagus - A free fantasy real time strategy game engine 00010 // 00012 // 00013 // (c) Copyright 2008 by Rafal Bursig 00014 // 00015 // This program is free software; you can redistribute it and/or modify 00016 // it under the terms of the GNU General Public License as published by 00017 // the Free Software Foundation; only version 2 of the License. 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 00027 // 02111-1307, USA. 00028 00029 #ifndef __UNIT_CACHE_H__ 00030 #define __UNIT_CACHE_H__ 00031 00033 00034 /*---------------------------------------------------------------------------- 00035 -- Includes 00036 ----------------------------------------------------------------------------*/ 00037 00038 #include <vector> 00039 #include <algorithm> 00040 #include <stdio.h> 00041 00042 /*---------------------------------------------------------------------------- 00043 -- Declarations 00044 ----------------------------------------------------------------------------*/ 00045 00046 class CUnit; 00047 00051 struct CUnitCache { 00052 std::vector<CUnit *> Units; 00053 00054 CUnitCache() : Units() { Units.clear();} 00055 00056 inline size_t size() const 00057 { 00058 return Units.size(); 00059 } 00060 inline void clear() 00061 { 00062 Units.clear(); 00063 } 00064 inline CUnit * operator[] (const unsigned int index) const 00065 { 00066 //Assert(index < Units.size()); 00067 return Units[index]; 00068 } 00069 inline CUnit * operator[] (const unsigned int index) { 00070 //Assert(index < Units.size()); 00071 return Units[index]; 00072 } 00073 00080 template<typename _T> 00081 inline CUnit *find(const _T &pred) const 00082 { 00083 #if __GNUC__ < 4 00084 if(Units.size()) { 00085 std::vector<CUnit *>::const_iterator beg(Units.begin()), end(Units.end()); 00086 std::vector<CUnit *>::const_iterator ret = std::find_if(beg, end, pred); 00087 return ret != end ? (*ret) : NULL; 00088 } 00089 return NULL; 00090 #else 00091 //GCC version only since std::vector::data() is not in STL 00092 const size_t size = Units.size(); 00093 if(size) { 00094 const CUnit *unit; 00095 int n = (size+3)/4; 00096 const CUnit **cache = (const CUnit **)Units.data(); 00097 switch (size & 3) { 00098 case 0: 00099 do { 00100 unit = *cache; 00101 if(pred(unit)) 00102 return (CUnit *)unit; 00103 cache++; 00104 case 3: 00105 unit = *cache; 00106 if(pred(unit)) 00107 return (CUnit *)unit; 00108 cache++; 00109 case 2: 00110 unit = *cache; 00111 if(pred(unit)) 00112 return (CUnit *)unit; 00113 cache++; 00114 case 1: 00115 unit = *cache; 00116 if(pred(unit)) 00117 return (CUnit *)unit; 00118 cache++; 00119 } while ( --n > 0 ); 00120 } 00121 } 00122 return NULL; 00123 #endif 00124 } 00125 00134 template<typename _T> 00135 inline void for_each(_T functor) 00136 { 00137 const size_t size = Units.size(); 00138 #if __GNUC__ < 4 00139 for(unsigned int i = 0; i < size; ++i) 00140 functor(Units[i]); 00141 #else 00142 //GCC version only since std::vector::data() is not in STL 00143 if(size) { 00144 int n = (size+3)/4; 00145 CUnit **cache = (CUnit **)Units.data(); 00146 switch (size & 3) { 00147 case 0: do { 00148 functor(*cache++); 00149 case 3: functor(*cache++); 00150 case 2: functor(*cache++); 00151 case 1: functor(*cache++); 00152 } while ( --n > 0 ); 00153 } 00154 } 00155 #endif 00156 } 00157 00167 template<typename _T> 00168 inline int for_each_if(_T &functor) 00169 { 00170 const size_t size = Units.size(); 00171 size_t count = 0; 00172 #ifdef _MSC_VER 00173 while(size && functor(Units[count]) && ++count < size); 00174 #else 00175 if(size) { 00176 int n = (size+3)/4; 00177 switch (size & 3) { 00178 case 0: 00179 do { 00180 if(!functor(Units[count])) 00181 return count; 00182 count++; 00183 case 3: 00184 if(!functor(Units[count])) 00185 return count; 00186 count++; 00187 case 2: 00188 if(!functor(Units[count])) 00189 return count; 00190 count++; 00191 case 1: 00192 if(!functor(Units[count])) 00193 return count ; 00194 count++; 00195 } while ( --n > 0 ); 00196 } 00197 } 00198 #endif 00199 return count; 00200 } 00201 00202 00209 inline CUnit * Remove(const unsigned int index) 00210 { 00211 const size_t size = Units.size(); 00212 Assert(index < size); 00213 CUnit *tmp = Units[index]; 00214 if(size > 1) { 00215 Units[index] = Units[size - 1]; 00216 } 00217 Units.pop_back(); 00218 return tmp; 00219 } 00220 00226 inline bool Remove(CUnit *const unit) 00227 { 00228 #ifndef SECURE_UNIT_REMOVING 00229 const size_t size = Units.size(); 00230 if(size == 1 && unit == Units[0]) { 00231 Units.pop_back(); 00232 return true; 00233 } else { 00234 for(unsigned int i = 0; i < size; ++i) { 00235 // Do we care on unit sequence in tile cache ? 00236 if (Units[i] == unit) { 00237 Units[i] = Units[size - 1]; 00238 Units.pop_back(); 00239 return true; 00240 } 00241 } 00242 } 00243 #else 00244 for(std::vector<CUnit *>::iterator i(Units.begin()), end(Units.end()); 00245 i != end; ++i) { 00246 if ((*i) == unit) { 00247 Units.erase(i); 00248 return true; 00249 } 00250 } 00251 #endif 00252 return false; 00253 } 00254 00260 inline void RemoveS(CUnit *const unit) 00261 { 00262 for(std::vector<CUnit *>::iterator i(Units.begin()), end(Units.end()); 00263 i != end; ++i) { 00264 if ((*i) == unit) { 00265 Units.erase(i); 00266 return; 00267 } 00268 } 00269 } 00270 00278 inline bool InsertS(CUnit *unit) { 00279 if (!binary_search(Units.begin(), Units.end(), unit)) 00280 { 00281 Units.insert(std::lower_bound(Units.begin(), Units.end(), unit), unit); 00282 return true; 00283 } 00284 return false; 00285 } 00286 00287 00293 inline void Insert(CUnit *unit) { 00294 Units.push_back(unit); 00295 } 00296 }; 00297 00298 00300 00301 #endif // !__UNIT_CACHE_H__ 00302