// 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
// 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_