Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 23, 2009, 7:28:48 PM (15 years ago)
Author:
rgrieder
Message:

Add a new core-feature: orxonox_cast<T>()
The functions casts objects like dynamic_cast, but uses the identifier instead for MSVC (much faster) and is just a redirection to dynamic_cast for GCC.
Also replaced almost all dynamic_casts (of course only those related to the class hierarchy).

Location:
code/branches/core4/src/core
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core4/src/core/EventIncludes.h

    r3196 r3223  
    5454        this->addEventContainer(eventname, containername); \
    5555    } \
    56     event.castedOriginator_ = dynamic_cast<subclassname*>(event.originator_); \
     56    event.castedOriginator_ = orxonox::orxonox_cast<subclassname>(event.originator_); \
    5757    containername->process(this, event)
    5858
     
    6666        this->addEventContainer(eventname, containername); \
    6767    } \
    68     event.castedOriginator_ = dynamic_cast<subclassname*>(event.originator_); \
     68    event.castedOriginator_ = orxonox::orxonox_cast<subclassname>(event.originator_); \
    6969    containername->process(this, event)
    7070
  • code/branches/core4/src/core/Identifier.cc

    r3196 r3223  
    4747    // ###       Identifier        ###
    4848    // ###############################
    49     int Identifier::hierarchyCreatingCounter_s = 0; // Set the static member variable hierarchyCreatingCounter_s to zero (this static member variable is ok: it's used in main(), not before)
     49    int Identifier::hierarchyCreatingCounter_s = 0;
     50    unsigned int Identifier::classIDCounter_s = 0;
    5051
    5152    /**
     
    5354    */
    5455    Identifier::Identifier()
     56        : classID_(classIDCounter_s++)
    5557    {
    5658        this->objects_ = new ObjectListBase(this);
     
    6769        this->directChildren_ = new std::set<const Identifier*>();
    6870
    69         // Use a static variable because the classID gets created before main() and that's why we should avoid static member variables
    70         static unsigned int classIDcounter_s = 0;
    71         this->classID_ = classIDcounter_s++;
     71        // Default network ID is the class ID
     72        this->networkID_ = this->classID_;
    7273    }
    7374
     
    244245    void Identifier::setNetworkID(uint32_t id)
    245246    {
    246         Factory::changeNetworkID(this, this->classID_, id);
    247         this->classID_ = id;
     247        Factory::changeNetworkID(this, this->networkID_, id);
     248        this->networkID_ = id;
    248249    }
    249250
  • code/branches/core4/src/core/Identifier.h

    r3196 r3223  
    224224
    225225            /** @brief Returns the network ID to identify a class through the network. @return the network ID */
    226             inline const uint32_t getNetworkID() const { return this->classID_; }
     226            inline const uint32_t getNetworkID() const { return this->networkID_; }
    227227
    228228            /** @brief Sets the network ID to a new value. @param id The new value */
    229229            void setNetworkID(uint32_t id);
     230
     231            /** @brief Returns the unique ID of the class */
     232            FORCEINLINE unsigned int getClassID() const { return this->classID_; }
    230233
    231234            void addConfigValueContainer(const std::string& varname, ConfigValueContainer* container);
     
    305308            BaseFactory* factory_;                                         //!< The Factory, able to create new objects of the given class (if available)
    306309            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)
    307             uint32_t classID_;                                             //!< The network ID to identify a class through the network
     310            uint32_t networkID_;                                           //!< The network ID to identify a class through the network
     311            const unsigned int classID_;                                   //!< Uniquely identifies a class (might not be the same as the networkID_)
     312            static unsigned int classIDCounter_s;                          //!< Static counter for the unique classIDs
    308313
    309314            bool bHasConfigValues_;                                        //!< True if this class has at least one assigned config value
     
    427432        COUT(5) << "*** ClassIdentifier: Added object to " << this->getName() << "-list." << std::endl;
    428433        object->getMetaList().add(this->objects_, this->objects_->add(new ObjectListElement<T>(object)));
     434        // Add pointer of type T to the map in the OrxonoxClass instance that enables "dynamic_casts"
     435        object->objectPointers_.push_back(std::make_pair(this->getClassID(), reinterpret_cast<void*>(object)));
    429436    }
    430437
     
    444451            for (std::set<const Identifier*>::const_iterator it = this->getChildrenBegin(); it != this->getChildrenEnd(); ++it)
    445452                (*it)->updateConfigValues(false);
     453    }
     454
     455
     456    // ###############################
     457    // ###      orxonox_cast       ###
     458    // ###############################
     459    /**
     460    @brief
     461        Casts on object of type OrxonoxClass to any derived type that is
     462        registered in the class hierarchy.
     463    @return
     464        Returns NULL if the cast is not possible
     465    @note
     466        In case of NULL return (and using MSVC), a dynamic_cast might still be possible if
     467        a class forgot to register its objects.
     468        Also note that the function is implemented differently for GCC/MSVC.
     469    */
     470    template <class T, class U>
     471    FORCEINLINE T* orxonox_cast(U* source)
     472    {
     473#ifdef ORXONOX_COMPILER_MSVC
     474        return source->template getDerivedPointer<T>(ClassIdentifier<T>::getIdentifier()->getClassID());
     475#else
     476        return dynamic_cast<T*>(source);
     477#endif
    446478    }
    447479
     
    539571                if (newObject)
    540572                {
    541                     return dynamic_cast<T*>(newObject);
     573                    return orxonox_cast<T>(newObject);
    542574                }
    543575                else
  • code/branches/core4/src/core/Iterator.h

    r3196 r3223  
    240240            {
    241241                if (this->element_)
    242                     return dynamic_cast<T*>(this->element_->objectBase_);
     242                    return orxonox_cast<T>(this->element_->objectBase_);
    243243                else
    244244                    return 0;
     
    252252            {
    253253                if (this->element_)
    254                     return dynamic_cast<T*>(this->element_->objectBase_);
     254                    return orxonox_cast<T>(this->element_->objectBase_);
    255255                else
    256256                    return 0;
  • code/branches/core4/src/core/OrxonoxClass.h

    r3196 r3223  
    5050    class _CoreExport OrxonoxClass
    5151    {
     52        template <class T>
     53        friend class ClassIdentifier;
     54
    5255        public:
    5356            OrxonoxClass();
     
    101104            bool isDirectParentOf(const OrxonoxClass* object);
    102105
     106            /**
     107            @brief
     108                Returns a valid pointer of any derived type that is
     109                registered in the class hierarchy.
     110            @return
     111                Returns NULL if the no pointer was found.
     112            */
     113            template <class T>
     114            FORCEINLINE T* getDerivedPointer(unsigned int classID) const
     115            {
     116                for (int i = this->objectPointers_.size() - 1; i >= 0; --i)
     117                {
     118                    if (this->objectPointers_[i].first == classID)
     119                        return reinterpret_cast<T*>(this->objectPointers_[i].second);
     120                }
     121                return NULL;
     122            }
     123
    103124        private:
    104125            Identifier* identifier_;                   //!< The Identifier of the object
    105126            std::set<const Identifier*>* parents_;     //!< List of all parents of the object
    106127            MetaObjectList* metaList_;                 //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
     128            //! 'Fast map' that holds this-pointers of all derived types
     129            std::vector<std::pair<unsigned int, void*> > objectPointers_;
    107130    };
    108131}
  • code/branches/core4/src/core/XMLPort.h

    r3196 r3223  
    565565                                                    newObject->setLoaderIndentation(object->getLoaderIndentation() + "  ");
    566566
    567                                                     O* castedObject = dynamic_cast<O*>(newObject);
     567                                                    O* castedObject = orxonox_cast<O>(newObject);
    568568                                                    assert(castedObject);
    569569
Note: See TracChangeset for help on using the changeset viewer.