00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef NL_MOT_H
00027 #define NL_MOT_H
00028
00029
00030 #include "nel/misc/types_nl.h"
00031 #include "nel/misc/smart_ptr.h"
00032 #include "nel/misc/bit_set.h"
00033 #include "nel/misc/class_id.h"
00034 #include <vector>
00035 #include <set>
00036 #include <map>
00037
00038
00039
00040 namespace NLMISC
00041 {
00042 class IStream;
00043 }
00044
00045
00046 namespace NL3D
00047 {
00048
00049
00050 class IModel;
00051 class IObs;
00052 class ITrav;
00053
00054
00055
00070 class CMOT
00071 {
00072 public:
00073
00074 CMOT();
00075
00076 virtual ~CMOT();
00077
00079
00080
00087 static void registerModel(const NLMISC::CClassId &idModel, const NLMISC::CClassId &idModelBase, IModel* (*creator)());
00095 static void registerObs(const NLMISC::CClassId &idTrav, const NLMISC::CClassId &idModel, IObs* (*creator)());
00097
00098
00099 public:
00101
00102
00109 void addTrav(ITrav *v);
00111 uint getNumTrav() const { return Traversals.size(); }
00113 ITrav *getTrav(uint index) const
00114 {
00115 nlassert(index < Traversals.size());
00116 return Traversals[index].Trav;
00117 }
00123 ITrav *getTrav(const NLMISC::CClassId &idTrav) const;
00125
00126
00127 public:
00129
00130
00147 IModel *createModel(const NLMISC::CClassId &idModel);
00148
00155 void deleteModel(IModel *model);
00156
00160 void validateModels();
00161
00163
00164
00168 virtual void release();
00169
00170
00171
00172 private:
00173 struct CModelEntry
00174 {
00175 NLMISC::CClassId ModelId, BaseModelId;
00176 IModel* (*Creator)();
00177 bool operator<(const CModelEntry& o) const {return ModelId<o.ModelId;}
00178 bool operator==(const CModelEntry& o) const {return ModelId==o.ModelId;}
00179 bool operator!=(const CModelEntry& o) const {return !(*this==o);}
00180 };
00181
00182 struct CObsEntry
00183 {
00184 NLMISC::CClassId TravId, ModelId;
00185 IObs* (*Creator)();
00186 bool operator<(const CObsEntry& o) const
00187 {
00188 if(TravId!=o.TravId)
00189 return TravId<o.TravId;
00190 else
00191 return ModelId<o.ModelId;
00192 }
00193 bool operator==(const CObsEntry& o) const
00194 {
00195 return ModelId==o.ModelId && TravId==o.TravId;
00196 }
00197 bool operator!=(const CObsEntry& o) const {return !(*this==o);}
00198 };
00199
00200 struct CTravEntry
00201 {
00202 NLMISC::CClassId TravId;
00203 ITrav *Trav;
00204 };
00205
00206 private:
00207
00208 friend class IModel;
00209
00210 std::vector<CTravEntry> Traversals;
00211 std::set<IModel*> Models;
00212 IModel *_ValidateModelList;
00213
00214 static std::set<CModelEntry> RegModels;
00215 static std::set<CObsEntry> RegObservers;
00216
00217 private:
00218
00219 IObs *createObs(const ITrav *trav, const NLMISC::CClassId &idModel) const;
00220
00221 protected:
00222
00223 IObs *getModelObs(IModel *m, const NLMISC::CClassId &idTrav) const;
00224
00225
00226 private:
00227
00228 virtual void dummyForDynamicCast() {}
00229
00230 };
00231
00232
00233
00258 class IModel : public NLMISC::CRefCount
00259 {
00260 protected:
00269 IModel();
00270
00281 virtual void initModel()
00282 {
00283 }
00284
00291 virtual ~IModel();
00292
00293 public:
00294
00296
00297
00301 enum TDirty
00302 {
00303 Dirty=0,
00304 Last
00305 };
00307 NLMISC::CBitSet TouchObs;
00309 void foul(uint flag) { TouchObs.set(Dirty); TouchObs.set(flag); }
00310
00312 void validate();
00313
00315
00316
00317 protected:
00318
00319 friend class CMOT;
00320 friend class IObs;
00321 friend class ITrav;
00322 typedef std::map<NLMISC::CClassId, IObs*> CObsMap;
00323 CObsMap Observers;
00324
00325
00326 mutable NLMISC::CClassId LastClassId;
00327 mutable IObs *LastObs;
00329 IObs *getObs(const NLMISC::CClassId &idTrav) const;
00330
00331
00332
00333 CMOT *_OwnerMot;
00334
00335
00336 IModel *_PrecModelToValidate;
00337 IModel *_NextModelToValidate;
00338
00339
00340 protected:
00341
00342
00344
00345
00357 virtual void update()
00358 {
00359 }
00360
00373 virtual void cleanTouch()
00374 {
00375 TouchObs.clearAll();
00376 }
00377
00378
00379 void linkToValidateList();
00380 void unlinkFromValidateList();
00381
00383
00384
00385 };
00386
00387
00388
00411 class IObs : public NLMISC::CRefCount
00412 {
00413 public:
00414 IModel *Model;
00415 ITrav *Trav;
00416
00417 public:
00418 IObs();
00420 virtual ~IObs();
00424 virtual void init() {}
00425
00426
00448
00449 virtual bool isTreeNode() {return true;}
00451 virtual void addChild(IObs *son);
00453 virtual void delChild(IObs *son);
00458 virtual void addParent(IObs *father);
00460 virtual void delParent(IObs *father);
00461
00463 sint getNumChildren() const {return NumSons;}
00465 IObs *getFirstChild() const
00466 {
00467 if(NumSons==0)
00468 return 0;
00469 CurSonIt= SonList.begin();
00470 nlassert(CurSonIt!=SonList.end());
00471 return (*CurSonIt);
00472 }
00474 IObs *getNextChild() const
00475 {
00476 nlassert(CurSonIt!=SonList.end());
00477 CurSonIt++;
00478 if(CurSonIt==SonList.end())
00479 return NULL;
00480 else
00481 return (*CurSonIt);
00482 }
00483
00485 sint getNumParents() const {return NumFathers;}
00487 IObs *getFirstParent() const
00488 {
00489 if(NumFathers==0)
00490 return 0;
00491 CurFatherIt= FatherList.begin();
00492 nlassert(CurFatherIt!=FatherList.end());
00493 return (*CurFatherIt);
00494 }
00496 IObs *getNextParent() const
00497 {
00498 nlassert(CurFatherIt!=FatherList.end());
00499 CurFatherIt++;
00500 if(CurFatherIt==FatherList.end())
00501 return NULL;
00502 else
00503 return (*CurFatherIt);
00504 }
00505
00507
00508
00510
00511
00518 virtual void traverse(IObs *caller)=0;
00520
00521
00523
00524
00531 virtual void update()
00532 {
00533 }
00535
00536
00538
00539
00540 void traverseSons()
00541 {
00542 for(IObs *c= getFirstChild(); c!=NULL; c= getNextChild())
00543 {
00544 c->traverse(this);
00545 }
00546 }
00548 IObs *getObs(const NLMISC::CClassId &idTrav) const;
00550
00551
00552 protected:
00553 typedef std::list<IObs*> TObsList;
00554 typedef TObsList::iterator ItObsList;
00555 typedef TObsList::const_iterator ConstItObsList;
00556 typedef std::map<IObs *, ItObsList> TObsMap;
00557 typedef TObsMap::iterator ItObsMap;
00558
00559
00560 TObsList SonList;
00561 TObsList FatherList;
00562 TObsMap SonMap;
00563 TObsMap FatherMap;
00564 sint NumFathers;
00565 sint NumSons;
00566
00567 mutable ConstItObsList CurSonIt;
00568 mutable ConstItObsList CurFatherIt;
00569
00570 };
00571
00572
00573
00574
00596 class ITrav : public NLMISC::CRefCount
00597 {
00598 public:
00599
00601
00602
00603 ITrav() {Root=NULL;}
00605 virtual ~ITrav() {Root= NULL;}
00607
00609
00610
00614 virtual IObs *createDefaultObs() const =0;
00616 virtual NLMISC::CClassId getClassId() const =0;
00618 virtual void addedToMOT(CMOT *mot) {}
00620
00621
00623
00624
00632 void setRoot(IModel *root);
00634 IModel *getRoot() const;
00641 void link(IModel *m1, IModel *m2) const;
00647 void unlink(IModel *m1, IModel *m2) const;
00649 void moveChildren(IModel *parentFrom, IModel *parentTo) const;
00651 void copyChildren(IModel *parentFrom, IModel *parentTo) const;
00652
00653
00655 sint getNumChildren(IModel *m) const;
00657 IModel *getFirstChild(IModel *m) const;
00659 IModel *getNextChild(IModel *m) const;
00660
00662 sint getNumParents(IModel *m) const;
00664 IModel *getFirstParent(IModel *m) const;
00666 IModel *getNextParent(IModel *m) const;
00667
00669
00670
00671 protected:
00672
00673 NLMISC::CRefPtr<IObs> Root;
00674
00675 };
00676
00677
00678
00679
00680 }
00681
00682
00683 #endif // NL_MOT_H
00684
00685
00686