1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxWeakRef - Generic weak references for wxWidgets
4 // Author: Arne Steinarson
7 // Copyright: (c) 2007 Arne Steinarson
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_WEAKREF_H_
12 #define _WX_WEAKREF_H_
14 #include "wx/tracker.h"
17 // Some compilers (VC6, Borland, otehrs?) have problem with template specialization.
18 // However, this is only used for optimization purposes (a smaller wxWeakRef pointer)
19 // (and the corner case of wxWeakRef<wxObject>). So for those compilers, we can fall
20 // back to the non-optimal case, where we use a the same type of weak ref (static one)
21 // in all cases. See defs.h for various setting these defines depending on compiler.
23 #if !defined(HAVE_PARTIAL_SPECIALIZATION) || !defined(HAVE_TEMPLATE_OVERLOAD_RESOLUTION)
24 #define USE_ONLY_STATIC_WEAKREF
28 #ifndef USE_ONLY_STATIC_WEAKREF
30 // Avoid including this for simpler compilers
31 #include "wx/meta/convertible.h"
32 #include "wx/meta/int2type.h"
35 struct wxIsStaticTrackable
37 enum { value
= wxConvertibleTo
<T
, wxTrackable
>::value
};
40 #endif // !USE_ONLY_STATIC_WEAKREF
43 // Weak ref implementation when T has wxTrackable as a known base class
45 class wxWeakRefStatic
: public wxTrackerNode
48 wxWeakRefStatic() : m_pobj(NULL
) { }
52 // Release old object if any
55 // Remove ourselves from object tracker list
56 wxTrackable
*pt
= static_cast<wxTrackable
*>(m_pobj
);
62 virtual void OnObjectDestroy()
64 // Tracked object itself removes us from list of trackers
65 wxASSERT(m_pobj
!= NULL
);
77 // Now set new trackable object
80 // Add ourselves to object tracker list
81 wxTrackable
*pt
= static_cast<wxTrackable
*>(pobj
);
87 void AssignCopy(const wxWeakRefStatic
& wr
)
97 #ifndef USE_ONLY_STATIC_WEAKREF
99 template<class T
,bool use_static
>
100 struct wxWeakRefImpl
;
102 // Intermediate class, to select the static case above.
104 struct wxWeakRefImpl
<T
, true> : public wxWeakRefStatic
<T
>
109 // Weak ref implementation when T does not have wxTrackable as known base class
111 struct wxWeakRefImpl
<T
, false> : public wxTrackerNode
115 // Release old object if any
118 // Remove ourselves from object tracker list
119 m_ptbase
->RemoveNode(this);
125 virtual void OnObjectDestroy()
127 // Tracked object itself removes us from list of trackers
128 wxASSERT(m_pobj
!= NULL
);
134 wxWeakRefImpl() : m_pobj(NULL
), m_ptbase(NULL
) { }
136 // Assign receives most derived class here and can use that
137 template <class TDerived
>
138 void Assign( TDerived
* pobj
)
140 AssignHelper( pobj
, wxInt2Type
<wxIsStaticTrackable
<TDerived
>::value
>() );
143 template <class TDerived
>
144 void AssignHelper(TDerived
* pobj
, wxInt2Type
<true>)
146 wxTrackable
*ptbase
= static_cast<wxTrackable
*>(pobj
);
147 DoAssign( pobj
, ptbase
);
150 #ifdef HAVE_DYNAMIC_CAST
151 void AssignHelper(T
* pobj
, wxInt2Type
<false>)
153 // A last way to get a trackable pointer
154 wxTrackable
*ptbase
= dynamic_cast<wxTrackable
*>(pobj
);
157 DoAssign( pobj
, ptbase
);
161 wxFAIL_MSG( "Tracked class should inherit from wxTrackable" );
166 #endif // HAVE_DYNAMIC_CAST
168 void AssignCopy(const wxWeakRefImpl
& wr
)
170 DoAssign(wr
.m_pobj
, wr
.m_ptbase
);
173 void DoAssign( T
* pobj
, wxTrackable
*ptbase
) {
174 if( m_pobj
==pobj
) return;
177 // Now set new trackable object
180 // Add ourselves to object tracker list
182 ptbase
->AddNode( this );
189 wxTrackable
*m_ptbase
;
192 #endif // #ifndef USE_ONLY_STATIC_WEAKREF
196 // A weak reference to an object of type T, where T has base wxTrackable
197 // (usually statically but if not dynamic_cast<> is tried).
199 class wxWeakRef
: public
200 #ifdef USE_ONLY_STATIC_WEAKREF
203 wxWeakRefImpl
<T
, wxIsStaticTrackable
<T
>::value
>
210 // When we have the full type here, static_cast<> will always work
211 // (or give a straight compiler error).
212 template <class TDerived
>
213 wxWeakRef(TDerived
* pobj
)
218 // We need this copy ctor, since otherwise a default compiler (binary) copy
219 // happens (if embedded as an object member).
220 wxWeakRef(const wxWeakRef
<T
>& wr
)
225 template <class TDerived
>
226 wxWeakRef
<T
>& operator=(TDerived
* pobj
)
232 wxWeakRef
<T
>& operator=(const wxWeakRef
<T
>& wr
)
238 virtual ~wxWeakRef() { this->Release(); }
240 // Smart pointer functions
241 T
& operator*() const { return *this->m_pobj
; }
242 T
* operator->() const { return this->m_pobj
; }
244 T
* get() const { return this->m_pobj
; }
245 operator T
*() const { return this->m_pobj
; }
249 #ifdef HAVE_DYNAMIC_CAST
251 // Weak ref implementation assign objects are queried for wxTrackable
252 // using dynamic_cast<>
254 class wxWeakRefDynamic
: public wxTrackerNode
257 wxWeakRefDynamic() : m_pobj(NULL
) { }
259 wxWeakRefDynamic(T
* pobj
) : m_pobj(pobj
)
264 wxWeakRefDynamic(const wxWeakRef
<T
>& wr
)
269 virtual ~wxWeakRefDynamic() { Release(); }
271 // Smart pointer functions
272 T
& operator*() const { wxASSERT(m_pobj
); return *m_pobj
; }
273 T
* operator->() const { wxASSERT(m_pobj
); return m_pobj
; }
275 T
* get() const { return m_pobj
; }
276 operator T
* () const { return m_pobj
; }
278 T
* operator = (T
* pobj
) { Assign(pobj
); return m_pobj
; }
280 // Assign from another weak ref, point to same object
281 T
* operator = (const wxWeakRef
<T
> &wr
) { Assign( wr
.get() ); return m_pobj
; }
285 // Release old object if any
288 // Remove ourselves from object tracker list
289 wxTrackable
*pt
= dynamic_cast<wxTrackable
*>(m_pobj
);
291 pt
->RemoveNode(this);
296 virtual void OnObjectDestroy()
298 wxASSERT_MSG(m_pobj
, "tracked object should have removed us itself");
306 if ( m_pobj
== pobj
)
311 // Now set new trackable object
314 // Add ourselves to object tracker list
315 wxTrackable
*pt
= dynamic_cast<wxTrackable
*>(pobj
);
323 // If the object we want to track does not support wxTackable, then
324 // log a message and keep the NULL object pointer.
325 wxFAIL_MSG( "Tracked class should inherit from wxTrackable" );
333 #endif // #ifdef HAVE_DYNAMIC_CAST
336 // Provide some basic types of weak references
337 class WXDLLIMPEXP_FWD_BASE wxEvtHandler
;
338 class WXDLLIMPEXP_FWD_CORE wxWindow
;
341 typedef wxWeakRef
<wxEvtHandler
> wxEvtHandlerRef
;
342 typedef wxWeakRef
<wxWindow
> wxWindowRef
;
344 #endif // _WX_WEAKREF_H_