]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/tracker.h
added template wxScopedArray<> too
[wxWidgets.git] / include / wx / tracker.h
index ccb81c8fe55e22c952c0e3fd0d3e352765b815ca..be699d1701e8d0224fdbfd5cb8269fea635873d0 100644 (file)
@@ -2,8 +2,8 @@
 // Name:        wx/tracker.h
 // Purpose:     Support class for object lifetime tracking (wxWeakRef<T>)
 // Author:      Arne Steinarson
-// Created:     2007-12-28
-// RCS-ID:      $Id:$
+// Created:     28 Dec 07
+// 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
+#include "wx/defs.h"
+
+class wxEventConnectionRef;
+
+// This class 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
+class WXDLLIMPEXP_BASE wxTrackerNode
 {
-    wxTrackerNode() : m_next(NULL) { }
+public:
+    wxTrackerNode() : m_nxt(NULL) { }
     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
-    // is not derived wxObject).
-    enum wxTrackerNodeType { WeakRef, EventConnectionRef };
-
-    virtual wxTrackerNodeType GetType() = 0;
+    virtual wxEventConnectionRef *ToEventConnection() { return NULL; }
 
-protected:
-    wxTrackerNode *m_next;
+private:
+    wxTrackerNode *m_nxt;
 
-    friend class wxTrackableBase;    // For list access
+    friend class wxTrackable;        // For list access
     friend class wxEvtHandler;       // For list access
 };
 
-
 // Add-on base class for a trackable object.
-struct wxTrackableBase
+class WXDLLIMPEXP_BASE wxTrackable
 {
-    wxTrackableBase() : m_first(NULL) { }
-
-    ~wxTrackableBase()
+public:
+    void AddNode(wxTrackerNode *prn)
     {
-        // Notify all registered refs
-
-        // OnObjectDestroy has to remove the item from the link chain
-        while ( m_first )
-        {
-            wxTrackerNode *first = m_first;
-            first->OnObjectDestroy();
-            RemoveNode(first);
-        }
+        prn->m_nxt = m_first;
+        m_first = prn;
     }
 
-    void AddNode(wxTrackerNode *node)
+    void RemoveNode(wxTrackerNode *prn)
     {
-        node->m_next = m_first;
-        m_first = node;
-    }
-
-    void RemoveNode(wxTrackerNode *node)
-    {
-        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" );
+        wxFAIL_MSG( "removing invalid tracker node" );
     }
 
-    wxTrackerNode *GetFirst() { return m_first; }
+    wxTrackerNode *GetFirst() const { return m_first; }
 
 protected:
-    wxTrackerNode *m_first;
-};
+    // this class is only supposed to be used as a base class but never be
+    // created nor destroyed directly so all ctors and dtor are protected
 
-// The difference to wxTrackableBase is that this class adds
-// a VTable to enable dynamic_cast query for wxTrackable.
-struct wxTrackable : wxTrackableBase
-{
-    virtual ~wxTrackable() { }
-};
+    wxTrackable() : m_first(NULL) { }
 
+    // copy ctor and assignment operator intentionally do not copy m_first: the
+    // objects which track the original trackable shouldn't track the new copy
+    wxTrackable(const wxTrackable& WXUNUSED(other)) : m_first(NULL) { }
+    wxTrackable& operator=(const wxTrackable& WXUNUSED(other)) { return *this; }
 
-// 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)
+    // dtor is not virtual: this class is not supposed to be used
+    // polymorphically and adding a virtual table to it would add unwanted
+    // overhead
+    ~wxTrackable()
     {
-        return dynamic_cast<wxTrackableBase *>(pt);
+        // Notify all registered refs
+        while ( m_first )
+        {
+            wxTrackerNode * const first = m_first;
+            m_first = first->m_nxt;
+            first->OnObjectDestroy();
+        }
     }
-};
-
-#else // !HAVE_DYNAMIC_CAST
 
-template <class T>
-struct wxTrackableCaster<T, false>
-{
-    static wxTrackableBase *Cast(T* pt) { return NULL; }
+    wxTrackerNode *m_first;
 };
 
-#endif // HAVE_DYNAMIC_CAST/!HAVE_DYNAMIC_CAST
-
 #endif // _WX_TRACKER_H_