00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef NL_IDENTIFIANT_H
00028 #define NL_IDENTIFIANT_H
00029 #include <stdlib.h>
00030 #include "nel/misc/file.h"
00031 #include "nel/ai/e/ai_exception.h"
00032 #include "nel/ai/agent/agent_string.h"
00033 #include "nel/ai/agent/identtype.h"
00034
00035 namespace NLAIAGENT
00036 {
00037 class IRefrence;
00038
00039
00040
00050 template<class T = sint64, sint32 indexMax = maxIndex, T maxT = (T)-1>
00051 class CIndexVariant
00052 {
00053 protected:
00055 T _Id[indexMax];
00056 private:
00057
00064 void inc(int n)
00065 {
00066 if (n == getMaxIndex())
00067 {
00068
00069 throw NLAIE::CExceptionIndexError();
00070 }
00071
00072 if (_Id[n] == maxT)
00073 {
00074
00075 inc(n+1);
00076 _Id[n] = 0;
00077 }
00078 else _Id[n]++;
00079 }
00080 public:
00081
00082
00084 CIndexVariant(const CIndexVariant<T,indexMax,maxT> &a)
00085 {
00086 memcpy(_Id,a._Id,getMaxIndex()*sizeof(T));
00087 }
00088
00090 CIndexVariant(const T *id)
00091 {
00092 for(sint32 i = 0; i < getMaxIndex(); i ++)
00093 {
00094 _Id[i] = id[i];
00095 }
00096 }
00097
00099 CIndexVariant(T n)
00100 {
00101
00102
00103
00104
00105 *this = n;
00106 }
00107
00108
00110 CIndexVariant(NLMISC::IStream &is)
00111 {
00112 load(is);
00113 }
00114
00116 const CIndexVariant &operator ++(int)
00117 {
00118 try
00119 {
00120 inc(0);
00121 }
00122 catch(NLAIE::IException &e)
00123 {
00124 throw e;
00125 }
00126 return *this;
00127 }
00128
00130
00131 bool operator == (const CIndexVariant<T,indexMax,maxT> &a) const
00132 {
00133 for(sint32 i = 0; i < getMaxIndex(); i ++)
00134 {
00135 if(_Id[i] != a._Id[i]) return false;
00136 }
00137
00138 return true;
00139 }
00140
00141 bool operator < (const CIndexVariant<T,indexMax,maxT> &a) const
00142 {
00143 for(sint32 i = a.getMaxIndex()-1; i >= 0; i --)
00144 {
00145 if(_Id[i] < a._Id[i]) return true;
00146 }
00147 return false;
00148 }
00149
00150 bool operator > (const CIndexVariant<T,indexMax,maxT> &a) const
00151 {
00152 for(sint32 i = a.getMaxIndex()-1; i >= 0; i --)
00153 {
00154 if(_Id[i] > a._Id[i]) return true;
00155 }
00156
00157 return false;
00158 }
00160
00162
00163 const CIndexVariant<T,indexMax,maxT> &operator |= (const CIndexVariant<T,indexMax,maxT> &a)
00164 {
00165 for(sint32 i = 0; i < getMaxIndex(); i ++)
00166 {
00167 _Id[i] |= a._Id[i];
00168 }
00169 return *this;
00170 }
00171 const CIndexVariant<T,indexMax,maxT> &operator &= (const CIndexVariant<T,indexMax,maxT> &a)
00172 {
00173 for(sint32 i = 0; i < getMaxIndex(); i ++)
00174 {
00175 _Id[i] &= a._Id[i];
00176 }
00177 return *this;
00178 }
00179
00180 const CIndexVariant<T,indexMax,maxT> &operator ^= (const CIndexVariant<T,indexMax,maxT> &a)
00181 {
00182 for(sint32 i = 0; i < getMaxIndex(); i ++)
00183 {
00184 _Id[i] ^= a._Id[i];
00185 }
00186 return *this;
00187 }
00189
00191
00192 const CIndexVariant<T,indexMax,maxT> &operator = (const CIndexVariant<T,indexMax,maxT> &a)
00193 {
00194 for(sint32 i = 0; i < getMaxIndex(); i ++)
00195 {
00196 _Id[i] = a._Id[i];
00197 }
00198 return *this;
00199 }
00200
00201 const CIndexVariant<T,indexMax,maxT> &operator = (T a)
00202 {
00203 memset(_Id,0,getMaxIndex()*sizeof(T));
00204 _Id[0] = a;
00205 return *this;
00206 }
00207
00208 const CIndexVariant<T,indexMax,maxT> &operator >>= (sint a)
00209 {
00210 T bits = 1;
00211 T r;
00212 T bitlen = 8*sizeof(T) - a;
00213 sint i;
00214
00215 bits <<= a;
00216 bits -= 1;
00217 _Id[0] >>= a;
00218 for(i = 1; i < getMaxIndex(); i ++)
00219 {
00220 r = _Id[i] & bits;
00221 _Id[i] >>= a;
00222 r <<= bitlen;
00223 _Id[i - 1] |= r;
00224 }
00225
00226 return *this;
00227 }
00228
00229 const CIndexVariant<T,indexMax,maxT> &operator <<= (sint a)
00230 {
00231 T bits = (1 << a) - 1;
00232 T r;
00233 T bitlen = 8*sizeof(T) - a;
00234 sint i;
00235
00236 bits <<= (bitlen);
00237
00238 _Id[getMaxIndex() - 1] <<= a;
00239 for(i = getMaxIndex() - 2 ; i >= 0; i --)
00240 {
00241 r = _Id[i] & bits;
00242 r >>= bitlen;
00243 _Id[i] <<= a;
00244 _Id[i+1] |= r;
00245 }
00246
00247 return *this;
00248 }
00249
00251
00252
00254 void save(NLMISC::IStream &os)
00255 {
00256 sint32 i;
00257 i = getMaxIndex();
00258 os.serial(i);
00259 for(i = 0; i < getMaxIndex(); i ++)
00260 {
00261 T n = _Id[i];
00262 os.serial(n);
00263 }
00264 }
00265
00267 void load(NLMISC::IStream &is)
00268 {
00269 sint32 max,i;
00270
00271 is.serial(max);
00272
00273
00274
00275
00276
00277 for(i = 0; i < getMaxIndex(); i ++)
00278 {
00279 T num;
00280 is.serial(num);
00281 _Id[i] = num;
00282 }
00283
00284 }
00285
00286
00288 void getDebugString(std::string &str) const
00289 {
00290 char b[sizeof(T)*8 + 1];
00291 b[sizeof(T)*8] = 0;
00292 sint i;
00293 for(i = getMaxIndex() - 1 ; i >= 0; i --)
00294 {
00295 memset(b,'0',sizeof(T)*8);
00296 T s = _Id[i];
00297 sint base = 0;
00298 sint count = 0;
00299 for(base = 0; base < sizeof(T)*8; base ++)
00300 {
00301 if(s & 1)
00302 {
00303 b[sizeof(T)*8 - base - 1] = '1';
00304 }
00305 s >>= 1;
00306 }
00307 str += std::string(b);
00308 }
00309 }
00310
00311
00312 sint32 getMaxIndex() const
00313 {
00314 return indexMax;
00315 }
00316 };
00317
00318
00319
00327 class CNumericIndex : public NLMISC::IStreamable
00328 {
00329
00331
00332
00333
00334
00335
00336
00337
00338 public:
00339 static CAgentNumber _I;
00340 private:
00341 CAgentNumber _Id;
00342 public:
00344 CNumericIndex():_Id (_I++)
00345 {
00346 }
00347
00348 CNumericIndex(const CNumericIndex &id): _Id(id._Id)
00349 {
00350 }
00351
00353 CNumericIndex(const CAgentNumber &i):_Id (i)
00354 {
00355 }
00356
00358 CNumericIndex(const char *id):_Id(id)
00359 {
00360 }
00361
00362
00364 CNumericIndex(NLMISC::IStream &is): _Id(is)
00365 {
00366 }
00367
00368 void setTypeAt(uint64 t)
00369 {
00370 _Id.setTypeAt(t);
00371 }
00372
00374
00375 bool operator == (const CNumericIndex &a) const
00376 {
00377 return _Id == a._Id;
00378 }
00379
00380 bool operator < (const CNumericIndex &a) const
00381 {
00382 return _Id < a._Id;
00383 }
00384
00385 bool operator > (const CNumericIndex &a) const
00386 {
00387 return _Id > a._Id;
00388 }
00390
00392 void save(NLMISC::IStream &os)
00393 {
00394 _Id.save(os);
00395 }
00396
00398 void load(NLMISC::IStream &is)
00399 {
00400 _Id.load(is);
00401 }
00402
00403 void getDebugString(std::string &str) const
00404 {
00405 _Id.getDebugString(str);
00406 }
00407
00409
00410 virtual std::string getClassName()
00411 {
00412 return std::string("<CNumericIndex>");
00413 }
00414
00415 virtual void serial(NLMISC::IStream &f) throw(NLMISC::EStream)
00416 {
00417 if(f.isReading())
00418 {
00419 load(f);
00420 }
00421 else
00422 {
00423 save(f);
00424 }
00425
00426 }
00428
00429
00430 const CAgentNumber &getId() const
00431 {
00432 return _Id;
00433 }
00434 };
00435
00447 class IWordNumRef: public NLAIC::IBasicInterface
00448 {
00449 public:
00450 IWordNumRef()
00451 {
00452 }
00453
00454 IWordNumRef(IWordNumRef &)
00455 {
00456 }
00457
00458 virtual operator const IRefrence *() const = 0;
00459 virtual const CNumericIndex &getNumIdent() const = 0;
00460
00461 virtual ~IWordNumRef()
00462 {
00463 }
00464
00465 };
00466
00476 class CLocWordNumRef: public IWordNumRef
00477 {
00478 private:
00480 typedef std::map<CNumericIndex ,IRefrence *> tMapRef;
00481 static NLMISC::CSynchronized<tMapRef> _LocRefence;
00482
00483 private:
00484
00486 CNumericIndex _Id;
00487
00489 IRefrence *_Stock;
00490
00491 public:
00493 static const NLAIC::CIdentType *IdLocWordNumRef;
00494
00495 public:
00497 CLocWordNumRef(IRefrence *ref):_Stock(ref)
00498 {
00499 NLMISC::CSynchronized<tMapRef >::CAccessor a(&_LocRefence);
00500 a.value().insert(tMapRef::value_type(_Id,ref));
00501 }
00502
00510 CLocWordNumRef(const CNumericIndex &ref) :_Id(ref),_Stock(NULL)
00511 {
00512 NLMISC::CSynchronized<tMapRef >::CAccessor a(&_LocRefence);
00513 tMapRef::iterator Itr = a.value().find(_Id);
00514 if(Itr != a.value().end())
00515 {
00516 _Stock = (*Itr).second;
00517 }
00518 else throw NLAIE::CExceptionIndexHandeledError();
00519 }
00520
00521 CLocWordNumRef(const CNumericIndex &id,IRefrence *ref) :_Id(id),_Stock(ref)
00522 {
00523 NLMISC::CSynchronized<tMapRef >::CAccessor a(&_LocRefence);
00524 tMapRef::iterator itr = a.value().find(_Id);
00525 if(itr != a.value().end())
00526 {
00527 if((*itr).second != _Stock)
00528 {
00529 return;
00530 }
00531 else
00532 {
00533 throw NLAIE::CExceptionIndexHandeledError();
00534 }
00535 a.value().erase(itr);
00536 }
00537 a.value().insert(tMapRef::value_type(_Id,_Stock));
00538 }
00539
00544 CLocWordNumRef(const CLocWordNumRef &l) :_Id(l._Id),_Stock(NULL)
00545 {
00546 NLMISC::CSynchronized<tMapRef >::CAccessor a(&_LocRefence);
00547 tMapRef::iterator itr = a.value().find(_Id);
00548 if(itr != a.value().end())
00549 {
00550 _Stock = (*itr).second;
00551 }
00552 else throw NLAIE::CExceptionIndexHandeledError();
00553 }
00554
00560 CLocWordNumRef(NLMISC::IStream &is) :_Stock(NULL)
00561 {
00562 load(is);
00563 }
00564
00565 CLocWordNumRef():_Stock(NULL)
00566 {
00567 }
00568
00569 void getDebugString(std::string &t) const
00570 {
00571 std::string i;
00572 _Id.getDebugString(i);
00573 t += NLAIC::stringGetBuild("CLocWordNumRef<%d>: _Id <%s>",this,i.c_str());
00574 }
00575
00577
00578 virtual const NLAIC::CIdentType &getType() const;
00579 virtual const NLAIC::IBasicType *clone() const
00580 {
00581 NLAIC::IBasicInterface *m = new CLocWordNumRef(*this);
00582 return m;
00583 }
00584 virtual const NLAIC::IBasicType *newInstance() const
00585 {
00586 NLAIC::IBasicInterface *m = new CLocWordNumRef();
00587 return m;
00588 }
00589 virtual void save(NLMISC::IStream &os)
00590 {
00591 _Id.save(os);
00592 }
00594 virtual void load(NLMISC::IStream &is)
00595 {
00596 NLMISC::CSynchronized<tMapRef >::CAccessor a(&_LocRefence);
00597 _Id.load(is);
00598 tMapRef::iterator Itr = a.value().find(_Id);
00599 if(Itr != a.value().end())
00600 {
00601 _Stock = (*Itr).second;
00602 }
00603 else throw NLAIE::CExceptionIndexHandeledError();
00604 }
00606
00607 virtual operator const IRefrence *() const
00608 {
00609 return (const IRefrence *)_Stock;
00610 }
00611
00612 virtual const CNumericIndex &getNumIdent() const
00613 {
00614 return _Id;
00615 }
00616
00617 void setTypeAt(uint64 t)
00618 {
00619 _Id.setTypeAt(t);
00620 }
00621
00622 virtual ~CLocWordNumRef();
00623
00624 public:
00625
00627
00628
00630 static void clear();
00631
00633 static void Init();
00639 static void saveMapping(ostream &);
00643 static bool loadMapping(NLMISC::IStream &);
00644
00645 static IRefrence *getRef(const CNumericIndex &);
00647 };
00648
00650 void initAgentLib();
00651
00653 void releaseAgentLib();
00654 }
00655
00656
00657 #endif
00658