]>
git.saurik.com Git - wxWidgets.git/blob - include/wx/tracker.h
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Support class for object lifetime tracking (wxWeakRef<T>)
4 // Author: Arne Steinarson
7 // Copyright: (c) 2007 Arne Steinarson
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_TRACKER_H_
12 #define _WX_TRACKER_H_
15 // This structure represents an object tracker and is stored in a linked list
16 // in the tracked object. It is only used in one of its derived forms.
17 struct wxTrackerNode
{
18 wxTrackerNode( ) : m_nxt(0) { }
19 virtual ~wxTrackerNode() { }
21 virtual void OnObjectDestroy( ) = 0;
23 // This is to tell the difference between different tracker node types.
24 // It's a replacement of dynamic_cast<> for this class since dynamic_cast
25 // may be disabled (and we don't have wxDynamicCast since wxTrackerNode
26 // is not derived wxObject).
27 enum wxTrackerNodeType
{ WeakRef
, EventConnectionRef
};
29 virtual wxTrackerNodeType
GetType() = 0;
33 friend class wxTrackableBase
; // For list access
34 friend class wxEvtHandler
; // For list access
38 // Add-on base class for a trackable object.
39 struct wxTrackableBase
{
40 wxTrackableBase() : m_first(0) { }
43 // Notify all registered refs
49 first
->OnObjectDestroy( );
54 void AddNode( wxTrackerNode
*prn
)
59 void RemoveNode( wxTrackerNode
*prn
)
61 for( wxTrackerNode
**pprn
=&m_first
; *pprn
; pprn
=&(*pprn
)->m_nxt
)
69 // Not found, an error.
73 wxTrackerNode
* GetFirst( ){ return m_first
; }
75 // If trying to copy this object, then do not copy its ref list.
76 wxTrackableBase
& operator = (const wxTrackableBase
& other
) { return *this; }
79 wxTrackerNode
*m_first
;
83 // The difference to wxTrackableBase is that this class adds
84 // a VTable to enable dynamic_cast query for wxTrackable.
85 struct wxTrackable
: public wxTrackableBase
87 virtual ~wxTrackable(){ }
91 // Helper to decide if an object has a base class or not
92 // (strictly speaking, this test succeeds if a type is convertible
93 // to another type in some way.)
94 template<class T
, class B
>
96 static char Match( B
* pb
);
97 static int Match( ... );
98 enum { value
= (sizeof(Match((T
*)NULL
))==sizeof(char)) };
101 // VC++ before 7.1 does not have partial template specialization
103 #if __VISUALC__ < 1310
104 #define HAVE_NO_PARTIAL_SPECIALIZATION
108 #if defined(HAVE_DYNAMIC_CAST) && !defined(HAVE_NO_PARTIAL_SPECIALIZATION)
109 // A structure to cast to wxTrackableBase, using either static_cast<> or dynamic_cast<>.
110 template<class T
,bool is_static
>
111 struct wxTrackableCaster
;
114 struct wxTrackableCaster
<T
,true> {
115 static wxTrackableBase
* Cast(T
* pt
){ return static_cast<wxTrackableBase
*>(pt
); }
119 struct wxTrackableCaster
<T
,false> {
120 static wxTrackableBase
* Cast(T
* pt
){ return dynamic_cast<wxTrackableBase
*>(pt
); }
123 #if defined(HAVE_DYNAMIC_CAST)
124 // If we have dynamic_cast, default to that. For gcc, dynamic_cast<> does the job
125 // of both the dynamic and the static case. It could be that all compilers do it
126 // that way, rendering the specialization code above rednundant.
127 template <class T
,bool is_static
>
128 struct wxTrackableCaster
{
129 static wxTrackableBase
* Cast(T
* pt
){ return dynamic_cast<wxTrackableBase
*>(pt
); }
132 // No dynamic_cast<> is available.
133 // We use static_cast<>, that gives support for wxEvtHandler and wxWindow references.
134 // We don't get weak refs to other wxObject derived types.
135 template <class T
,bool is_static
>
136 struct wxTrackableCaster
{
137 static wxTrackableBase
* Cast(T
* pt
){ return static_cast<wxTrackableBase
*>(pt
); }
142 #endif // _WX_TRACKER_H_