Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 10, 2011, 11:34:20 PM (14 years ago)
Author:
landauf
Message:

added "safe mode" feature to FunctorMember: if enabled, the functor acts like a WeakPtr and sets the object-pointer to NULL if the object is deleted, hence the functor can not be executed anymore and instead prints an error message. safe mode is _disabled_ by default.

enabled safe mode for timers

To implement safe mode, FunctorMember<void> (= FunctorStatic) was spezialized and implemented differently. Additionally functors now work only with polymorphic objects due to a dynamic cast, hence XMLPortVariableHelperClass and Magazine got a virtual destructor.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/libraries/core/command/Functor.h

    r7401 r7851  
    120120#include "util/Debug.h"
    121121#include "util/MultiType.h"
     122#include "core/OrxonoxClass.h"
    122123#include "FunctorPtr.h"
    123124
     
    186187
    187188        public:
     189            virtual ~Functor() {}
     190
    188191            /// Calls the function-pointer with up to five arguments. In case of a member-function, the assigned object-pointer is used to call the function. @return Returns the return-value of the function (if any; MT_Type::Null otherwise)
    189192            virtual MultiType operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
     
    211214            /// Returns the object-pointer.
    212215            virtual void* getRawObjectPointer() const = 0;
     216
     217            /// Enables or disables the safe mode which causes the functor to change the object pointer to NULL if the object is deleted (only member functors).
     218            virtual void setSafeMode(bool bSafeMode) = 0;
    213219
    214220            /// Returns the full identifier of the function-pointer which is defined as typeid(@a F), where @a F is the type of the stored function-pointer. Used to compare functors.
     
    220226    };
    221227
    222     namespace detail
    223     {
    224         // helper class to determine if a functor is static or not
    225         template <class O>
    226         struct FunctorTypeStatic
    227         { enum { result = false }; };
    228         template <>
    229         struct FunctorTypeStatic<void>
    230         { enum { result = true }; };
    231     }
    232 
    233228    /**
    234229        @brief FunctorMember is a child class of Functor and expands it with an object-pointer, that
     
    243238    */
    244239    template <class O>
    245     class FunctorMember : public Functor
     240    class FunctorMember : public Functor, public DestructionListener
    246241    {
    247242        public:
    248243            /// Constructor: Stores the object-pointer.
    249             FunctorMember(O* object = 0) : object_(object) {}
     244            FunctorMember(O* object = 0) : object_(object), bSafeMode_(false) {}
     245            virtual ~FunctorMember() { if (this->bSafeMode_) { this->unregisterObject(this->object_); } }
    250246
    251247            /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be NULL. @return Returns the return-value of the function (if any; MT_Type::Null otherwise)
     
    255251            MultiType operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null)
    256252            {
    257                 // call the function if it is static or if an object was assigned
    258                 if (detail::FunctorTypeStatic<O>::result || this->object_)
     253                // call the function if an object was assigned
     254                if (this->object_)
    259255                    return (*this)(this->object_, param1, param2, param3, param4, param5);
    260256                else
     
    266262
    267263            // see Functor::getType()
    268             Functor::Type::Enum getType() const
    269                 { return detail::FunctorTypeStatic<O>::result ? Functor::Type::Static : Functor::Type::Member; }
     264            inline Functor::Type::Enum getType() const
     265                { return Functor::Type::Member; }
    270266
    271267            /// Assigns an object-pointer to the functor which is used to execute a member-function.
    272268            inline void setObject(O* object)
    273                 { this->object_ = object;}
     269            {
     270                if (this->bSafeMode_ && object != this->object_)
     271                {
     272                    this->unregisterObject(this->object_);
     273                    this->registerObject(object);
     274                }
     275                this->object_ = object;
     276            }
    274277            /// Returns the object-pointer.
    275278            inline O* getObject() const
     
    278281            // see Functor::setRawObjectPointer()
    279282            inline void setRawObjectPointer(void* object)
    280                 { this->object_ = (O*)object; }
     283                { this->setObject((O*)object); }
    281284            // see Functor::getRawObjectPointer()
    282285            inline void* getRawObjectPointer() const
    283286                { return this->object_; }
    284287
     288            // see Functor::setSafeMode()
     289            inline void setSafeMode(bool bSafeMode)
     290            {
     291                if (bSafeMode == this->bSafeMode_)
     292                    return;
     293
     294                this->bSafeMode_ = bSafeMode;
     295
     296                if (bSafeMode)
     297                    this->registerObject(this->object_);
     298                else
     299                    this->unregisterObject(this->object_);
     300            }
     301
    285302        protected:
     303            /// Casts the object and registers as destruction listener.
     304            inline void registerObject(O* object)
     305                { OrxonoxClass* base = orxonox_cast<OrxonoxClass*>(object); if (base) { this->registerAsDestructionListener(base); } }
     306            /// Casts the object and unregisters as destruction listener.
     307            inline void unregisterObject(O* object)
     308                { OrxonoxClass* base = orxonox_cast<OrxonoxClass*>(object); if (base) { this->unregisterAsDestructionListener(base); } }
     309
     310            /// Will be called by OrxonoxClass::~OrxonoxClass() if the stored object is deleted and the Functor is in safe mode.
     311            inline void objectDeleted()
     312                { this->object_ = 0; }
     313
    286314            O* object_;     ///< The stored object-pointer, used to execute a member-function (or NULL for static functions)
     315            bool bSafeMode_; ///< If true, the functor is in safe mode and registers itself as listener at the object and changes the pointer to NULL if the object is deleted
     316    };
     317
     318    /// Specialization of FunctorMember with @a T = void.
     319    template <>
     320    class FunctorMember<void> : public Functor
     321    {
     322        public:
     323            /// Constructor: Stores the object-pointer.
     324            FunctorMember(void* object = 0) {}
     325
     326            /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be NULL. @return Returns the return-value of the function (if any; MT_Type::Null otherwise)
     327            virtual MultiType operator()(void* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
     328
     329            // see Functor::operator()()
     330            MultiType operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null)
     331            {
     332                return (*this)((void*)0, param1, param2, param3, param4, param5);
     333            }
     334
     335            // see Functor::getType()
     336            inline Functor::Type::Enum getType() const
     337                { return Functor::Type::Static; }
     338
     339            // see Functor::setRawObjectPointer()
     340            inline void setRawObjectPointer(void*)
     341                { COUT(2) << "Warning: Can't assign an object pointer to a static functor" << std::endl; }
     342            // see Functor::getRawObjectPointer()
     343            inline void* getRawObjectPointer() const
     344                { return 0; }
     345
     346            // see Functor::setSafeMode()
     347            inline void setSafeMode(bool) {}
    287348    };
    288349
Note: See TracChangeset for help on using the changeset viewer.