]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dynload.cpp
Applied #15375 to stop event-sending in generic wxSpinCtrl ctor (eco)
[wxWidgets.git] / src / common / dynload.cpp
index 5cb065859d11077c14e0475edeabb83159b2f98a..0b184d0e5bc8e223a8ec2bd834e36549c7ce5c54 100644 (file)
@@ -1,11 +1,10 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:         dynload.cpp
+// Name:         src/common/dynload.cpp
 // Purpose:      Dynamic loading framework
 // Author:       Ron Lee, David Falkinder, Vadim Zeitlin and a cast of 1000's
 //               (derived in part from dynlib.cpp (c) 1998 Guilhem Lavaux)
 // Modified by:
 // Created:      03/12/01
 // Purpose:      Dynamic loading framework
 // Author:       Ron Lee, David Falkinder, Vadim Zeitlin and a cast of 1000's
 //               (derived in part from dynlib.cpp (c) 1998 Guilhem Lavaux)
 // Modified by:
 // Created:      03/12/01
-// RCS-ID:       $Id$
 // Copyright:    (c) 2001 Ron Lee <ron@debian.org>
 // Licence:      wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 // Copyright:    (c) 2001 Ron Lee <ron@debian.org>
 // Licence:      wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
     #include "wx/intl.h"
     #include "wx/hash.h"
     #include "wx/utils.h"
     #include "wx/intl.h"
     #include "wx/hash.h"
     #include "wx/utils.h"
+    #include "wx/module.h"
 #endif
 
 #include "wx/strconv.h"
 
 #include "wx/dynload.h"
 #endif
 
 #include "wx/strconv.h"
 
 #include "wx/dynload.h"
-#include "wx/module.h"
 
 
 // ---------------------------------------------------------------------------
 
 
 // ---------------------------------------------------------------------------
@@ -61,8 +60,7 @@ public:
 
     virtual void OnExit()
     {
 
     virtual void OnExit()
     {
-        delete wxPluginLibrary::ms_classes;
-        wxPluginLibrary::ms_classes = NULL;
+        wxDELETE(wxPluginLibrary::ms_classes);
         wxPluginManager::ClearManifest();
     }
 
         wxPluginManager::ClearManifest();
     }
 
@@ -77,9 +75,33 @@ wxPluginLibrary::wxPluginLibrary(const wxString &libname, int flags)
         : m_linkcount(1)
         , m_objcount(0)
 {
         : m_linkcount(1)
         , m_objcount(0)
 {
-    m_before = wxClassInfo::sm_first;
+    const wxClassInfo* const oldFirst = wxClassInfo::GetFirst();
     Load( libname, flags );
     Load( libname, flags );
-    m_after = wxClassInfo::sm_first;
+
+    // It is simple to know what is the first object in the linked list of
+    // wxClassInfo that we registered (it's also the last one chronologically),
+    // it's just the new head of the wxClassInfo list:
+    m_ourFirst = wxClassInfo::GetFirst();
+
+    // But to find the first wxClassInfo created by this library we need to
+    // iterate until we get to the previous head as we don't have the links in
+    // the backwards direction:
+    if ( m_ourFirst != oldFirst )
+    {
+        for ( const wxClassInfo* info = m_ourFirst; ; info = info->GetNext() )
+        {
+            if ( info->GetNext() == oldFirst )
+            {
+                m_ourLast = info;
+                break;
+            }
+        }
+    }
+    else // We didn't register any classes at all.
+    {
+        m_ourFirst =
+        m_ourLast = NULL;
+    }
 
     if( m_handle != 0 )
     {
 
     if( m_handle != 0 )
     {
@@ -105,7 +127,7 @@ wxPluginLibrary::~wxPluginLibrary()
 wxPluginLibrary *wxPluginLibrary::RefLib()
 {
     wxCHECK_MSG( m_linkcount > 0, NULL,
 wxPluginLibrary *wxPluginLibrary::RefLib()
 {
     wxCHECK_MSG( m_linkcount > 0, NULL,
-                 _T("Library had been already deleted!") );
+                 wxT("Library had been already deleted!") );
 
     ++m_linkcount;
     return this;
 
     ++m_linkcount;
     return this;
@@ -114,7 +136,7 @@ wxPluginLibrary *wxPluginLibrary::RefLib()
 bool wxPluginLibrary::UnrefLib()
 {
     wxASSERT_MSG( m_objcount == 0,
 bool wxPluginLibrary::UnrefLib()
 {
     wxASSERT_MSG( m_objcount == 0,
-                  _T("Library unloaded before all objects were destroyed") );
+                  wxT("Library unloaded before all objects were destroyed") );
 
     if ( m_linkcount == 0 || --m_linkcount == 0 )
     {
 
     if ( m_linkcount == 0 || --m_linkcount == 0 )
     {
@@ -131,7 +153,10 @@ bool wxPluginLibrary::UnrefLib()
 
 void wxPluginLibrary::UpdateClasses()
 {
 
 void wxPluginLibrary::UpdateClasses()
 {
-    for (wxClassInfo *info = m_after; info != m_before; info = info->m_next)
+    if ( !m_ourFirst )
+        return;
+
+    for ( const wxClassInfo *info = m_ourFirst; ; info = info->GetNext() )
     {
         if( info->GetClassName() )
         {
     {
         if( info->GetClassName() )
         {
@@ -139,6 +164,9 @@ void wxPluginLibrary::UpdateClasses()
             // we can quickly find the entry they correspond to.
             (*ms_classes)[info->GetClassName()] = this;
         }
             // we can quickly find the entry they correspond to.
             (*ms_classes)[info->GetClassName()] = this;
         }
+
+        if ( info == m_ourLast )
+            break;
     }
 }
 
     }
 }
 
@@ -148,9 +176,15 @@ void wxPluginLibrary::RestoreClasses()
     if (!ms_classes)
         return;
 
     if (!ms_classes)
         return;
 
-    for(wxClassInfo *info = m_after; info != m_before; info = info->m_next)
+    if ( !m_ourFirst )
+        return;
+
+    for ( const wxClassInfo *info = m_ourFirst; ; info = info->GetNext() )
     {
         ms_classes->erase(ms_classes->find(info->GetClassName()));
     {
         ms_classes->erase(ms_classes->find(info->GetClassName()));
+
+        if ( info == m_ourLast )
+            break;
     }
 }
 
     }
 }
 
@@ -165,18 +199,24 @@ void wxPluginLibrary::RegisterModules()
     // though, as there is currently no way to Unregister it without it.
 
     wxASSERT_MSG( m_linkcount == 1,
     // though, as there is currently no way to Unregister it without it.
 
     wxASSERT_MSG( m_linkcount == 1,
-                  _T("RegisterModules should only be called for the first load") );
+                  wxT("RegisterModules should only be called for the first load") );
 
 
-    for ( wxClassInfo *info = m_after; info != m_before; info = info->m_next)
+    if ( m_ourFirst )
     {
     {
-        if( info->IsKindOf(CLASSINFO(wxModule)) )
+        for ( const wxClassInfo *info = m_ourFirst; ; info = info->GetNext() )
         {
         {
-            wxModule *m = wxDynamicCast(info->CreateObject(), wxModule);
+            if( info->IsKindOf(wxCLASSINFO(wxModule)) )
+            {
+                wxModule *m = wxDynamicCast(info->CreateObject(), wxModule);
 
 
-            wxASSERT_MSG( m, _T("wxDynamicCast of wxModule failed") );
+                wxASSERT_MSG( m, wxT("wxDynamicCast of wxModule failed") );
 
 
-            m_wxmodules.push_back(m);
-            wxModule::RegisterModule(m);
+                m_wxmodules.push_back(m);
+                wxModule::RegisterModule(m);
+            }
+
+            if ( info == m_ourLast )
+                break;
         }
     }
 
         }
     }
 
@@ -188,7 +228,7 @@ void wxPluginLibrary::RegisterModules()
     {
         if( !(*it)->Init() )
         {
     {
         if( !(*it)->Init() )
         {
-            wxLogDebug(_T("wxModule::Init() failed for wxPluginLibrary"));
+            wxLogDebug(wxT("wxModule::Init() failed for wxPluginLibrary"));
 
             // XXX: Watch this, a different hash implementation might break it,
             //      a good hash implementation would let us fix it though.
 
             // XXX: Watch this, a different hash implementation might break it,
             //      a good hash implementation would let us fix it though.
@@ -243,7 +283,7 @@ wxPluginManager::LoadLibrary(const wxString &libname, int flags)
     wxString realname(libname);
 
     if( !(flags & wxDL_VERBATIM) )
     wxString realname(libname);
 
     if( !(flags & wxDL_VERBATIM) )
-        realname += wxDynamicLibrary::GetDllExt();
+        realname += wxDynamicLibrary::GetDllExt(wxDL_MODULE);
 
     wxPluginLibrary *entry;
 
 
     wxPluginLibrary *entry;
 
@@ -258,8 +298,8 @@ wxPluginManager::LoadLibrary(const wxString &libname, int flags)
 
     if ( entry )
     {
 
     if ( entry )
     {
-        wxLogTrace(_T("dll"),
-                   _T("LoadLibrary(%s): already loaded."), realname.c_str());
+        wxLogTrace(wxT("dll"),
+                   wxT("LoadLibrary(%s): already loaded."), realname.c_str());
 
         entry->RefLib();
     }
 
         entry->RefLib();
     }
@@ -271,20 +311,20 @@ wxPluginManager::LoadLibrary(const wxString &libname, int flags)
         {
             (*ms_manifest)[realname] = entry;
 
         {
             (*ms_manifest)[realname] = entry;
 
-            wxLogTrace(_T("dll"),
-                       _T("LoadLibrary(%s): loaded ok."), realname.c_str());
+            wxLogTrace(wxT("dll"),
+                       wxT("LoadLibrary(%s): loaded ok."), realname.c_str());
 
         }
         else
         {
 
         }
         else
         {
-            wxLogTrace(_T("dll"),
-                       _T("LoadLibrary(%s): failed to load."), realname.c_str());
+            wxLogTrace(wxT("dll"),
+                       wxT("LoadLibrary(%s): failed to load."), realname.c_str());
 
             // we have created entry just above
             if ( !entry->UnrefLib() )
             {
                 // ... so UnrefLib() is supposed to delete it
 
             // we have created entry just above
             if ( !entry->UnrefLib() )
             {
                 // ... so UnrefLib() is supposed to delete it
-                wxFAIL_MSG( _T("Currently linked library is not loaded?") );
+                wxFAIL_MSG( wxT("Currently linked library is not loaded?") );
             }
 
             entry = NULL;
             }
 
             entry = NULL;
@@ -302,20 +342,20 @@ bool wxPluginManager::UnloadLibrary(const wxString& libname)
 
     if ( !entry )
     {
 
     if ( !entry )
     {
-        realname += wxDynamicLibrary::GetDllExt();
+        realname += wxDynamicLibrary::GetDllExt(wxDL_MODULE);
 
         entry = FindByName(realname);
     }
 
     if ( !entry )
     {
 
         entry = FindByName(realname);
     }
 
     if ( !entry )
     {
-        wxLogDebug(_T("Attempt to unload library '%s' which is not loaded."),
+        wxLogDebug(wxT("Attempt to unload library '%s' which is not loaded."),
                    libname.c_str());
 
         return false;
     }
 
                    libname.c_str());
 
         return false;
     }
 
-    wxLogTrace(_T("dll"), _T("UnloadLibrary(%s)"), realname.c_str());
+    wxLogTrace(wxT("dll"), wxT("UnloadLibrary(%s)"), realname.c_str());
 
     if ( !entry->UnrefLib() )
     {
 
     if ( !entry->UnrefLib() )
     {
@@ -341,7 +381,7 @@ bool wxPluginManager::Load(const wxString &libname, int flags)
 
 void wxPluginManager::Unload()
 {
 
 void wxPluginManager::Unload()
 {
-    wxCHECK_RET( m_entry, _T("unloading an invalid wxPluginManager?") );
+    wxCHECK_RET( m_entry, wxT("unloading an invalid wxPluginManager?") );
 
     for ( wxDLManifest::iterator i = ms_manifest->begin();
           i != ms_manifest->end();
 
     for ( wxDLManifest::iterator i = ms_manifest->begin();
           i != ms_manifest->end();
@@ -360,4 +400,3 @@ void wxPluginManager::Unload()
 }
 
 #endif  // wxUSE_DYNAMIC_LOADER
 }
 
 #endif  // wxUSE_DYNAMIC_LOADER
-