X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2ef989c972df0bd023ec3b7252fb91afca55f8ab..f9d6e4e454ac06b3303c71081b289152c8867ec1:/include/wx/tracker.h diff --git a/include/wx/tracker.h b/include/wx/tracker.h index ef1ab84388..be699d1701 100644 --- a/include/wx/tracker.h +++ b/include/wx/tracker.h @@ -2,7 +2,7 @@ // Name: wx/tracker.h // Purpose: Support class for object lifetime tracking (wxWeakRef) // Author: Arne Steinarson -// Created: 2007-12-28 +// Created: 28 Dec 07 // RCS-ID: $Id$ // Copyright: (c) 2007 Arne Steinarson // Licence: wxWindows licence @@ -11,133 +11,82 @@ #ifndef _WX_TRACKER_H_ #define _WX_TRACKER_H_ +#include "wx/defs.h" -// This structure represents an object tracker and is stored in a linked list +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 { - wxTrackerNode( ) : m_nxt(0) { } +class WXDLLIMPEXP_BASE wxTrackerNode +{ +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; - -protected: + + virtual void OnObjectDestroy() = 0; + + virtual wxEventConnectionRef *ToEventConnection() { return NULL; } + +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 { - wxTrackableBase() : m_first(0) { } - ~wxTrackableBase() - { - // Notify all registered refs - - wxTrackerNode *first; - while( m_first ) - { - first = m_first; - first->OnObjectDestroy( ); - RemoveNode(first); - } - } - - void AddNode( wxTrackerNode *prn ) +class WXDLLIMPEXP_BASE wxTrackable +{ +public: + void AddNode(wxTrackerNode *prn) { prn->m_nxt = m_first; m_first = prn; } - void RemoveNode( wxTrackerNode *prn ) + + void RemoveNode(wxTrackerNode *prn) { - for( wxTrackerNode **pprn=&m_first; *pprn; pprn=&(*pprn)->m_nxt ) + for ( wxTrackerNode **pprn = &m_first; *pprn; pprn = &(*pprn)->m_nxt ) { - if( *pprn==prn ) + if ( *pprn == prn ) { *pprn = prn->m_nxt; return; } } - // Not found, an error. - wxASSERT( false ); + + wxFAIL_MSG( "removing invalid tracker node" ); } - - wxTrackerNode* GetFirst( ){ return m_first; } - // If trying to copy this object, then do not copy its ref list. - wxTrackableBase& operator = (const wxTrackableBase& WXUNUSED(other)) { return *this; } - -protected: - wxTrackerNode *m_first; -}; + wxTrackerNode *GetFirst() const { return m_first; } +protected: + // 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 : public 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 -struct wxHasBase{ - static char Match( B* pb ); - static int Match( ... ); - enum { value = (sizeof(Match((T*)NULL))==sizeof(char)) }; -}; + // 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() + { + // Notify all registered refs + while ( m_first ) + { + wxTrackerNode * const first = m_first; + m_first = first->m_nxt; + first->OnObjectDestroy(); + } + } -// VC++ before 7.1 does not have partial template specialization -#ifdef __VISUALC__ - #if __VISUALC__ < 1310 - #define HAVE_NO_PARTIAL_SPECIALIZATION - #endif -#endif - -#if defined(HAVE_DYNAMIC_CAST) && !defined(HAVE_NO_PARTIAL_SPECIALIZATION) - // A structure to cast to wxTrackableBase, using either static_cast<> or dynamic_cast<>. - template - struct wxTrackableCaster; - - template - struct wxTrackableCaster { - static wxTrackableBase* Cast(T* pt){ return static_cast(pt); } - }; - - template - struct wxTrackableCaster { - static wxTrackableBase* Cast(T* pt){ return dynamic_cast(pt); } - }; -#else - #if defined(HAVE_DYNAMIC_CAST) - // If we have dynamic_cast, default to that. For gcc, dynamic_cast<> does the job - // of both the dynamic and the static case. It could be that all compilers do it - // that way, rendering the specialization code above rednundant. - template - struct wxTrackableCaster { - static wxTrackableBase* Cast(T* pt){ return dynamic_cast(pt); } - }; - #else - // No dynamic_cast<> is available. - // We use static_cast<>, that gives support for wxEvtHandler and wxWindow references. - // We don't get weak refs to other wxObject derived types. - template - struct wxTrackableCaster { - static wxTrackableBase* Cast(T* pt){ return static_cast(pt); } - }; - #endif -#endif + wxTrackerNode *m_first; +}; #endif // _WX_TRACKER_H_