Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 4, 2015, 9:12:21 PM (9 years ago)
Author:
landauf
Message:

merged branch core7 back to trunk

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/class/Identifier.h

    r9667 r10624  
    8080#include <typeinfo>
    8181#include <loki/TypeTraits.h>
     82#include <boost/static_assert.hpp>
     83#include <boost/type_traits/is_base_of.hpp>
    8284
    8385#include "util/Output.h"
     86#include "util/OrxAssert.h"
    8487#include "core/object/ObjectList.h"
    8588#include "core/object/Listable.h"
     
    109112    {
    110113        public:
    111             Identifier();
     114            struct InheritsFrom //! helper class to manually define inheritance
     115            {
     116                virtual ~InheritsFrom() {}
     117                virtual Identifier* getParent() const = 0;
     118            };
     119
     120        public:
     121            Identifier(const std::string& name, Factory* factory, bool bLoadable);
    112122            Identifier(const Identifier& identifier); // don't copy
    113123            virtual ~Identifier();
     
    115125            /// Returns the name of the class the Identifier belongs to.
    116126            inline const std::string& getName() const { return this->name_; }
    117             void setName(const std::string& name);
    118 
    119             /// Returns the name of the class as it is returned by typeid(T).name()
    120             virtual const std::string& getTypeidName() = 0;
     127
     128            /// Returns the type_info of the class as it is returned by typeid(T)
     129            virtual const std::type_info& getTypeInfo() = 0;
    121130
    122131            /// Returns the network ID to identify a class through the network.
     
    127136            ORX_FORCEINLINE unsigned int getClassID() const { return this->classID_; }
    128137
    129             /// Sets the Factory.
    130             void setFactory(Factory* factory);
    131138            /// Returns true if the Identifier has a Factory.
    132139            inline bool hasFactory() const { return (this->factory_ != 0); }
     
    136143            /// Returns true if the class can be loaded through XML.
    137144            inline bool isLoadable() const { return this->bLoadable_; }
    138             /// Set the class to be loadable through XML or not.
    139             inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; }
     145
     146            /// Returns true if child classes should inherit virtually from this class.
     147            inline bool isVirtualBase() const { return this->bIsVirtualBase_; }
     148            /// Defines if child classes should inherit virtually from this class.
     149            inline void setVirtualBase(bool bIsVirtualBase) { this->bIsVirtualBase_ = bIsVirtualBase; }
    140150
    141151            /// Returns true if the Identifier was completely initialized.
    142152            inline bool isInitialized() const { return this->bInitialized_; }
     153
     154            virtual void destroyObjects() = 0;
     155
     156            virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0;
     157
     158            static bool initConfigValues_s; // TODO: this is a hack - remove it as soon as possible
    143159
    144160
     
    146162            ////// Class Hierarchy //////
    147163            /////////////////////////////
    148             Identifier& inheritsFrom(Identifier* directParent);
    149 
    150             void initializeParents(const std::set<const Identifier*>& identifiers);
    151             void initializeDirectParentsOfAbstractClass();
     164            Identifier& inheritsFrom(InheritsFrom* directParent);
     165
     166            void initializeParents(const std::list<const Identifier*>& initializationTrace);
    152167            void finishInitialization();
     168            void reset();
    153169
    154170            bool isA(const Identifier* identifier) const;
     
    159175            bool isDirectParentOf(const Identifier* identifier) const;
    160176
     177            /// Returns the direct parents of the class the Identifier belongs to.
     178            inline const std::list<const Identifier*>& getDirectParents() const { return this->directParents_; }
    161179            /// Returns the parents of the class the Identifier belongs to.
    162             inline const std::set<const Identifier*>& getParents() const { return this->parents_; }
    163             /// Returns the begin-iterator of the parents-list.
    164             inline std::set<const Identifier*>::const_iterator getParentsBegin() const { return this->parents_.begin(); }
    165             /// Returns the end-iterator of the parents-list.
    166             inline std::set<const Identifier*>::const_iterator getParentsEnd() const { return this->parents_.end(); }
    167 
     180            inline const std::list<const Identifier*>& getParents() const { return this->parents_; }
     181
     182            /// Returns the direct children the class the Identifier belongs to.
     183            inline const std::set<const Identifier*>& getDirectChildren() const { return this->directChildren_; }
    168184            /// Returns the children of the class the Identifier belongs to.
    169185            inline const std::set<const Identifier*>& getChildren() const { return this->children_; }
    170             /// Returns the begin-iterator of the children-list.
    171             inline std::set<const Identifier*>::const_iterator getChildrenBegin() const { return this->children_.begin(); }
    172             /// Returns the end-iterator of the children-list.
    173             inline std::set<const Identifier*>::const_iterator getChildrenEnd() const { return this->children_.end(); }
    174 
    175             /// Returns the direct parents of the class the Identifier belongs to.
    176             inline const std::set<const Identifier*>& getDirectParents() const { return this->directParents_; }
    177             /// Returns the begin-iterator of the direct-parents-list.
    178             inline std::set<const Identifier*>::const_iterator getDirectParentsBegin() const { return this->directParents_.begin(); }
    179             /// Returns the end-iterator of the direct-parents-list.
    180             inline std::set<const Identifier*>::const_iterator getDirectParentsEnd() const { return this->directParents_.end(); }
    181 
    182             /// Returns the direct children the class the Identifier belongs to.
    183             inline const std::set<const Identifier*>& getDirectChildren() const { return this->directChildren_; }
    184             /// Returns the begin-iterator of the direct-children-list.
    185             inline std::set<const Identifier*>::const_iterator getDirectChildrenBegin() const { return this->directChildren_.begin(); }
    186             /// Returns the end-iterator of the direct-children-list.
    187             inline std::set<const Identifier*>::const_iterator getDirectChildrenEnd() const { return this->directChildren_.end(); }
    188186
    189187
     
    223221            XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
    224222
    225 
    226223        protected:
    227224            virtual void createSuperFunctionCaller() const = 0;
    228225
    229226        private:
    230             std::set<const Identifier*> parents_;                          //!< The parents of the class the Identifier belongs to
     227            void verifyIdentifierTrace() const;
     228            void addIfNotExists(std::list<const Identifier*>& list, const Identifier* identifierToAdd) const;
     229
     230            std::list<const InheritsFrom*> manualDirectParents_;            //!< Manually defined direct parents
     231            std::list<const Identifier*> directParents_;                    //!< The direct parents of the class the Identifier belongs to (sorted by their order of initialization)
     232            std::list<const Identifier*> parents_;                          //!< The parents of the class the Identifier belongs to (sorted by their order of initialization)
     233
     234            std::set<const Identifier*> directChildren_;                   //!< The direct children of the class the Identifier belongs to
    231235            std::set<const Identifier*> children_;                         //!< The children of the class the Identifier belongs to
    232 
    233             std::set<const Identifier*> directParents_;                    //!< The direct parents of the class the Identifier belongs to
    234             std::set<const Identifier*> directChildren_;                   //!< The direct children of the class the Identifier belongs to
    235236
    236237            bool bInitialized_;                                            //!< Is true if the Identifier was completely initialized
    237238            bool bLoadable_;                                               //!< False = it's not permitted to load the object through XML
     239            bool bIsVirtualBase_;                                          //!< If true, it is recommended to inherit virtually from this class. This changes the order of initialization of child classes, thus this information is necessary to check the class hierarchy.
    238240            std::string name_;                                             //!< The name of the class the Identifier belongs to
    239241            Factory* factory_;                                             //!< The Factory, able to create new objects of the given class (if available)
    240242            uint32_t networkID_;                                           //!< The network ID to identify a class through the network
    241             const unsigned int classID_;                                   //!< Uniquely identifies a class (might not be the same as the networkID_)
     243            unsigned int classID_;                                         //!< Uniquely identifies a class (might not be the same as the networkID_)
    242244
    243245            bool bHasConfigValues_;                                        //!< True if this class has at least one assigned config value
     
    267269    class ClassIdentifier : public Identifier
    268270    {
     271        BOOST_STATIC_ASSERT((boost::is_base_of<Identifiable, T>::value));
     272
    269273        #ifndef DOXYGEN_SHOULD_SKIP_THIS
    270274          #define SUPER_INTRUSIVE_DECLARATION_INCLUDE
     
    273277
    274278        public:
    275             static ClassIdentifier<T>* getIdentifier();
    276             static ClassIdentifier<T>* getIdentifier(const std::string& name);
    277 
    278             bool initializeObject(T* object);
    279 
    280             void setConfigValues(T* object, Configurable*) const;
    281             void setConfigValues(T* object, Identifiable*) const;
    282 
    283             void addObjectToList(T* object, Listable*);
    284             void addObjectToList(T* object, Identifiable*);
    285 
    286             virtual void updateConfigValues(bool updateChildren = true) const;
    287 
    288             virtual const std::string& getTypeidName()
    289                 { return this->typeidName_; }
    290 
    291         private:
    292             static void initializeIdentifier();
    293 
    294             ClassIdentifier(const ClassIdentifier<T>& identifier) {}    // don't copy
    295             ClassIdentifier()
     279            ClassIdentifier(const std::string& name, Factory* factory, bool bLoadable) : Identifier(name, factory, bLoadable)
    296280            {
    297                 this->typeidName_ = typeid(T).name();
     281                OrxVerify(ClassIdentifier<T>::classIdentifier_s == NULL, "Assertion failed in ClassIdentifier of type " << typeid(T).name());
     282                ClassIdentifier<T>::classIdentifier_s = this;
     283
    298284                SuperFunctionInitialization<0, T>::initialize(this);
    299285            }
     
    303289            }
    304290
     291            bool initializeObject(T* object);
     292
     293            virtual void updateConfigValues(bool updateChildren = true) const;
     294
     295            virtual const std::type_info& getTypeInfo()
     296                { return typeid(T); }
     297
     298            virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const
     299                { return dynamic_cast<T*>(object) != 0; }
     300
     301            virtual void destroyObjects();
     302
     303            static ClassIdentifier<T>* getIdentifier();
     304
     305        private:
     306            ClassIdentifier(const ClassIdentifier<T>& identifier) {}    // don't copy
     307
     308            void setConfigValues(T* object, Configurable*) const;
     309            void setConfigValues(T* object, Identifiable*) const;
     310
     311            void addObjectToList(T* object, Listable*);
     312            void addObjectToList(T* object, Identifiable*);
     313
     314            void destroyObjects(Listable*);
     315            void destroyObjects(void*);
     316
     317            void destroyObject(Destroyable* object);
     318            void destroyObject(void* object);
     319
    305320            void updateConfigValues(bool updateChildren, Listable*) const;
    306321            void updateConfigValues(bool updateChildren, Identifiable*) const;
    307322
    308             std::string typeidName_;
    309323            static WeakPtr<ClassIdentifier<T> > classIdentifier_s;
    310324    };
     
    318332    */
    319333    template <class T>
    320     inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
    321     {
    322         // check if the Identifier already exists
    323         if (!ClassIdentifier<T>::classIdentifier_s)
    324             ClassIdentifier<T>::initializeIdentifier();
    325 
     334    /*static*/ inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
     335    {
     336        if (ClassIdentifier<T>::classIdentifier_s == NULL)
     337            ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*) IdentifierManager::getInstance().getIdentifierByTypeInfo(typeid(T));
     338
     339        OrxVerify(ClassIdentifier<T>::classIdentifier_s != NULL, "Did you forget to register the class of type " << typeid(T).name() << "?");
    326340        return ClassIdentifier<T>::classIdentifier_s;
    327     }
    328 
    329     /**
    330         @brief Does the same as getIdentifier() but sets the name if this wasn't done yet.
    331         @param name The name of this Identifier
    332         @return The Identifier
    333     */
    334     template <class T>
    335     inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier(const std::string& name)
    336     {
    337         ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
    338         identifier->setName(name);
    339         return identifier;
    340     }
    341 
    342     /**
    343         @brief Assigns the static field for the identifier singleton.
    344     */
    345     template <class T>
    346     /*static */ void ClassIdentifier<T>::initializeIdentifier()
    347     {
    348         // create a new identifier anyway. Will be deleted if not used.
    349         ClassIdentifier<T>* proposal = new ClassIdentifier<T>();
    350 
    351         // Get the entry from the map
    352         ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)IdentifierManager::getInstance().getGloballyUniqueIdentifier(proposal);
    353 
    354         if (ClassIdentifier<T>::classIdentifier_s == proposal)
    355             orxout(verbose, context::identifier) << "Requested Identifier for " << proposal->getTypeidName() << " was not yet existing and got created." << endl;
    356         else
    357         {
    358             orxout(verbose, context::identifier) << "Requested Identifier for " << proposal->getTypeidName() << " was already existing and got assigned." << endl;
    359             delete proposal; // delete proposal (it is not used anymore)
    360         }
    361341    }
    362342
     
    375355            IdentifierManager::getInstance().createdObject(object);
    376356
    377             this->setConfigValues(object, object);
     357            if (Identifier::initConfigValues_s)
     358                this->setConfigValues(object, object);
     359
    378360            return true;
    379361        }
     
    420402
    421403    /**
     404     * @brief Destroy all objects of this class (must be Listable).
     405     * Destroyables are destroyed with destroy(), all other classes with delete.
     406     */
     407    template <class T>
     408    void ClassIdentifier<T>::destroyObjects()
     409    {
     410        this->destroyObjects((T*)0);
     411    }
     412
     413    /**
     414     * @brief Only searches and destroys objects if is a @ref Listable
     415     */
     416    template <class T>
     417    void ClassIdentifier<T>::destroyObjects(Listable*)
     418    {
     419        ObjectListBase* objectList = Context::getRootContext()->getObjectList(this);
     420        ObjectListElement<T>* begin = static_cast<ObjectListElement<T>*>(objectList->begin());
     421        ObjectListElement<T>* end = static_cast<ObjectListElement<T>*>(objectList->end());
     422        for (typename ObjectList<T>::iterator it = begin; it != end; )
     423            this->destroyObject(*(it++));
     424    }
     425
     426    template <class T>
     427    void ClassIdentifier<T>::destroyObjects(void*)
     428    {
     429        // no action
     430    }
     431
     432    /**
     433     * @brief Call 'object->destroy()' for Destroyables and 'delete object' for all other types.
     434     */
     435    template <class T>
     436    void ClassIdentifier<T>::destroyObject(Destroyable* object)
     437    {
     438        object->destroy();
     439    }
     440
     441    template <class T>
     442    void ClassIdentifier<T>::destroyObject(void* object)
     443    {
     444        delete static_cast<Identifiable*>(object);
     445    }
     446
     447    /**
    422448        @brief Updates the config-values of all existing objects of this class by calling their setConfigValues() function.
    423449    */
     
    438464
    439465        if (updateChildren)
    440             for (std::set<const Identifier*>::const_iterator it = this->getChildrenBegin(); it != this->getChildrenEnd(); ++it)
     466            for (std::set<const Identifier*>::const_iterator it = this->getChildren().begin(); it != this->getChildren().end(); ++it)
    441467                (*it)->updateConfigValues(false);
    442468    }
Note: See TracChangeset for help on using the changeset viewer.