Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 4, 2007, 11:48:28 PM (16 years ago)
Author:
landauf
Message:

copied changed files from objecthierarchy-branch

File:
1 edited

Legend:

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

    r367 r384  
     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__
     
    830#include "Factory.h"
    931
    10 #ifdef WIN32
    11 #define HIERARCHY_VERBOSE 0
    12 #else
    1332#define HIERARCHY_VERBOSE false
    14 #endif
    1533
    1634
    1735namespace orxonox
    1836{
    19     class BaseObject;
     37    class BaseObject; // Forward declaration
    2038
    2139    // ###############################
    2240    // ###       Identifier        ###
    2341    // ###############################
     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    */
    2456    class Identifier
    2557    {
    2658        template <class T>
    27         friend class ClassIdentifier;
     59        friend class ClassIdentifier; // Forward declaration
    2860
    2961        template <class T>
    30         friend class SubclassIdentifier;
     62        friend class SubclassIdentifier; // Forward declaration
    3163
    3264        template <class T>
    33         friend class ClassFactory;
     65        friend class ClassFactory; // Forward declaration
    3466
    3567        public:
     68            /** @brief Sets the Factory. @param facotry The factory to assign */
    3669            inline void addFactory(BaseFactory* factory) { this->factory_ = factory; }
     70
    3771            BaseObject* fabricate();
    3872
     
    4276            bool isParentOf(const Identifier* identifier) const;
    4377
     78            /** @returns the name of the class the Identifier belongs to. */
    4479            inline const std::string& getName() const { return this->name_; }
     80
     81            /** @returns the parents of the class the Identifier belongs to. */
    4582            inline const IdentifierList& getParents() const { return this->parents_; }
     83
     84            /** @returns the children of the class the Identifier belongs to. */
    4685            inline IdentifierList& getChildren() const { return *this->children_; }
    4786
     87            /** @returns true, if a branch of the class-hierarchy is getting created, causing all new objects to store their parents. */
    4888            inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
    4989
     90            /** @returns the NetworkID to identify a class through the network. */
    5091            inline const unsigned int getNetworkID() const { return this->classID_; }
     92
    5193            void setNetworkID(unsigned int id);
    5294
    5395        private:
    5496            Identifier();
    55             Identifier(const Identifier& identifier) {}
     97            Identifier(const Identifier& identifier) {} // don't copy
    5698            virtual ~Identifier();
    5799            void initialize(const IdentifierList* parents);
    58100
     101            /**
     102                @brief Increases the hierarchyCreatingCounter_s variable, causing all new objects to store their parents.
     103            */
    59104            inline static void startCreatingHierarchy()
    60105            {
     
    65110            }
    66111
     112            /**
     113                @brief Decreases the hierarchyCreatingCounter_s variable, causing the objects to stop storing their parents.
     114            */
    67115            inline static void stopCreatingHierarchy()
    68116            {
     
    73121            }
    74122
    75             IdentifierList parents_;
    76             IdentifierList* children_;
    77 
    78             std::string name_;
    79 
    80             BaseFactory* factory_;
    81             bool bCreatedOneObject_;
    82             static int hierarchyCreatingCounter_s;
    83             static unsigned int classIDcounter_s;
    84             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
    85133    };
    86134
     
    89137    // ###     ClassIdentifier     ###
    90138    // ###############################
     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    */
    91145    template <class T>
    92146    class ClassIdentifier : public Identifier
     
    99153        private:
    100154            ClassIdentifier();
    101             ClassIdentifier(const ClassIdentifier<T>& identifier) {}
     155            ClassIdentifier(const ClassIdentifier<T>& identifier) {} // don't copy
    102156            ~ClassIdentifier();
    103157
    104             static ClassIdentifier<T>* pointer_s;
    105             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
    106160    };
    107161
    108162    template <class T>
    109     ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
    110 
     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    */
    111168    template <class T>
    112169    ClassIdentifier<T>::ClassIdentifier()
     
    115172    }
    116173
     174    /**
     175        @brief Destructor: Delete the ObjectList, set the singleton-pointer to zero.
     176    */
    117177    template <class T>
    118178    ClassIdentifier<T>::~ClassIdentifier()
     
    122182    }
    123183
     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    */
    124191    template <class T>
    125192    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass)
     
    128195        std::cout << "*** Register Class in " << name << "-Singleton.\n";
    129196#endif
     197
     198        // It's a singleton, so maybe we have to create it first
    130199        if (!pointer_s)
    131200        {
     
    136205        }
    137206
     207        // Check if at least one object of the given type was created
    138208        if (!pointer_s->bCreatedOneObject_)
    139209        {
     210            // If no: We have to store the informations and initialize the Identifier
     211
    140212#if HIERARCHY_VERBOSE
    141213            std::cout << "*** Register Class in " << name << "-Singleton -> Initialize Singleton.\n";
    142214#endif
    143215            pointer_s->name_ = name;
    144             Factory::add(name, pointer_s);
     216            Factory::add(name, pointer_s); // Add the Identifier to the Factory
    145217
    146218            if (bRootClass)
    147                 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.
    148220            else
    149221                pointer_s->initialize(parents);
     
    153225    }
    154226
     227    /**
     228        @returns the Identifier itself
     229    */
    155230    template <class T>
    156231    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
     
    167242    }
    168243
     244    /**
     245        @brief Adds an object of the given type to the ObjectList.
     246        @param object The object to add
     247    */
    169248    template <class T>
    170249    void ClassIdentifier<T>::addObject(T* object)
     
    173252        std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n";
    174253#endif
    175         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));
    176255    }
    177256
     
    180259    // ###   SubclassIdentifier    ###
    181260    // ###############################
    182     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>
    183268    class SubclassIdentifier
    184269    {
    185270        public:
    186             SubclassIdentifier();
    187 
    188             SubclassIdentifier<B>& operator=(Identifier* identifier)
    189             {
    190                 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()))
    191287                {
    192                     std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
    193                     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";
    194290                    std::cout << "Aborting...\n";
    195291                    abort();
     
    199295            }
    200296
     297            /**
     298                @brief Overloading of the * operator: returns the assigned identifier.
     299                @return The assigned identifier
     300            */
    201301            Identifier* operator*()
    202302            {
     
    204304            }
    205305
     306            /**
     307                @brief Overloading of the -> operator: returns the assigned identifier.
     308                @return The assigned identifier
     309            */
    206310            Identifier* operator->() const
    207311            {
     
    209313            }
    210314
    211             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()
    212320            {
    213321                BaseObject* newObject = this->identifier_->fabricate();
     322
     323                // Check if the creation worked
    214324                if (newObject)
    215325                {
    216                     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);
    217328                }
    218329                else
    219330                {
     331                    // Something went terribly wrong
    220332                    if (this->identifier_)
    221333                    {
    222                         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";
    223335                        std::cout << "Error: Couldn't fabricate a new Object.\n";
    224336                        std::cout << "Aborting...\n";
     
    234346            }
    235347
     348            /** @returns the assigned identifier. */
    236349            inline const Identifier* getIdentifier() const
    237350                { 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 */
    238353            inline bool isA(const Identifier* identifier) const
    239354                { 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 */
    240357            inline bool isDirectlyA(const Identifier* identifier) const
    241358                { 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 */
    242361            inline bool isChildOf(const Identifier* identifier) const
    243362                { 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 */
    244365            inline bool isParentOf(const Identifier* identifier) const
    245366                { return this->identifier_->isParentOf(identifier); }
    246367
    247368        private:
    248             Identifier* identifier_;
     369            Identifier* identifier_;        //!< The assigned identifier
    249370    };
    250 
    251     template <class B>
    252     SubclassIdentifier<B>::SubclassIdentifier()
    253     {
    254         this->identifier_ = ClassIdentifier<B>::getIdentifier();
    255     }
    256371}
    257372
Note: See TracChangeset for help on using the changeset viewer.