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 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064
00065
00066
00067
00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091 00092 00093 00094 00095 00096 00097 00098 00099 00100 00101 00102 00103 00104 00105 00106 00107 00108 00109 00110 00111 00112 00113 00114 00115 00116 00117 00118 00119 00120 00121 00122 00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135
00136
00137
00138
00139 class IModel;
00140 class IObs;
00141 class ITrav;
00142
00143
00144 00159 class CMOT
00160 {
00161 public:
00162
00163 CMOT();
00164
00165 ~CMOT();
00166
00168
00169
00176 static void registerModel(const NLMISC::CClassId &idModel, const NLMISC::CClassId &idModelBase, IModel* (*creator)());
00184 static void registerObs(const NLMISC::CClassId &idTrav, const NLMISC::CClassId &idModel, IObs* (*creator)());
00186
00187
00188 public:
00190
00191
00198 void addTrav(ITrav *v);
00204 ITrav *getTrav(const NLMISC::CClassId &idTrav) const;
00206
00207
00208 public:
00210
00211
00228 IModel *createModel(const NLMISC::CClassId &idModel);
00229
00236 void deleteModel(IModel *model);
00237
00241 void validateModels();
00242
00244
00245
00249 void release();
00250
00251
00252
00253 private:
00254 struct CModelEntry
00255 {
00256 NLMISC::CClassId ModelId, BaseModelId;
00257 IModel* (*Creator)();
00258 bool operator<(const CModelEntry& o) const {return ModelId<o.ModelId;}
00259 bool operator==(const CModelEntry& o) const {return ModelId==o.ModelId;}
00260 bool operator!=(const CModelEntry& o) const {return !(*this==o);}
00261 };
00262
00263 struct CObsEntry
00264 {
00265 NLMISC::CClassId TravId, ModelId;
00266 IObs* (*Creator)();
00267 bool operator<(const CObsEntry& o) const
00268 {
00269 if(TravId!=o.TravId)
00270 return TravId<o.TravId;
00271 else
00272 return ModelId<o.ModelId;
00273 }
00274 bool operator==(const CObsEntry& o) const
00275 {
00276 return ModelId==o.ModelId && TravId==o.TravId;
00277 }
00278 bool operator!=(const CObsEntry& o) const {return !(*this==o);}
00279 };
00280
00281 struct CTravEntry
00282 {
00283 NLMISC::CClassId TravId;
00284 ITrav *Trav;
00285 };
00286
00287 private:
00288 std::vector<CTravEntry> Traversals;
00289 std::set<IModel*> Models;
00290 static std::set<CModelEntry> RegModels;
00291 static std::set<CObsEntry> RegObservers;
00292
00293 private:
00294
00295 IObs *createObs(const ITrav *trav, const NLMISC::CClassId &idModel) const;
00296
00297 protected:
00298
00299 IObs *getModelObs(IModel *m, const NLMISC::CClassId &idTrav) const;
00300 };
00301
00302
00303 00328 class IModel : public NLMISC::CRefCount
00329 {
00330 protected:
00339 IModel();
00340
00347 virtual ~IModel();
00348
00349 public:
00350
00352
00353
00357 enum TDirty
00358 {
00359 Dirty=0,
00360 Last
00361 };
00363 NLMISC::CBitSet TouchObs;
00365 void foul(uint flag) { TouchObs.set(Dirty); TouchObs.set(flag); }
00366
00368 void validate();
00369
00371
00372
00373 protected:
00374
00375 friend class CMOT;
00376 friend class IObs;
00377 friend class ITrav;
00378 typedef std::map<NLMISC::CClassId, IObs*> CObsMap;
00379 CObsMap Observers;
00380
00381
00382 mutable NLMISC::CClassId LastClassId;
00383 mutable IObs *LastObs;
00385 IObs *getObs(const NLMISC::CClassId &idTrav) const;
00386
00387
00388 protected:
00389
00390
00392
00393
00405 virtual void update()
00406 {
00407 }
00408
00421 virtual void cleanTouch()
00422 {
00423 TouchObs.clearAll();
00424 }
00426
00427 };
00428
00429
00430 00453 class IObs : public NLMISC::CRefCount
00454 {
00455 public:
00456 IModel *Model;
00457 ITrav *Trav;
00458
00459 public:
00460 IObs();
00462 virtual ~IObs();
00466 virtual void init() {}
00467
00468
00489
00490 virtual bool isTreeNode() {return true;}
00492 virtual void addChild(IObs *son);
00494 virtual void delChild(IObs *son);
00499 virtual void addParent(IObs *father);
00501 virtual void delParent(IObs *father);
00502
00504 virtual sint getNumChildren() const;
00506 virtual IObs *getFirstChild() const;
00508 virtual IObs *getNextChild() const;
00509
00511 virtual sint getNumParents() const;
00513 virtual IObs *getFirstParent() const;
00515 virtual IObs *getNextParent() const;
00517
00518
00520
00521
00528 virtual void traverse(IObs *caller)=0;
00530
00531
00533
00534
00541 virtual void update()
00542 {
00543 }
00545
00546
00548
00549
00550 void traverseSons()
00551 {
00552 for(IObs *c= getFirstChild(); c!=NULL; c= getNextChild())
00553 {
00554 c->traverse(this);
00555 }
00556 }
00558 IObs *getObs(const NLMISC::CClassId &idTrav) const;
00560
00561
00562 protected:
00563 std::set<IObs*> Sons;
00564 std::set<IObs*> Fathers;
00565
00566 mutable std::set<IObs*>::const_iterator SonIt;
00567 mutable std::set<IObs*>::const_iterator FatherIt;
00568
00569 };
00570
00571
00572
00573 00595 class ITrav : public NLMISC::CRefCount
00596 {
00597 public:
00598
00600
00601
00602 ITrav() {Root=NULL;}
00604 virtual ~ITrav() {Root= NULL;}
00606
00608
00609
00613 virtual IObs *createDefaultObs() const =0;
00615 virtual NLMISC::CClassId getClassId() const =0;
00617
00618
00620
00621
00629 void setRoot(IModel *root);
00631 IModel *getRoot() const;
00638 void link(IModel *m1, IModel *m2) const;
00644 void unlink(IModel *m1, IModel *m2) const;
00646 void moveChildren(IModel *parentFrom, IModel *parentTo) const;
00648 void copyChildren(IModel *parentFrom, IModel *parentTo) const;
00649
00650
00652 sint getNumChildren(IModel *m) const;
00654 IModel *getFirstChild(IModel *m) const;
00656 IModel *getNextChild(IModel *m) const;
00657
00659 sint getNumParents(IModel *m) const;
00661 IModel *getFirstParent(IModel *m) const;
00663 IModel *getNextParent(IModel *m) const;
00664
00666
00667
00668 protected:
00669
00670 NLMISC::CRefPtr<IObs> Root;
00671
00672 };
00673
00674
00675
00676
00677 }
00678
00679
00680 #endif // NL_MOT_H
00681
00682
00683