3D Audio GSoC:
[blender.git] / intern / audaspace / intern / AUD_Reference.h
index 4cc5c51d24d1850235a8ae1101ea4531a6289ccc..3977b22a1dd5ad0d3b18e56ba274b8caa57decc4 100644 (file)
 
 #include <map>
 
+// #define MEM_DEBUG
+
+#ifdef MEM_DEBUG
+#include <iostream>
+#include <typeinfo>
+#endif
+
+/**
+ * This class handles the reference counting.
+ */
 class AUD_ReferenceHandler
 {
 private:
+       /**
+        * Saves the reference counts.
+        */
        static std::map<void*, int> m_references;
 
 public:
+       /**
+        * Reference increment.
+        * \param reference The reference.
+        */
        static inline void incref(void* reference)
        {
+               if(!reference)
+                       return;
+
                std::map<void*, int>::iterator result = m_references.find(reference);
                if(result != m_references.end())
                {
@@ -52,8 +72,16 @@ public:
                }
        }
 
+       /**
+        * Reference decrement.
+        * \param reference The reference.
+        * \return Whether the reference has to be deleted.
+        */
        static inline bool decref(void* reference)
        {
+               if(!reference)
+                       return false;
+
                if(!--m_references[reference])
                {
                        m_references.erase(reference);
@@ -78,10 +106,22 @@ public:
         * Creates a new reference counter.
         * \param reference The reference.
         */
-       AUD_Reference(T* reference = 0)
+       template <class U>
+       AUD_Reference(U* reference)
+       {
+               m_original = reference;
+               m_reference = dynamic_cast<T*>(reference);
+               AUD_ReferenceHandler::incref(m_original);
+#ifdef MEM_DEBUG
+               if(m_reference != 0)
+                       std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
+       }
+
+       AUD_Reference()
        {
-               m_original = m_reference = reference;
-               AUD_ReferenceHandler::incref(reference);
+               m_original = 0;
+               m_reference = 0;
        }
 
        /**
@@ -90,8 +130,13 @@ public:
         */
        AUD_Reference(const AUD_Reference& ref)
        {
-               m_original = m_reference = ref.m_reference;
-               AUD_ReferenceHandler::incref(m_reference);
+               m_original = ref.m_original;
+               m_reference = ref.m_reference;
+               AUD_ReferenceHandler::incref(m_original);
+#ifdef MEM_DEBUG
+               if(m_reference != 0)
+                       std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
        }
 
        template <class U>
@@ -100,6 +145,10 @@ public:
                m_original = ref.get();
                m_reference = dynamic_cast<T*>(ref.get());
                AUD_ReferenceHandler::incref(m_original);
+#ifdef MEM_DEBUG
+               if(m_reference != 0)
+                       std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
        }
 
        /**
@@ -108,6 +157,10 @@ public:
         */
        ~AUD_Reference()
        {
+#ifdef MEM_DEBUG
+               if(m_reference != 0)
+                       std::cerr << "-" << typeid(*m_reference).name() << std::endl;
+#endif
                if(AUD_ReferenceHandler::decref(m_original))
                        delete m_reference;
        }
@@ -121,12 +174,20 @@ public:
                if(&ref == this)
                        return *this;
 
+#ifdef MEM_DEBUG
+               if(m_reference != 0)
+                       std::cerr << "-" << typeid(*m_reference).name() << std::endl;
+#endif
                if(AUD_ReferenceHandler::decref(m_original))
                        delete m_reference;
 
                m_original = ref.m_original;
                m_reference = ref.m_reference;
                AUD_ReferenceHandler::incref(m_original);
+#ifdef MEM_DEBUG
+               if(m_reference != 0)
+                       std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
 
                return *this;
        }
@@ -147,6 +208,9 @@ public:
                return m_reference;
        }
 
+       /**
+        * Returns the original pointer.
+        */
        inline void* getOriginal() const
        {
                return m_original;