]> git.saurik.com Git - wxWidgets.git/commitdiff
Updated wxTrackable to patch Weak references for wx - part 2
authorRobert Roebling <robert@roebling.de>
Tue, 8 Jan 2008 09:58:44 +0000 (09:58 +0000)
committerRobert Roebling <robert@roebling.de>
Tue, 8 Jan 2008 09:58:44 +0000 (09:58 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51101 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/tracker.h

index ccb81c8fe55e22c952c0e3fd0d3e352765b815ca..4f4ec195a73beb9aeb575827922ec99d82fb531b 100644 (file)
@@ -3,7 +3,7 @@
 // Purpose:     Support class for object lifetime tracking (wxWeakRef<T>)
 // Author:      Arne Steinarson
 // Created:     2007-12-28
-// RCS-ID:      $Id:$
+// RCS-ID:      $Id$
 // Copyright:   (c) 2007 Arne Steinarson
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 #ifndef _WX_TRACKER_H_
 #define _WX_TRACKER_H_
 
+
 // This structure represents an object tracker and is stored in a linked list
 // in the tracked object. It is only used in one of its derived forms.
-struct wxTrackerNode
-{
-    wxTrackerNode() : m_next(NULL) { }
+struct wxTrackerNode {
+    wxTrackerNode( ) : m_nxt(0) { }
     virtual ~wxTrackerNode() { }
-
-    virtual void OnObjectDestroy() = 0;
-
-    // This is to tell the difference between different tracker node types.
-    // It's a replacement of dynamic_cast<> for this class since dynamic_cast
-    // may be disabled (and we don't have wxDynamicCast since wxTrackerNode
+    
+    virtual void OnObjectDestroy( ) = 0;
+    
+    // This is to tell the difference between different tracker node types. 
+    // It's a replacement of dynamic_cast<> for this class since dynamic_cast 
+    // may be disabled (and we don't have wxDynamicCast since wxTrackerNode 
     // is not derived wxObject).
-    enum wxTrackerNodeType { WeakRef, EventConnectionRef };
+    enum wxTrackerNodeType { WeakRef, EventConnectionRef }; 
 
     virtual wxTrackerNodeType GetType() = 0;
-
+    
 protected:
-    wxTrackerNode *m_next;
-
+    wxTrackerNode *m_nxt;
     friend class wxTrackableBase;    // For list access
     friend class wxEvtHandler;       // For list access
 };
 
 
 // Add-on base class for a trackable object.
-struct wxTrackableBase
-{
-    wxTrackableBase() : m_first(NULL) { }
-
+struct wxTrackableBase {
+    wxTrackableBase() : m_first(0) { }
     ~wxTrackableBase()
-    {
+    { 
         // Notify all registered refs
-
-        // OnObjectDestroy has to remove the item from the link chain
-        while ( m_first )
+        
+        wxTrackerNode *first;
+        while( m_first )
         {
-            wxTrackerNode *first = m_first;
-            first->OnObjectDestroy();
+               first = m_first;
+            first->OnObjectDestroy( );
             RemoveNode(first);
         }
     }
-
-    void AddNode(wxTrackerNode *node)
+    
+    void AddNode( wxTrackerNode *prn )
     {
-        node->m_next = m_first;
-        m_first = node;
+        prn->m_nxt = m_first;
+        m_first = prn;
     }
-
-    void RemoveNode(wxTrackerNode *node)
+    void RemoveNode( wxTrackerNode *prn )
     {
-        for ( wxTrackerNode **pn = &m_first; *pn; pn = &(*pn)->m_next )
+        for( wxTrackerNode **pprn=&m_first; *pprn; pprn=&(*pprn)->m_nxt )
         {
-            if ( *pn == node )
+            if( *pprn==prn )
             {
-                *pn = node->m_next;
+                *pprn = prn->m_nxt;
                 return;
             }
         }
-
-        wxFAIL_MSG( "node should be present" );
+        // Not found, an error.
+        wxASSERT( false );
     }
+    
+    wxTrackerNode* GetFirst( ){ return m_first; }
 
-    wxTrackerNode *GetFirst() { return m_first; }
-
-protected:
+    // If trying to copy this object, then do not copy its ref list.
+    wxTrackableBase& operator = (const wxTrackableBase& other) { return *this; }
+    
+protected:    
     wxTrackerNode *m_first;
 };
 
-// The difference to wxTrackableBase is that this class adds
+
+// The difference to wxTrackableBase is that this class adds 
 // a VTable to enable dynamic_cast query for wxTrackable.
-struct wxTrackable : wxTrackableBase
+struct wxTrackable : public wxTrackableBase 
 {
-    virtual ~wxTrackable() { }
+    virtual ~wxTrackable(){ }
 };
 
 
 // Helper to decide if an object has a base class or not
 // (strictly speaking, this test succeeds if a type is convertible
 //  to another type in some way.)
-template <class T, class B>
-struct wxHasBase
-{
-       static char Match(B *pb);
-       static int Match(...);
-
-       enum { value = sizeof(Match((T*)NULL)) == sizeof(char) };
-};
-
-// A structure to cast to wxTrackableBase, using either static_cast<> or
-// dynamic_cast<>.
-template <class T, bool is_static>
-struct wxTrackableCaster;
-
-template <class T>
-struct wxTrackableCaster<T, true>
-{
-    static wxTrackableBase* Cast(T* pt)
-    {
-        return static_cast<wxTrackableBase *>(pt);
-    }
-};
-
-#ifdef HAVE_DYNAMIC_CAST
-
-template <class T>
-struct wxTrackableCaster<T, false>
-{
-    static wxTrackableBase *Cast(T* pt)
-    {
-        return dynamic_cast<wxTrackableBase *>(pt);
-    }
-};
-
-#else // !HAVE_DYNAMIC_CAST
-
-template <class T>
-struct wxTrackableCaster<T, false>
-{
-    static wxTrackableBase *Cast(T* pt) { return NULL; }
+template<class T, class B>
+struct wxHasBase{
+       static char Match( B* pb );        
+       static int Match( ... );       
+       enum { value = (sizeof(Match((T*)NULL))==sizeof(char)) };
 };
 
-#endif // HAVE_DYNAMIC_CAST/!HAVE_DYNAMIC_CAST
+// VC++ before 7.1 does not have partial template specialization 
+#ifdef __VISUALC__
+    #if __VISUALC__ < 1310
+        #define HAVE_NO_PARTIAL_SPECIALIZATION
+    #endif
+#endif 
+
+#if defined(HAVE_DYNAMIC_CAST) && !defined(HAVE_NO_PARTIAL_SPECIALIZATION) 
+    // A structure to cast to wxTrackableBase, using either static_cast<> or dynamic_cast<>. 
+    template<class T,bool is_static>
+    struct wxTrackableCaster;
+
+    template <class T>
+    struct wxTrackableCaster<T,true> {
+        static wxTrackableBase* Cast(T* pt){ return static_cast<wxTrackableBase*>(pt); }
+    };
+
+    template <class T>
+    struct wxTrackableCaster<T,false> {
+        static wxTrackableBase* Cast(T* pt){ return dynamic_cast<wxTrackableBase*>(pt); }
+    };
+#else 
+    #if defined(HAVE_DYNAMIC_CAST) 
+        // If we have dynamic_cast, default to that. For gcc, dynamic_cast<> does the job 
+        // of both the dynamic and the static case. It could be that all compilers do it 
+        // that way, rendering the specialization code above rednundant.
+        template <class T,bool is_static>
+        struct wxTrackableCaster {
+            static wxTrackableBase* Cast(T* pt){ return dynamic_cast<wxTrackableBase*>(pt); }
+        };
+    #else
+        // No dynamic_cast<> is available.
+        // We use static_cast<>, that gives support for wxEvtHandler and wxWindow references. 
+        // We don't get weak refs to other wxObject derived types.
+        template <class T,bool is_static>
+        struct wxTrackableCaster {
+            static wxTrackableBase* Cast(T* pt){ return static_cast<wxTrackableBase*>(pt); }
+        };
+    #endif
+#endif 
 
 #endif // _WX_TRACKER_H_