[Orxonox-commit 1102] r5823 - code/branches/core5/src/libraries/core

landauf at orxonox.net landauf at orxonox.net
Mon Sep 28 17:16:36 CEST 2009


Author: landauf
Date: 2009-09-28 17:16:36 +0200 (Mon, 28 Sep 2009)
New Revision: 5823

Added:
   code/branches/core5/src/libraries/core/WeakPtr.h
Modified:
   code/branches/core5/src/libraries/core/OrxonoxClass.cc
   code/branches/core5/src/libraries/core/OrxonoxClass.h
   code/branches/core5/src/libraries/core/SmartPtr.h
Log:
added WeakPtr (a pointer which becomes 0 if the target object is deleted)

Modified: code/branches/core5/src/libraries/core/OrxonoxClass.cc
===================================================================
--- code/branches/core5/src/libraries/core/OrxonoxClass.cc	2009-09-28 15:05:28 UTC (rev 5822)
+++ code/branches/core5/src/libraries/core/OrxonoxClass.cc	2009-09-28 15:16:36 UTC (rev 5823)
@@ -35,6 +35,7 @@
 
 #include "MetaObjectList.h"
 #include "Identifier.h"
+#include "WeakPtr.h"
 
 namespace orxonox
 {
@@ -61,6 +62,10 @@
         // parents_ exists only if isCreatingHierarchy() of the associated Identifier returned true while creating the class
         if (this->parents_)
             delete this->parents_;
+            
+        // reset all weak pointers pointing to this object
+        for (std::set<WeakPtr<OrxonoxClass>*>::iterator it = this->weakPointers_.begin(); it != this->weakPointers_.end(); )
+            (*(it++))->reset();
     }
 
     /** @brief Deletes the object if no smart pointers point to this object. Otherwise schedules the object to be deleted as soon as possible. */

Modified: code/branches/core5/src/libraries/core/OrxonoxClass.h
===================================================================
--- code/branches/core5/src/libraries/core/OrxonoxClass.h	2009-09-28 15:05:28 UTC (rev 5822)
+++ code/branches/core5/src/libraries/core/OrxonoxClass.h	2009-09-28 15:16:36 UTC (rev 5823)
@@ -57,6 +57,9 @@
         template <class T>
         friend class SmartPtr;
 
+        template <class T>
+        friend class WeakPtr;
+
         public:
             OrxonoxClass();
             virtual ~OrxonoxClass();
@@ -130,12 +133,22 @@
             /** @brief Decrements the reference counter (for smart pointers). */
             inline void decrementReferenceCount()
                 { --this->referenceCount_; if (this->referenceCount_ == 0 && this->requestedDestruction_) { delete this; } }
+                
+            /** @brief Register a weak pointer which points to this object. */
+            template <class T>
+            inline void registerWeakPtr(WeakPtr<T>* pointer)
+                { this->weakPointers_.insert(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
+            /** @brief Unegister a weak pointer which pointed to this object before. */
+            template <class T>
+            inline void unregisterWeakPtr(WeakPtr<T>* pointer)
+                { this->weakPointers_.erase(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
 
             Identifier* identifier_;                   //!< The Identifier of the object
             std::set<const Identifier*>* parents_;     //!< List of all parents of the object
             MetaObjectList* metaList_;                 //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
             int referenceCount_;                       //!< Counts the references from smart pointers to this object
             bool requestedDestruction_;                //!< Becomes true after someone called delete on this object
+            std::set<WeakPtr<OrxonoxClass>*> weakPointers_; //!< All weak pointers which point to this object (and like to get notified if it dies)
 
             //! 'Fast map' that holds this-pointers of all derived types
             std::vector<std::pair<unsigned int, void*> > objectPointers_;

Modified: code/branches/core5/src/libraries/core/SmartPtr.h
===================================================================
--- code/branches/core5/src/libraries/core/SmartPtr.h	2009-09-28 15:05:28 UTC (rev 5822)
+++ code/branches/core5/src/libraries/core/SmartPtr.h	2009-09-28 15:16:36 UTC (rev 5823)
@@ -34,8 +34,9 @@
 #include "CorePrereqs.h"
 
 #include <cassert>
-#include <ostream>
+
 #include "OrxonoxClass.h"
+#include "WeakPtr.h"
 
 namespace orxonox
 {
@@ -70,6 +71,13 @@
                     this->base_->incrementReferenceCount();
             }
 
+            template <class O>
+            inline SmartPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.getBase())
+            {
+                if (this->base_)
+                    this->base_->incrementReferenceCount();
+            }
+
             inline ~SmartPtr()
             {
                 if (this->base_)
@@ -101,11 +109,23 @@
                 return *this;
             }
 
+            template <class O>
+            inline const SmartPtr& operator=(const WeakPtr<O>& other)
+            {
+                SmartPtr(other).swap(*this);
+                return *this;
+            }
+
             inline T* get() const
             {
                 return this->pointer_;
             }
 
+            inline OrxonoxClass* getBase() const
+            {
+                return this->base_;
+            }
+
             inline operator T*() const
             {
                 return this->pointer_;
@@ -152,25 +172,7 @@
             OrxonoxClass* base_;
     };
 
-    template <class A, class B>
-    inline bool operator==(const SmartPtr<A>& a, const SmartPtr<B>& b)
-    {
-        return (a.get() == b.get());
-    }
-
-    template <class A, class B>
-    inline bool operator!=(const SmartPtr<A>& a, const SmartPtr<B>& b)
-    {
-        return (a.get() != b.get());
-    }
-
     template <class T>
-    inline bool operator<(const SmartPtr<T>& a, const SmartPtr<T>& b)
-    {
-        return std::less<T*>()(a.get(), b.get());
-    }
-
-    template <class T>
     void swap(SmartPtr<T>& a, SmartPtr<T>& b)
     {
         a.swap(b);
@@ -193,13 +195,6 @@
     {
         return dynamic_cast<T*>(p.get());
     }
-
-    template <class T>
-    std::ostream& operator<<(std::ostream& os, const SmartPtr<T>& p)
-    {
-        os << p.get();
-        return os;
-    }
 }
 
 #endif /* _SmartPtr_H__ */

Added: code/branches/core5/src/libraries/core/WeakPtr.h
===================================================================
--- code/branches/core5/src/libraries/core/WeakPtr.h	                        (rev 0)
+++ code/branches/core5/src/libraries/core/WeakPtr.h	2009-09-28 15:16:36 UTC (rev 5823)
@@ -0,0 +1,184 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+// Inspired by boost::intrusive_ptr by Peter Dimov
+
+#ifndef _WeakPtr_H__
+#define _WeakPtr_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    template <class T>
+    class WeakPtr
+    {
+        public:
+            inline WeakPtr() : pointer_(0), base_(0)
+            {
+            }
+
+            inline WeakPtr(int) : pointer_(0), base_(0)
+            {
+            }
+
+            inline WeakPtr(T* pointer) : pointer_(pointer), base_(pointer)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            inline WeakPtr(const WeakPtr& other) : pointer_(other.pointer_), base_(other.base_)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            template <class O>
+            inline WeakPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.base_)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            inline ~WeakPtr()
+            {
+                if (this->base_)
+                    this->base_->unregisterWeakPtr(this);
+            }
+            
+            inline const WeakPtr& operator=(int)
+            {
+                WeakPtr(0).swap(*this);
+                return *this;
+            }
+
+            inline const WeakPtr& operator=(T* pointer)
+            {
+                WeakPtr(pointer).swap(*this);
+                return *this;
+            }
+
+            inline const WeakPtr& operator=(const WeakPtr& other)
+            {
+                WeakPtr(other).swap(*this);
+                return *this;
+            }
+
+            template <class O>
+            inline const WeakPtr& operator=(const WeakPtr<O>& other)
+            {
+                WeakPtr(other).swap(*this);
+                return *this;
+            }
+
+            inline T* get() const
+            {
+                return this->pointer_;
+            }
+
+            inline OrxonoxClass* getBase() const
+            {
+                return this->base_;
+            }
+
+            inline operator T*() const
+            {
+                return this->pointer_;
+            }
+
+            inline T* operator->() const
+            {
+                assert(this->pointer_ != 0);
+                return this->pointer_;
+            }
+
+            inline T& operator*() const
+            {
+                assert(this->pointer_ != 0);
+                return *this->pointer_;
+            }
+
+            inline bool operator!() const
+            {
+                return (this->pointer_ == 0);
+            }
+
+            inline void swap(WeakPtr& other)
+            {
+                {
+                    T* temp = this->pointer_;
+                    this->pointer_ = other.pointer_;
+                    other.pointer_ = temp;
+                }
+                {
+                    OrxonoxClass* temp = this->base_;
+                    this->base_ = other.base_;
+                    other.base_ = temp;
+                }
+            }
+
+            inline void reset()
+            {
+                WeakPtr().swap(*this);
+            }
+
+        private:
+            T* pointer_;
+            OrxonoxClass* base_;
+    };
+
+    template <class T>
+    void swap(WeakPtr<T>& a, WeakPtr<T>& b)
+    {
+        a.swap(b);
+    }
+
+    template <class T, class U>
+    WeakPtr<T> static_pointer_cast(const WeakPtr<U>& p)
+    {
+        return static_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    WeakPtr<T> const_pointer_cast(const WeakPtr<U>& p)
+    {
+        return const_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    WeakPtr<T> dynamic_pointer_cast(const WeakPtr<U>& p)
+    {
+        return dynamic_cast<T*>(p.get());
+    }
+}
+
+#endif /* _WeakPtr_H__ */


Property changes on: code/branches/core5/src/libraries/core/WeakPtr.h
___________________________________________________________________
Added: svn:eol-style
   + native




More information about the Orxonox-commit mailing list