1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxObject class, plus run-time type information macros 
   4 // Author:      Julian Smart 
   5 // Modified by: Ron Lee 
   8 // Copyright:   (c) 1997 Julian Smart and Markus Holzem 
   9 //              (c) 2001 Ron Lee <ron@debian.org> 
  10 // Licence:     wxWindows licence 
  11 ///////////////////////////////////////////////////////////////////////////// 
  17 #pragma interface "object.h" 
  20 // ---------------------------------------------------------------------------- 
  22 // ---------------------------------------------------------------------------- 
  25 #include "wx/memory.h" 
  27 class WXDLLEXPORT wxObject
; 
  29 #if wxUSE_DYNAMIC_CLASSES 
  31 // ---------------------------------------------------------------------------- 
  32 // conditional compilation 
  33 // ---------------------------------------------------------------------------- 
  42 class WXDLLEXPORT wxClassInfo
; 
  43 class WXDLLEXPORT wxHashTable
; 
  45 #if wxUSE_STD_IOSTREAM && (defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT) 
  46 #include "wx/ioswrap.h" 
  50 // ---------------------------------------------------------------------------- 
  52 // ---------------------------------------------------------------------------- 
  54 typedef wxObject 
*(*wxObjectConstructorFn
)(void); 
  56 class WXDLLEXPORT wxClassInfo
 
  59     wxClassInfo( const wxChar 
*className
, 
  60                  const wxChar 
*baseName1
, 
  61                  const wxChar 
*baseName2
, 
  63                  wxObjectConstructorFn ctor 
) 
  64         : m_className(className
) 
  65         , m_baseClassName1(baseName1
) 
  66         , m_baseClassName2(baseName2
) 
  68         , m_objectConstructor(ctor
) 
  74     wxObject 
*CreateObject() { return m_objectConstructor 
? (*m_objectConstructor
)() : 0; } 
  76     const wxChar       
*GetClassName() const { return m_className
; } 
  77     const wxChar       
*GetBaseClassName1() const { return m_baseClassName1
; } 
  78     const wxChar       
*GetBaseClassName2() const { return m_baseClassName2
; } 
  79     const wxClassInfo  
*GetBaseClass1() const { return m_baseInfo1
; } 
  80     const wxClassInfo  
*GetBaseClass2() const { return m_baseInfo2
; } 
  81     int                 GetSize() const { return m_objectSize
; } 
  83     wxObjectConstructorFn      
GetConstructor() const { return m_objectConstructor
; } 
  84     static const wxClassInfo  
*GetFirst() { return sm_first
; } 
  85     const wxClassInfo         
*GetNext() const { return m_next
; } 
  86     static wxClassInfo        
*FindClass(const wxChar 
*className
); 
  88         // Climb upwards through inheritance hierarchy. 
  89         // Dual inheritance is catered for. 
  91     bool IsKindOf(const wxClassInfo 
*info
) const 
  95                  ( m_baseInfo1 
&& m_baseInfo1
->IsKindOf(info
) ) || 
  96                  ( m_baseInfo2 
&& m_baseInfo2
->IsKindOf(info
) ) ); 
  99         // Initializes parent pointers and hash table for fast searching. 
 101     static void     InitializeClasses(); 
 103         // Cleans up hash table used for fast searching. 
 105     static void     CleanUpClasses(); 
 108     const wxChar            
*m_className
; 
 109     const wxChar            
*m_baseClassName1
; 
 110     const wxChar            
*m_baseClassName2
; 
 112     wxObjectConstructorFn    m_objectConstructor
; 
 114         // Pointers to base wxClassInfos: set in InitializeClasses 
 116     const wxClassInfo       
*m_baseInfo1
; 
 117     const wxClassInfo       
*m_baseInfo2
; 
 119         // class info object live in a linked list: 
 120         // pointers to its head and the next element in it 
 122     static wxClassInfo      
*sm_first
; 
 125     static wxHashTable      
*sm_classTable
; 
 128 WXDLLEXPORT wxObject 
*wxCreateDynamicObject(const wxChar 
*name
); 
 131 // ---------------------------------------------------------------------------- 
 132 // Dynamic class macros 
 133 // ---------------------------------------------------------------------------- 
 135 #define DECLARE_DYNAMIC_CLASS(name)           \ 
 137   static wxClassInfo sm_class##name;          \ 
 138   virtual wxClassInfo *GetClassInfo() const   \ 
 139    { return &name::sm_class##name; } 
 141 #define DECLARE_ABSTRACT_CLASS(name) DECLARE_DYNAMIC_CLASS(name) 
 142 #define DECLARE_CLASS(name) DECLARE_DYNAMIC_CLASS(name) 
 144 // ----------------------------------- 
 145 // for concrete classes 
 146 // ----------------------------------- 
 148     // Single inheritance with one base class 
 150 #define IMPLEMENT_DYNAMIC_CLASS(name, basename)                 \ 
 151  wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name()          \ 
 152   { return new name; }                                          \ 
 153  wxClassInfo name::sm_class##name(wxT(#name), wxT(#basename),   \ 
 154             0, (int) sizeof(name),                              \ 
 155             (wxObjectConstructorFn) wxConstructorFor##name); 
 157     // Multiple inheritance with two base classes 
 159 #define IMPLEMENT_DYNAMIC_CLASS2(name, basename1, basename2)    \ 
 160  wxObject* WXDLLEXPORT_CTORFN wxConstructorFor##name()          \ 
 161   { return new name; }                                          \ 
 162  wxClassInfo name::sm_class##name(wxT(#name), wxT(#basename1),  \ 
 163             wxT(#basename2), (int) sizeof(name),                \ 
 164             (wxObjectConstructorFn) wxConstructorFor##name); 
 166 // ----------------------------------- 
 167 // for abstract classes 
 168 // ----------------------------------- 
 170     // Single inheritance with one base class 
 172 #define IMPLEMENT_ABSTRACT_CLASS(name, basename)                \ 
 173  wxClassInfo name::sm_class##name(wxT(#name), wxT(#basename),   \ 
 174             0, (int) sizeof(name), (wxObjectConstructorFn) 0); 
 176     // Multiple inheritance with two base classes 
 178 #define IMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2)   \ 
 179  wxClassInfo name::sm_class##name(wxT(#name), wxT(#basename1),  \ 
 180             wxT(#basename2), (int) sizeof(name),                \ 
 181             (wxObjectConstructorFn) 0); 
 183 #define IMPLEMENT_CLASS IMPLEMENT_ABSTRACT_CLASS 
 184 #define IMPLEMENT_CLASS2 IMPLEMENT_ABSTRACT_CLASS2 
 186 // ----------------------------------- 
 187 // for pluggable classes 
 188 // ----------------------------------- 
 190     // NOTE: this should probably be the very first statement 
 191     //       in the class declaration so wxPluginSentinel is 
 192     //       the first member initialised and the last destroyed. 
 194 // _DECLARE_DL_SENTINEL(name) wxPluginSentinel m_pluginsentinel; 
 196 #if wxUSE_NESTED_CLASSES 
 198 #define _DECLARE_DL_SENTINEL(name, exportdecl)  \ 
 199 class exportdecl name##PluginSentinel {         \ 
 201     static const wxString sm_className;         \ 
 203     name##PluginSentinel();                     \ 
 204     ~name##PluginSentinel();                    \ 
 206 name##PluginSentinel  m_pluginsentinel; 
 208 #define _IMPLEMENT_DL_SENTINEL(name)                                \ 
 209  const wxString name::name##PluginSentinel::sm_className(#name);    \ 
 210  name::name##PluginSentinel::name##PluginSentinel() {               \ 
 211     wxPluginLibrary *e = (wxPluginLibrary*) wxPluginLibrary::ms_classes.Get(#name);   \ 
 212     if( e != 0 ) { e->RefObj(); }                                      \ 
 214  name::name##PluginSentinel::~##name##PluginSentinel() {            \ 
 215     wxPluginLibrary *e = (wxPluginLibrary*) wxPluginLibrary::ms_classes.Get(#name);   \ 
 216     if( e != 0 ) { e->UnrefObj(); }                                 \ 
 220 #define _DECLARE_DL_SENTINEL(name) 
 221 #define _IMPLEMENT_DL_SENTINEL(name) 
 223 #endif  // wxUSE_NESTED_CLASSES 
 225 #define DECLARE_PLUGGABLE_CLASS(name) \ 
 226  DECLARE_DYNAMIC_CLASS(name) _DECLARE_DL_SENTINEL(name, WXDLLEXPORT) 
 227 #define DECLARE_ABSTRACT_PLUGGABLE_CLASS(name)  \ 
 228  DECLARE_ABSTRACT_CLASS(name) _DECLARE_DL_SENTINEL(name, WXDLLEXPORT) 
 230 #define DECLARE_USER_EXPORTED_PLUGGABLE_CLASS(name, usergoo) \ 
 231  DECLARE_DYNAMIC_CLASS(name) _DECLARE_DL_SENTINEL(name, usergoo) 
 232 #define DECLARE_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(name, usergoo)  \ 
 233  DECLARE_ABSTRACT_CLASS(name) _DECLARE_DL_SENTINEL(name, usergoo) 
 235 #define IMPLEMENT_PLUGGABLE_CLASS(name, basename) \ 
 236  IMPLEMENT_DYNAMIC_CLASS(name, basename) _IMPLEMENT_DL_SENTINEL(name) 
 237 #define IMPLEMENT_PLUGGABLE_CLASS2(name, basename1, basename2)  \ 
 238  IMPLEMENT_DYNAMIC_CLASS2(name, basename1, basename2) _IMPLEMENT_DL_SENTINEL(name) 
 239 #define IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(name, basename) \ 
 240  IMPLEMENT_ABSTRACT_CLASS(name, basename) _IMPLEMENT_DL_SENTINEL(name) 
 241 #define IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2)  \ 
 242  IMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2) _IMPLEMENT_DL_SENTINEL(name) 
 244 #define IMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS(name, basename) \ 
 245  IMPLEMENT_PLUGGABLE_CLASS(name, basename) 
 246 #define IMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS2(name, basename1, basename2)  \ 
 247  IMPLEMENT_PLUGGABLE_CLASS2(name, basename1, basename2) 
 248 #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(name, basename) \ 
 249  IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(name, basename) 
 250 #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2)  \ 
 251  IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) 
 254 #define CLASSINFO(name) (&name::sm_class##name) 
 256 #else // !wxUSE_DYNAMIC_CLASSES 
 258     // No dynamic class system: so stub out the macros 
 260 #define DECLARE_DYNAMIC_CLASS(name) 
 261 #define DECLARE_ABSTRACT_CLASS(name) 
 262 #define DECLARE_CLASS(name) 
 263 #define IMPLEMENT_DYNAMIC_CLASS(name, basename) 
 264 #define IMPLEMENT_DYNAMIC_CLASS2(name, basename1, basename2) 
 265 #define IMPLEMENT_ABSTRACT_CLASS(name, basename) 
 266 #define IMPLEMENT_ABSTRACT_CLASS2(name, basename1, basename2) 
 267 #define IMPLEMENT_CLASS IMPLEMENT_ABSTRACT_CLASS 
 268 #define IMPLEMENT_CLASS2 IMPLEMENT_ABSTRACT_CLASS2 
 270 #define DECLARE_PLUGGABLE_CLASS(name) 
 271 #define DECLARE_ABSTRACT_PLUGGABLE_CLASS(name) 
 272 #define IMPLEMENT_PLUGGABLE_CLASS(name, basename) 
 273 #define IMPLEMENT_PLUGGABLE_CLASS2(name, basename1, basename2) 
 274 #define IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS(name, basename) 
 275 #define IMPLEMENT_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) 
 277 #define DECLARE_USER_EXPORTED_PLUGGABLE_CLASS(name, usergoo) 
 278 #define DECLARE_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(name, usergoo) 
 279 #define IMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS(name, basename) 
 280 #define IMPLEMENT_USER_EXPORTED_PLUGGABLE_CLASS2(name, basename1, basename2) 
 281 #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS(name, basename) 
 282 #define IMPLEMENT_USER_EXPORTED_ABSTRACT_PLUGGABLE_CLASS2(name, basename1, basename2) 
 284 #endif // wxUSE_DYNAMIC_CLASSES 
 287 #define wxIS_KIND_OF(obj, className) obj->IsKindOf(&className::sm_class##className) 
 289     // Just seems a bit nicer-looking (pretend it's not a macro) 
 291 #define wxIsKindOf(obj, className) obj->IsKindOf(&className::sm_class##className) 
 293     // to be replaced by dynamic_cast<> in the future 
 295 #define wxDynamicCast(obj, className) \ 
 296  (className *) wxCheckDynamicCast((wxObject*)(obj), &className::sm_class##className) 
 298     // The 'this' pointer is always true, so use this version 
 299     // to cast the this pointer and avoid compiler warnings. 
 301 #define wxDynamicCastThis(className) \ 
 302  (IsKindOf(&className::sm_class##className) ? (className *)(this) : (className *)0) 
 304 #define wxConstCast(obj, className) ((className *)(obj)) 
 308 inline void wxCheckCast(void *ptr
) 
 310     wxASSERT_MSG( ptr
, _T("wxStaticCast() used incorrectly") ); 
 312 #define wxStaticCast(obj, className) \ 
 313  (wxCheckCast(wxDynamicCast(obj, className)), ((className *)(obj))) 
 315 #else  // !__WXDEBUG__ 
 316 #define wxStaticCast(obj, className) ((className *)(obj)) 
 318 #endif  // __WXDEBUG__ 
 321     // Unfortunately Borland seems to need this include. 
 323 #if wxUSE_STD_IOSTREAM                                \ 
 324     && (defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT)  \ 
 325     && defined(__BORLANDC__) 
 327 #include <iostream.h> 
 334 // ---------------------------------------------------------------------------- 
 336 // ---------------------------------------------------------------------------- 
 338 class WXDLLEXPORT wxObjectRefData
; 
 340 class WXDLLEXPORT wxObject
 
 342 DECLARE_ABSTRACT_CLASS(wxObject
) 
 345     wxObject() : m_refData(0) {} 
 346     virtual ~wxObject() { UnRef(); } 
 348     bool IsKindOf(wxClassInfo 
*info
) const; 
 350 #if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING 
 351     void *operator new (size_t size
, wxChar 
*fileName 
= 0, int lineNum 
= 0); 
 353 #ifndef __VISAGECPP__ 
 354     void operator delete (void * buf
); 
 355 #elif __DEBUG_ALLOC__ 
 356     void operator delete (void *buf
, const char *_fname
, size_t _line
); 
 361 #if defined(__VISUALC__) && (__VISUALC__ >= 1200) 
 362     void operator delete(void *buf
, wxChar
*, int); 
 365     // Causes problems for VC++ 
 367 #if wxUSE_ARRAY_MEMORY_OPERATORS && !defined(__VISUALC__) && !defined( __MWERKS__) 
 368     void *operator new[] (size_t size
, wxChar 
*fileName 
= 0, int lineNum 
= 0); 
 369     void operator delete[] (void *buf
); 
 373     void *operator new[] (size_t size
, wxChar 
*fileName 
, int lineNum 
= 0); 
 374     void *operator new[] (size_t size
) { return operator new[] ( size
, 0, 0 ) ; } 
 375     void operator delete[] (void *buf
); 
 378 #endif // Debug & memory tracing 
 381 #if wxUSE_STD_IOSTREAM && (defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT) 
 382     virtual void Dump(wxSTD ostream
& str
); 
 385         // make a 'clone' of the object 
 387     void Ref(const wxObject
& clone
); 
 389         // destroy a reference 
 393     inline wxObjectRefData 
*GetRefData() const { return m_refData
; } 
 394     inline void SetRefData(wxObjectRefData 
*data
) { m_refData 
= data
; } 
 397     wxObjectRefData 
*m_refData
; 
 401 class WXDLLEXPORT wxObjectRefData
 
 403     friend class wxObject
; 
 406     wxObjectRefData() : m_count(1) {} 
 407     virtual ~wxObjectRefData() {} 
 409     inline int GetRefCount() const { return m_count
; } 
 415 inline wxObject 
*wxCheckDynamicCast(wxObject 
*obj
, wxClassInfo 
*classInfo
) 
 417     return obj 
&& obj
->GetClassInfo()->IsKindOf(classInfo
) ? obj 
: 0; 
 422 #define WXDEBUG_NEW new(__TFILE__,__LINE__) 
 425 #define WXDEBUG_NEW new 
 428     // Redefine new to be the debugging version. This doesn't 
 429     // work with all compilers, in which case you need to 
 430     // use WXDEBUG_NEW explicitly if you wish to use the debugging version. 
 432 #if defined(__WXDEBUG__) && wxUSE_GLOBAL_MEMORY_OPERATORS && wxUSE_DEBUG_NEW_ALWAYS 
 433 #define new new(__TFILE__,__LINE__) 
 436 #endif  // _WX_OBJECTH__