]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/object.cpp
some wxArtProv docs
[wxWidgets.git] / src / common / object.cpp
index 120d0afac5ef0ce6f974c193df60197119ad4717..776878d214a7f1440480b3c8596fdd29996d5333 100644 (file)
@@ -135,15 +135,43 @@ void wxObject::operator delete[] (void *buf)
 
 wxClassInfo *wxClassInfo::FindClass(const wxChar *className)
 {
-    for(wxClassInfo *info = sm_first; info ; info = info->m_next)
-        if( wxStrcmp(info->GetClassName(), className) == 0 )
-            return info;
+    if ( sm_classTable )
+    {
+        return (wxClassInfo *)wxClassInfo::sm_classTable->Get(className);
+    }
+    else
+    {
+        for ( wxClassInfo *info = sm_first; info ; info = info->m_next )
+        {
+            if ( wxStrcmp(info->GetClassName(), className) == 0 )
+                return info;
+        }
 
-    return 0;
+        return NULL;
+    }
 }
 
-    // Set pointers to base class(es) to speed up IsKindOf
+// a tiny InitializeClasses() helper
+/* static */
+inline wxClassInfo *wxClassInfo::GetBaseByName(const wxChar *name)
+{
+    if ( !name )
+        return NULL;
+
+    wxClassInfo *classInfo = (wxClassInfo *)sm_classTable->Get(name);
+
+    // this must be fixed, other things risk work wrongly later if you get this
+    wxASSERT_MSG( classInfo,
+                  wxString::Format
+                  (
+                    _T("base class '%s' is unknown to wxWindows RTTI"),
+                    name
+                  ) );
+
+    return classInfo;
+}
 
+// Set pointers to base class(es) to speed up IsKindOf
 void wxClassInfo::InitializeClasses()
 {
     // using IMPLEMENT_DYNAMIC_CLASS() macro twice (which may happen if you
@@ -176,10 +204,8 @@ void wxClassInfo::InitializeClasses()
 
     for(info = sm_first; info; info = info->m_next)
     {
-        if (info->GetBaseClassName1())
-            info->m_baseInfo1 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName1());
-        if (info->GetBaseClassName2())
-            info->m_baseInfo2 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName2());
+        info->m_baseInfo1 = GetBaseByName(info->GetBaseClassName1());
+        info->m_baseInfo2 = GetBaseByName(info->GetBaseClassName2());
     }
 }
 
@@ -218,14 +244,18 @@ wxObject *wxCreateDynamicObject(const wxChar *name)
 void wxObject::Ref(const wxObject& clone)
 {
 #if defined(__WXDEBUG__) || wxUSE_DEBUG_CONTEXT
- DEBUG_PRINTF(wxObject::Ref)
   DEBUG_PRINTF(wxObject::Ref)
 #endif
 
+    // nothing to be done
+    if (m_refData == clone.m_refData)
+        return;
+
     // delete reference to old data
     UnRef();
 
     // reference new data
-    if( clone.m_refData )
+    if ( clone.m_refData )
     {
         m_refData = clone.m_refData;
         ++(m_refData->m_count);
@@ -234,16 +264,57 @@ void wxObject::Ref(const wxObject& clone)
 
 void wxObject::UnRef()
 {
-    if( m_refData )
+    if ( m_refData )
     {
         wxASSERT_MSG( m_refData->m_count > 0, _T("invalid ref data count") );
 
         if ( !--m_refData->m_count )
             delete m_refData;
-        m_refData = 0;
+        m_refData = NULL;
+    }
+}
+
+void wxObject::AllocExclusive()
+{
+    if ( !m_refData )
+    {
+        m_refData = CreateRefData();
+    }
+    else if ( m_refData->GetRefCount() > 1 )
+    {
+        // note that ref is not going to be destroyed in this case
+        const wxObjectRefData* ref = m_refData;
+        UnRef();
+
+        // ... so we can still access it
+        m_refData = CloneRefData(ref);
     }
+    //else: ref count is 1, we are exclusive owners of m_refData anyhow
+
+    wxASSERT_MSG( m_refData && m_refData->GetRefCount() == 1,
+                  _T("wxObject::AllocExclusive() failed.") );
+}
+
+wxObjectRefData *wxObject::CreateRefData() const
+{
+    // if you use AllocExclusive() you must override this method
+    wxFAIL_MSG( _T("CreateRefData() must be overridden if called!") );
+
+    return NULL;
+}
+
+wxObjectRefData *
+wxObject::CloneRefData(const wxObjectRefData * WXUNUSED(data)) const
+{
+    // if you use AllocExclusive() you must override this method
+    wxFAIL_MSG( _T("CloneRefData() must be overridden if called!") );
+
+    return NULL;
 }
 
+// ----------------------------------------------------------------------------
+// misc
+// ----------------------------------------------------------------------------
 
 #if defined(__DARWIN__) && defined(DYLIB_INIT)