]> git.saurik.com Git - wxWidgets.git/blob - include/wx/tracker.h
added wxWeakRef<T> (slightly modified patch 1860953)
[wxWidgets.git] / include / wx / tracker.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/tracker.h
3 // Purpose: Support class for object lifetime tracking (wxWeakRef<T>)
4 // Author: Arne Steinarson
5 // Created: 2007-12-28
6 // RCS-ID: $Id:$
7 // Copyright: (c) 2007 Arne Steinarson
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_TRACKER_H_
12 #define _WX_TRACKER_H_
13
14 // This structure represents an object tracker and is stored in a linked list
15 // in the tracked object. It is only used in one of its derived forms.
16 struct wxTrackerNode
17 {
18 wxTrackerNode() : m_next(NULL) { }
19 virtual ~wxTrackerNode() { }
20
21 virtual void OnObjectDestroy() = 0;
22
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 };
28
29 virtual wxTrackerNodeType GetType() = 0;
30
31 protected:
32 wxTrackerNode *m_next;
33
34 friend class wxTrackableBase; // For list access
35 friend class wxEvtHandler; // For list access
36 };
37
38
39 // Add-on base class for a trackable object.
40 struct wxTrackableBase
41 {
42 wxTrackableBase() : m_first(NULL) { }
43
44 ~wxTrackableBase()
45 {
46 // Notify all registered refs
47
48 // OnObjectDestroy has to remove the item from the link chain
49 while ( m_first )
50 {
51 wxTrackerNode *first = m_first;
52 first->OnObjectDestroy();
53 RemoveNode(first);
54 }
55 }
56
57 void AddNode(wxTrackerNode *node)
58 {
59 node->m_next = m_first;
60 m_first = node;
61 }
62
63 void RemoveNode(wxTrackerNode *node)
64 {
65 for ( wxTrackerNode **pn = &m_first; *pn; pn = &(*pn)->m_next )
66 {
67 if ( *pn == node )
68 {
69 *pn = node->m_next;
70 return;
71 }
72 }
73
74 wxFAIL_MSG( "node should be present" );
75 }
76
77 wxTrackerNode *GetFirst() { return m_first; }
78
79 protected:
80 wxTrackerNode *m_first;
81 };
82
83 // The difference to wxTrackableBase is that this class adds
84 // a VTable to enable dynamic_cast query for wxTrackable.
85 struct wxTrackable : wxTrackableBase
86 {
87 virtual ~wxTrackable() { }
88 };
89
90
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>
95 struct wxHasBase
96 {
97 static char Match(B *pb);
98 static int Match(...);
99
100 enum { value = sizeof(Match((T*)NULL)) == sizeof(char) };
101 };
102
103 // A structure to cast to wxTrackableBase, using either static_cast<> or
104 // dynamic_cast<>.
105 template <class T, bool is_static>
106 struct wxTrackableCaster;
107
108 template <class T>
109 struct wxTrackableCaster<T, true>
110 {
111 static wxTrackableBase* Cast(T* pt)
112 {
113 return static_cast<wxTrackableBase *>(pt);
114 }
115 };
116
117 #ifdef HAVE_DYNAMIC_CAST
118
119 template <class T>
120 struct wxTrackableCaster<T, false>
121 {
122 static wxTrackableBase *Cast(T* pt)
123 {
124 return dynamic_cast<wxTrackableBase *>(pt);
125 }
126 };
127
128 #else // !HAVE_DYNAMIC_CAST
129
130 template <class T>
131 struct wxTrackableCaster<T, false>
132 {
133 static wxTrackableBase *Cast(T* pt) { return NULL; }
134 };
135
136 #endif // HAVE_DYNAMIC_CAST/!HAVE_DYNAMIC_CAST
137
138 #endif // _WX_TRACKER_H_
139