Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 1, 2007, 4:24:56 AM (16 years ago)
Author:
landauf
Message:

added comments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/objecthierarchy/src/orxonox/core/Identifier.h

    r362 r365  
     1/*!
     2    @file Identifier.h
     3    @brief Definition of the Identifier, ClassIdentifier and SubclassIdentifier classes.
     4
     5    The Identifier contains all needed informations about the class it belongs to:
     6     - the name
     7     - a list with all objects
     8     - parents and childs
     9     - the factory, if available
     10     - the networkID that can be synchronised with the server
     11
     12    Every object has a pointer to the Identifier of its class. This allows the use isA(...),
     13    isDirectlyA(...), isChildOf(...) and isParentOf(...).
     14
     15    To create the class-hierarchy, the Identifier has some intern functions and variables.
     16
     17    Every Identifier is in fact a ClassIdentifier, but they are derived from Identifier.
     18
     19    SubclassIdentifier is a separated class, acting like an Identifier, but has a given class.
     20    You can only assign Identifiers of the given class or a derivative to a SubclassIdentifier.
     21*/
     22
    123#ifndef _Identifier_H__
    224#define _Identifier_H__
     
    1335namespace orxonox
    1436{
    15     class BaseObject;
     37    class BaseObject; // Forward declaration
    1638
    1739    // ###############################
    1840    // ###       Identifier        ###
    1941    // ###############################
     42    //! The Identifier is used to identify the class of an object and to store informations about the class.
     43    /**
     44        The Identifier contains all needed informations about the class it belongs to:
     45         - the name
     46         - a list with all objects
     47         - parents and childs
     48         - the factory, if available
     49         - the networkID that can be synchronised with the server
     50
     51        Every object has a pointer to the Identifier of its class. This allows the use isA(...),
     52        isDirectlyA(...), isChildOf(...) and isParentOf(...).
     53
     54        You can't directly create an Identifier, it's just the base-class for ClassIdentifier.
     55    */
    2056    class Identifier
    2157    {
    2258        template <class T>
    23         friend class ClassIdentifier;
     59        friend class ClassIdentifier; // Forward declaration
    2460
    2561        template <class T>
    26         friend class SubclassIdentifier;
     62        friend class SubclassIdentifier; // Forward declaration
    2763
    2864        template <class T>
    29         friend class ClassFactory;
     65        friend class ClassFactory; // Forward declaration
    3066
    3167        public:
     68            /** @brief Sets the Factory. @param facotry The factory to assign */
    3269            inline void addFactory(BaseFactory* factory) { this->factory_ = factory; }
     70
    3371            BaseObject* fabricate();
    3472
     
    3876            bool isParentOf(const Identifier* identifier) const;
    3977
     78            /** @returns the name of the class the Identifier belongs to. */
    4079            inline const std::string& getName() const { return this->name_; }
     80
     81            /** @returns the parents of the class the Identifier belongs to. */
    4182            inline const IdentifierList& getParents() const { return this->parents_; }
     83
     84            /** @returns the children of the class the Identifier belongs to. */
    4285            inline IdentifierList& getChildren() const { return *this->children_; }
    4386
     87            /** @returns true, if a branch of the class-hierarchy is getting created, causing all new objects to store their parents. */
    4488            inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
    4589
     90            /** @returns the NetworkID to identify a class through the network. */
    4691            inline const unsigned int getNetworkID() const { return this->classID_; }
     92
    4793            void setNetworkID(unsigned int id);
    4894
    4995        private:
    5096            Identifier();
    51             Identifier(const Identifier& identifier) {}
     97            Identifier(const Identifier& identifier) {} // don't copy
    5298            virtual ~Identifier();
    5399            void initialize(const IdentifierList* parents);
    54100
     101            /**
     102                @brief Increases the hierarchyCreatingCounter_s variable, causing all new objects to store their parents.
     103            */
    55104            inline static void startCreatingHierarchy()
    56105            {
     
    61110            }
    62111
     112            /**
     113                @brief Decreases the hierarchyCreatingCounter_s variable, causing the objects to stop storing their parents.
     114            */
    63115            inline static void stopCreatingHierarchy()
    64116            {
     
    69121            }
    70122
    71             IdentifierList parents_;
    72             IdentifierList* children_;
    73 
    74             std::string name_;
    75 
    76             BaseFactory* factory_;
    77             bool bCreatedOneObject_;
    78             static int hierarchyCreatingCounter_s;
    79             static unsigned int classIDcounter_s;
    80             unsigned int classID_;
     123            IdentifierList parents_;                    //!< The Parents of the class the Identifier belongs to
     124            IdentifierList* children_;                  //!< The Children of the class the Identifier belongs to
     125
     126            std::string name_;                          //!< The name of the class the Identifier belongs to
     127
     128            BaseFactory* factory_;                      //!< The Factory, able to create new objects of the given class
     129            bool bCreatedOneObject_;                    //!< True if at least one object of the given type was created (used to determine the need of storing the parents)
     130            static int hierarchyCreatingCounter_s;      //!< Bigger than zero if at least one Identifier stores its parents (its an int instead of a bool to avoid conflicts with multithreading)
     131            static unsigned int classIDcounter_s;       //!< The number of unique Identifiers
     132            unsigned int classID_;                      //!< The networkID to identify a class through the network
    81133    };
    82134
     
    85137    // ###     ClassIdentifier     ###
    86138    // ###############################
     139    //! The ClassIdentifier is derived from Identifier and holds all class-specific functions and variables the Identifier cannot have.
     140    /**
     141        ClassIdentifier is a Singleton, which means that only one object of a given type T exists.
     142        This makes it possible to store informations about a class, sharing them with all
     143        objects of that class without defining static variables in every class.
     144    */
    87145    template <class T>
    88146    class ClassIdentifier : public Identifier
     
    95153        private:
    96154            ClassIdentifier();
    97             ClassIdentifier(const ClassIdentifier<T>& identifier) {}
     155            ClassIdentifier(const ClassIdentifier<T>& identifier) {} // don't copy
    98156            ~ClassIdentifier();
    99157
    100             static ClassIdentifier<T>* pointer_s;
    101             ObjectList<T>* objects_;
     158            static ClassIdentifier<T>* pointer_s;       //!< A pointer to the singleton-object
     159            ObjectList<T>* objects_;                    //!< The ObjectList, containing all objects of type T
    102160    };
    103161
    104162    template <class T>
    105     ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
    106 
     163    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL; // Set the static member variable pointer_s to zero
     164
     165    /**
     166        @brief Constructor: Create the ObjectList.
     167    */
    107168    template <class T>
    108169    ClassIdentifier<T>::ClassIdentifier()
     
    111172    }
    112173
     174    /**
     175        @brief Destructor: Delete the ObjectList, set the singleton-pointer to zero.
     176    */
    113177    template <class T>
    114178    ClassIdentifier<T>::~ClassIdentifier()
     
    118182    }
    119183
     184    /**
     185        @brief Registers a class, which means that the name and the parents get stored.
     186        @param parents An IdentifierList, containing the Identifiers of all parents of the class
     187        @param name A string, containing exactly the name of the class
     188        @param bRootClass True if the class is either an Interface or BaseObject itself
     189        @return The ClassIdentifier itself
     190    */
    120191    template <class T>
    121192    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass)
     
    124195        std::cout << "*** Register Class in " << name << "-Singleton.\n";
    125196#endif
     197
     198        // It's a singleton, so maybe we have to create it first
    126199        if (!pointer_s)
    127200        {
     
    132205        }
    133206
     207        // Check if at least one object of the given type was created
    134208        if (!pointer_s->bCreatedOneObject_)
    135209        {
     210            // If no: We have to store the informations and initialize the Identifier
     211
    136212#if HIERARCHY_VERBOSE
    137213            std::cout << "*** Register Class in " << name << "-Singleton -> Initialize Singleton.\n";
    138214#endif
    139215            pointer_s->name_ = name;
    140             Factory::add(name, pointer_s);
     216            Factory::add(name, pointer_s); // Add the Identifier to the Factory
    141217
    142218            if (bRootClass)
    143                 pointer_s->initialize(NULL);
     219                pointer_s->initialize(NULL); // If a class is derived from two interfaces, the second interface might think it's derived from the first because of the order of constructor-calls. Thats why we set parents to zero in that case.
    144220            else
    145221                pointer_s->initialize(parents);
     
    149225    }
    150226
     227    /**
     228        @returns the Identifier itself
     229    */
    151230    template <class T>
    152231    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
     
    163242    }
    164243
     244    /**
     245        @brief Adds an object of the given type to the ObjectList.
     246        @param object The object to add
     247    */
    165248    template <class T>
    166249    void ClassIdentifier<T>::addObject(T* object)
     
    169252        std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n";
    170253#endif
    171         object->getMetaList()->add(ClassIdentifier<T>::getIdentifier()->objects_, ClassIdentifier<T>::getIdentifier()->objects_->add(object));
     254        object->getMetaList().add(ClassIdentifier<T>::getIdentifier()->objects_, ClassIdentifier<T>::getIdentifier()->objects_->add(object));
    172255    }
    173256
     
    176259    // ###   SubclassIdentifier    ###
    177260    // ###############################
    178     template <class B>
     261    //! The SubclassIdentifier acts almost like an Identifier, but has some prerequisites.
     262    /**
     263        You can only assign Identifiers that belong to a class of at least B (or derived) to a SubclassIdentifier<T>.
     264        If you assign something else, the program aborts.
     265        Because we know the minimal type, a dynamic_cast is done, which makes it easier to create a new object.
     266    */
     267    template <class T>
    179268    class SubclassIdentifier
    180269    {
    181270        public:
    182             SubclassIdentifier();
    183 
    184             SubclassIdentifier<B>& operator=(Identifier* identifier)
    185             {
    186                 if (!identifier->isA(ClassIdentifier<B>::getIdentifier()))
     271            /**
     272                @brief Constructor: Automaticaly assigns the Identifier of the given class.
     273            */
     274            SubclassIdentifier()
     275            {
     276                this->identifier_ = ClassIdentifier<T>::getIdentifier();
     277            }
     278
     279            /**
     280                @brief Overloading of the = operator: assigns the identifier and checks its type.
     281                @param identifier The Identifier to assign
     282                @return The SubclassIdentifier itself
     283            */
     284            SubclassIdentifier<T>& operator=(Identifier* identifier)
     285            {
     286                if (!identifier->isA(ClassIdentifier<T>::getIdentifier()))
    187287                {
    188                     std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
    189                     std::cout << "Error: SubclassIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
     288                    std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!\n";
     289                    std::cout << "Error: SubclassIdentifier<" << ClassIdentifier<T>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
    190290                    std::cout << "Aborting...\n";
    191291                    abort();
     
    195295            }
    196296
     297            /**
     298                @brief Overloading of the * operator: returns the assigned identifier.
     299                @return The assigned identifier
     300            */
    197301            Identifier* operator*()
    198302            {
     
    200304            }
    201305
     306            /**
     307                @brief Overloading of the -> operator: returns the assigned identifier.
     308                @return The assigned identifier
     309            */
    202310            Identifier* operator->() const
    203311            {
     
    205313            }
    206314
    207             B* fabricate()
     315            /**
     316                @brief Creates a new object of the type of the assigned identifier and dynamic_casts it to the minimal type given by the SubclassIdentifier.
     317                @return The new object
     318            */
     319            T* fabricate()
    208320            {
    209321                BaseObject* newObject = this->identifier_->fabricate();
     322
     323                // Check if the creation worked
    210324                if (newObject)
    211325                {
    212                     return dynamic_cast<B*>(newObject);
     326                    // Do a dynamic_cast, because an object of type T is much better than of type BaseObject
     327                    return dynamic_cast<T*>(newObject);
    213328                }
    214329                else
    215330                {
     331                    // Something went terribly wrong
    216332                    if (this->identifier_)
    217333                    {
    218                         std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
     334                        std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!\n";
    219335                        std::cout << "Error: Couldn't fabricate a new Object.\n";
    220336                        std::cout << "Aborting...\n";
     
    230346            }
    231347
     348            /** @returns the assigned identifier. */
    232349            inline const Identifier* getIdentifier() const
    233350                { return this->identifier_; }
     351
     352            /** @returns true, if the assigned identifier is at least of the given type. @param identifier The identifier to compare with */
    234353            inline bool isA(const Identifier* identifier) const
    235354                { return this->identifier_->isA(identifier); }
     355
     356            /** @returns true, if the assigned identifier is exactly of the given type. @param identifier The identifier to compare with */
    236357            inline bool isDirectlyA(const Identifier* identifier) const
    237358                { return this->identifier_->isDirectlyA(identifier); }
     359
     360            /** @returns true, if the assigned identifier is a child of the given identifier. @param identifier The identifier to compare with */
    238361            inline bool isChildOf(const Identifier* identifier) const
    239362                { return this->identifier_->isChildOf(identifier); }
     363
     364            /** @returns true, if the assigned identifier is a parent of the given identifier. @param identifier The identifier to compare with */
    240365            inline bool isParentOf(const Identifier* identifier) const
    241366                { return this->identifier_->isParentOf(identifier); }
    242367
    243368        private:
    244             Identifier* identifier_;
     369            Identifier* identifier_;        //!< The assigned identifier
    245370    };
    246 
    247     template <class B>
    248     SubclassIdentifier<B>::SubclassIdentifier()
    249     {
    250         this->identifier_ = ClassIdentifier<B>::getIdentifier();
    251     }
    252371}
    253372
Note: See TracChangeset for help on using the changeset viewer.