# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

mot.h

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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         // Ctor.
00074         CMOT();
00075         // Dtor.
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         // must do this for _ValidateModelList access.
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         // Create an observer, obeying the hierachy/observer system explained in createModel().
00219         IObs    *createObs(const ITrav *trav, const NLMISC::CClassId &idModel) const;
00220 
00221 protected:
00222         // For hertied class, to access observer result of a model.
00223         IObs    *getModelObs(IModel *m, const NLMISC::CClassId &idTrav) const;
00224 
00225 
00226 private:
00227         // a dummy method, usefull for dynamic_cast only.
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,                // First bit, to say that the Model is dirty.
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         // Observers created and linked by CMOT::createModel()
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         // Cache the last observer acceded through getObs().
00326         mutable NLMISC::CClassId        LastClassId;
00327         mutable IObs                            *LastObs;
00329         IObs    *getObs(const NLMISC::CClassId &idTrav) const;
00330 
00331 
00332         // A link to the CMOT which created us, filled in createModel().
00333         CMOT                    *_OwnerMot;
00334 
00335         // linked list of models to validate.
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         // for CMOT::createModel() and for CTransform::freezeHRC() only.
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;         // The model for this observer.
00415         ITrav   *Trav;          // The traversal for this observer.
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         // separate in list/set, to have o(1) lookup, and o(logn) insertion/erase.
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         // The root observer.
00673         NLMISC::CRefPtr<IObs>   Root;
00674 
00675 };
00676 
00677 
00678 
00679 
00680 }
00681 
00682 
00683 #endif // NL_MOT_H
00684 
00685 /* End of mot.h */
00686