00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_PS_ATTRIB_H
00027 #define NL_PS_ATTRIB_H
00028
00029
00030
00031 #include "nel/misc/types_nl.h"
00032 #include "nel/misc/stream.h"
00033 #include "nel/3d/animation_time.h"
00034 #include "nel/misc/vector.h"
00035 #include "nel/misc/rgba.h"
00036 #include "nel/misc/common.h"
00037
00038
00039 namespace NL3D {
00040
00043 template <class T, const uint snapPower = 5>
00044 class CSnappedVector
00045 {
00046 public:
00047 typedef T *iterator;
00048 typedef const T *const_iterator;
00049 typedef T value_type;
00050
00051 CSnappedVector() : _Size(0), _Capacity(0), _Start(NULL), _Tab(NULL) {}
00052 ~CSnappedVector()
00053 {
00054 nlassert(_Size <= _Capacity);
00055 for (iterator it = _Tab, endIt = _Tab + _Size; it != endIt; ++it)
00056 {
00057 it->~T();
00058 }
00059 delete _Start;
00060 }
00061 iterator begin(void) { return _Tab; }
00062 const_iterator begin(void) const { return _Tab; }
00063 iterator end(void) { return _Tab + _Size; }
00064 const_iterator end(void) const { return _Tab + _Size; }
00065
00066 T &operator[](uint index) { nlassert(index < _Size && _Size); return _Tab[index]; }
00067 const T &operator[](uint index) const { nlassert(index < _Size && _Size); return _Tab[index]; }
00068
00070 void reserve(uint capacity)
00071 {
00072 if (capacity < _Capacity) return;
00073 uint8 *newStart = NULL;
00074 try
00075 {
00076 newStart = new uint8[sizeof(T) * capacity + (1 << snapPower)];
00077 T *newTab = (T *) ( (uint) (newStart + (1 << snapPower)) & ~((1 << snapPower) - 1));
00078
00079
00080
00081 for (iterator src = _Tab, end = _Tab + (capacity < _Size ? capacity : _Size), dest = newTab
00082 ; src != end
00083 ; ++ src, ++dest)
00084 {
00085 new ((void *) dest) T(*src);
00086 }
00087
00088
00089 std::swap(_Start, newStart);
00090 std::swap(_Tab, newTab);
00091
00092
00093 for (iterator it = newTab , endIt = newTab + _Size; it != endIt; ++ it)
00094 {
00095 it->~T();
00096 }
00097
00098
00099 _Capacity = capacity;
00100 _Size = capacity < _Size ? capacity : _Size;
00101
00102
00103
00104 delete [] newStart;
00105 nlassert(_Size <= _Capacity);
00106 }
00107 catch (...)
00108 {
00109 delete [] newStart;
00110 throw;
00111 }
00112
00113 }
00114 void resize(uint size)
00115 {
00116 nlassert(size < (1 << 16));
00117 if (size < _Size)
00118 {
00119 for (iterator it = _Tab + size, endIt = _Tab + _Size; it != endIt; ++it)
00120 {
00121 it->~T();
00122 }
00123 }
00124 else
00125 {
00126 if (size > _Capacity)
00127 {
00128 reserve(size);
00129 }
00130 for (iterator it = _Tab + _Size, endIt = _Tab + size; it != endIt; ++it)
00131 {
00132 new ((void *) it) T();
00133 }
00134 }
00135
00136 _Size = size;
00137 nlassert(_Size <= _Capacity);
00138 }
00139
00140 void push_back(const T &t)
00141 {
00142 if (!_Size)
00143 {
00144 reserve(2);
00145 new ((void *) _Tab) T(t);
00146 _Size = 1;
00147 }
00148 else
00149 if (_Size < _Capacity)
00150 {
00151 new ((void *) (_Tab + _Size)) T(t);
00152 ++_Size;
00153 }
00154 else
00155 if (_Size == _Capacity)
00156 {
00157 if (_Capacity == 1)
00158 {
00159 reserve(2);
00160 }
00161 else
00162 {
00163 reserve(_Capacity + (_Capacity>>1));
00164 }
00165 nlassert(_Size <= _Capacity);
00166 new ((void *) (_Tab + _Size)) T(t);
00167 ++_Size;
00168 }
00169 }
00170
00171 void pop_back()
00172 {
00173 nlassert(_Size);
00174 _Tab[_Size - 1].~T();
00175 --_Size;
00176 }
00177
00178
00179 uint capacity() const { return _Capacity; }
00180 uint size() const { return _Size; }
00181
00183 void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00184 {
00185 if (f.isReading())
00186 {
00187 clear();
00188 uint32 size, maxsize;
00189 f.serial(size, maxsize);
00190 reserve(maxsize);
00191 for (uint k = 0; k < size; ++k)
00192 {
00193 T tmp;
00194 f.serial(tmp);
00195 push_back(tmp);
00196 }
00197 }
00198 else
00199 {
00200 f.serial(_Size, _Capacity);
00201 for (uint k = 0; k < _Size; ++k)
00202 {
00203 f.serial(_Tab[k]);
00204 }
00205 }
00206 }
00207
00208
00209 void clear() { resize(0); }
00210
00211 protected:
00212
00213 uint8 *_Start;
00214 T *_Tab;
00215 uint32 _Size;
00216 uint32 _Capacity;
00217 };
00218
00219
00220
00221
00222
00223
00233 template <typename T> class CPSAttrib
00234 {
00235 public:
00236
00238
00239
00240 CPSAttrib();
00241
00243 void serial(NLMISC::IStream &f) throw(NLMISC::EStream);
00245
00247
00248
00251
00252 typedef std::vector<T> TContType;
00253
00255 typedef T value_type;
00256
00258 typedef typename TContType::iterator iterator;
00260 typedef typename TContType::const_iterator const_iterator;
00262
00263
00265
00266
00269 void resize(uint32 nbInstances);
00270
00272 uint32 getSize(void) const { return _Tab.size(); }
00273
00275 uint32 getMaxSize(void) const { return _MaxSize; }
00276
00278
00279
00281
00282
00283 const T & operator[](uint32 index) const
00284 {
00285 #ifdef NL_DEBUG
00286 nlassert(index < _Tab.size());
00287 #endif
00288 return _Tab[index];
00289 }
00290
00292 T & operator[](uint32 index)
00293 {
00294 #ifdef NL_DEBUG
00295 nlassert(index < _Tab.size());
00296 #endif
00297 return _Tab[index];
00298 }
00300
00301
00302
00304
00305
00306
00308 iterator begin(void) { return _Tab.begin(); }
00309
00311 iterator end(void) { return _Tab.end(); }
00312
00314 const_iterator begin(void) const { return _Tab.begin(); }
00315
00317 const_iterator end(void) const { return _Tab.end(); }
00319
00321
00322
00326 sint32 insert(const T &t = T() );
00327
00329 void remove(uint32 index);
00330
00332 void clear(void)
00333 {
00334 _Tab.clear();
00335 }
00337
00338 protected:
00339 TContType _Tab;
00340 uint32 _MaxSize;
00341 };
00342
00343
00344
00345
00346
00348
00350
00351 template <typename T>
00352 CPSAttrib<T>::CPSAttrib()
00353 {
00354 _MaxSize = DefaultMaxLocatedInstance;
00355 }
00356
00357
00358 template <typename T>
00359 void CPSAttrib<T>::resize(uint32 nbInstances)
00360 {
00361 nlassert(nbInstances < (1 << 16));
00362 _Tab.reserve(nbInstances);
00363 _MaxSize = nbInstances;
00364 }
00365
00366
00367 template <typename T>
00368 sint32 CPSAttrib<T>::insert(const T &t)
00369 {
00370 if (_Tab.size() == _MaxSize && _Tab.size() > DefaultMaxLocatedInstance)
00371 {
00372 return -1;
00373 }
00374 _Tab.push_back(t);
00375 return _Tab.size() - 1;
00376 }
00377
00378
00379 template <typename T>
00380 void CPSAttrib<T>::remove(uint32 index)
00381 {
00382 nlassert(index < _Tab.size());
00383
00384 if (index != _Tab.size() - 1)
00385 {
00386 _Tab[index] = _Tab[_Tab.size() - 1];
00387 }
00388 _Tab.pop_back();
00389
00390 }
00391
00392 template <typename T>
00393 void CPSAttrib<T>::serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00394 {
00395 sint ver = f.serialVersion(3);
00396
00397
00398 if (ver == 1)
00399 {
00400 if(f.isReading())
00401 {
00402 uint32 size;
00403 f.serial(size);
00404 f.serial(_MaxSize);
00405 _Tab.reserve(_MaxSize);
00406 f.serial(size);
00407 T tmp;
00408
00409 for(uint i = 0; i < size; i++)
00410 {
00411 f.serial(tmp);
00412 _Tab.push_back(tmp);
00413 }
00414 nlassert(_Tab.size() == size);
00415 }
00416 else
00417 {
00418 uint32 size = _Tab.size();
00419 f.serial(size);
00420 f.serial(_MaxSize);
00421 f.serial(size);
00422
00423 for(uint i = 0; i < size; i++)
00424 {
00425 f.serial(_Tab[i]);
00426 }
00427 }
00428 }
00429
00430 if (ver == 2)
00431 {
00432 nlassert(0);
00433
00434
00435
00436
00437
00438 }
00439
00440 if (ver == 3)
00441 {
00442 f.serial(_MaxSize);
00443 _Tab.reserve(_MaxSize);
00444
00445
00446
00447 if (f.isReading())
00448 {
00449 _Tab.clear();
00450 uint32 size, maxsize;
00451 f.serial(size, maxsize);
00452 _Tab.reserve(maxsize);
00453 for (uint k = 0; k < size; ++k)
00454 {
00455 T tmp;
00456 f.serial(tmp);
00457 _Tab.push_back(tmp);
00458 }
00459 }
00460 else
00461 {
00462 uint32 size = _Tab.size(), capacity = _Tab.capacity();
00463 f.serial(size, capacity);
00464 for (uint k = 0; k < size; ++k)
00465 {
00466 f.serial(_Tab[k]);
00467 }
00468 }
00469 }
00470 }
00471
00472
00473
00474
00475
00476
00477 typedef CPSAttrib<NLMISC::CVector> TPSAttribVector;
00478 typedef CPSAttrib<NLMISC::CRGBA> TPSAttribRGBA;
00479 typedef CPSAttrib<float> TPSAttribFloat;
00480 typedef CPSAttrib<uint32> TPSAttribUInt;
00481 typedef CPSAttrib<uint8> TPSAttribUInt8;
00482 typedef CPSAttrib<TAnimationTime> TPSAttribTime;
00483
00484
00485
00486
00487
00488 }
00489
00490
00491 #endif // NL_PS_ATTRIB_H
00492
00493